Merge branch 'master' into movement-duplicate-switch
This commit is contained in:
commit
e5f8b5de5b
@ -1,43 +0,0 @@
|
|||||||
# Java Gradle CircleCI 2.0 configuration file
|
|
||||||
#
|
|
||||||
# Check https://circleci.com/docs/2.0/language-java/ for more details
|
|
||||||
#
|
|
||||||
version: 2
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
docker:
|
|
||||||
# specify the version you desire here
|
|
||||||
- image: circleci/openjdk:8-jdk
|
|
||||||
|
|
||||||
# Specify service dependencies here if necessary
|
|
||||||
# CircleCI maintains a library of pre-built images
|
|
||||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
|
||||||
# - image: circleci/postgres:9.4
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
environment:
|
|
||||||
# Customize the JVM maximum heap limit
|
|
||||||
JVM_OPTS: -Xmx3200m
|
|
||||||
TERM: dumb
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
# Download and cache dependencies
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- v1-dependencies-{{ checksum "build.gradle" }}
|
|
||||||
# fallback to using the latest cache if no exact match is found
|
|
||||||
- v1-dependencies-
|
|
||||||
|
|
||||||
- run: gradle dependencies
|
|
||||||
|
|
||||||
- save_cache:
|
|
||||||
paths:
|
|
||||||
- ~/.gradle
|
|
||||||
key: v1-dependencies-{{ checksum "build.gradle" }}
|
|
||||||
|
|
||||||
# run tests!
|
|
||||||
- run: gradle test
|
|
||||||
|
|
1
.travis.yml
Normal file
1
.travis.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
language: java
|
48
FEATURES.md
Normal file
48
FEATURES.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Pathing features
|
||||||
|
- **Long distance pathing and splicing** Baritone calculates paths in segments, and precalculates the next segment when the current one is about to end, so that it's moving towards the goal at all times.
|
||||||
|
- **Chunk caching** Baritone simplifies chunks to a compacted internal 2-bit representation (AIR, SOLID, WATER, AVOID) and stores them in RAM for better very-long-distance pathing. There is also an option to save these cached chunks to disk. <a href="https://www.youtube.com/watch?v=dyfYKSubhdc">Example</a>
|
||||||
|
- **Block breaking** Baritone considers breaking blocks as part of its path. It also takes into account your current tool set and hot bar. For example, if you have a Eff V diamond pick, it may choose to mine through a stone barrier, while if you only had a wood pick it might be faster to climb over it.
|
||||||
|
- **Block placing** Baritone considers placing blocks as part of its path. This includes sneak-back-placing, pillaring, etc. It has a configurable penalty of placing a block (set to 1 second by default), to conserve its resources. The list of acceptable throwaway blocks is also configurable, and is cobble, dirt, or netherrack by default. <a href="https://www.youtube.com/watch?v=F6FbI1L9UmU">Example</a>
|
||||||
|
- **Falling** Baritone will fall up to 3 blocks onto solid ground (configurable, if you have Feather Falling and/or don't mind taking a little damage). If you have a water bucket on your hotbar, it will fall up to 23 blocks and place the bucket beneath it. It will fall an unlimited distance into existing still water.
|
||||||
|
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`).
|
||||||
|
- **Opening fence gates and doors**
|
||||||
|
- **Slabs and stairs**
|
||||||
|
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
|
||||||
|
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
|
||||||
|
|
||||||
|
# Pathing method
|
||||||
|
Baritone uses a modified version of A*.
|
||||||
|
|
||||||
|
- **Incremental cost backoff** Since most of the time Baritone only knows the terrain up to the render distance, it can't calculate a full path to the goal. Therefore it needs to select a segment to execute first (assuming it will calculate the next segment at the end of this one). It uses incremental cost backoff to select the best node by varying metrics, then paths to that node. This is unchanged from MineBot and I made a <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit">write-up</a> that still applies. In essence, it keeps track of the best node by various increasing coefficients, then picks the node with the least coefficient that goes at least 5 blocks from the starting position.
|
||||||
|
- **Minimum improvement repropagation** The pathfinder ignores alternate routes that provide minimal improvements (less than 0.01 ticks of improvement), because the calculation cost of repropagating this to all connected nodes is much higher than the half-millisecond path time improvement it would get.
|
||||||
|
- **Backtrack cost favoring** While calculating the next segment, Baritone favors backtracking its current segment slightly, as a tiebreaker. This allows it to splice and jump onto the next segment as early as possible, if the next segment begins with a backtrack of the current one. <a href="https://www.youtube.com/watch?v=CGiMcb8-99Y">Example</a>
|
||||||
|
|
||||||
|
# Configuring Baritone
|
||||||
|
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/Settings.java">here</a>.
|
||||||
|
To change a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `pathTimeoutMS 250`). It's case insensitive.
|
||||||
|
|
||||||
|
# Goals
|
||||||
|
The pathing goal can be set to any of these options:
|
||||||
|
- **GoalBlock** one specific block that the player should stand inside at foot level
|
||||||
|
- **GoalXZ** an X and a Z coordinate, used for long distance pathing
|
||||||
|
- **GoalYLevel** a Y coordinate
|
||||||
|
- **GoalTwoBlocks** a block position that the player should stand in, either at foot or eye level
|
||||||
|
- **GoalGetToBlock** a block position that the player should stand adjacent to, below, or on top of
|
||||||
|
- **GoalNear** a block position that the player should get within a certain radius of, used for following entities
|
||||||
|
|
||||||
|
And finally `GoalComposite`. `GoalComposite` is a list of other goals, any one of which satisfies the goal. For example, `mine diamond_ore` creates a `GoalComposite` of `GoalTwoBlocks`s for every diamond ore location it knows of.
|
||||||
|
|
||||||
|
|
||||||
|
# Future features
|
||||||
|
Things it doesn't have yet
|
||||||
|
- Trapdoors
|
||||||
|
- Sprint jumping in a 1x2 corridor
|
||||||
|
- Parkour (jumping over gaps of any length) [IN PROGRESS]
|
||||||
|
|
||||||
|
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
|
||||||
|
|
||||||
|
Things it may not ever have, from most likely to least likely =(
|
||||||
|
- Boats
|
||||||
|
- Pigs
|
||||||
|
- Horses (2x3 path instead of 1x2)
|
||||||
|
- Elytra
|
16
IMPACT.md
Normal file
16
IMPACT.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Integration between Baritone and Impact
|
||||||
|
|
||||||
|
Baritone will be in Impact 4.4 with nice integrations with its utility modules, but if you're impatient you can run Baritone on top of Impact 4.3 right now.
|
||||||
|
|
||||||
|
You can either build Baritone yourself, or download the jar from September 4 from <a href="https://www.dropbox.com/s/imc6xwwpwsh3i0y/baritone-1.0.0.jar?dl=0">here</a>
|
||||||
|
|
||||||
|
To build it yourself, clone and setup Baritone (instructions in main README.md). Then, build the jar. From the command line, it's `./gradlew build` (or `gradlew build` on Windows). In IntelliJ, you can just start the `build` task in the Gradle menu.
|
||||||
|
|
||||||
|
Copy the jar into place. It should be `build/libs/baritone-1.0.0.jar` in baritone. Copy it to your libraries in your Minecraft install. For example, on Mac I do `cp Documents/baritone/build/libs/baritone-1.0.0.jar Library/Application\ Support/minecraft/libraries/cabaletta/baritone/1.0.0/baritone-1.0.0.jar`. The first time you'll need to make the directory `cabaletta/baritone/1.0.0` in libraries first.
|
||||||
|
|
||||||
|
Then, we'll need to modify the Impact launch json. Open `minecraft/versions/1.12.2-Impact_4.3/1.12.2-Impact_4.3.json` or copy your existing installation and rename the version folder, json, and id in the json.
|
||||||
|
|
||||||
|
- Add the Baritone tweak class to line 7 "minecraftArguments" like so: `"minecraftArguments": " ... --tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine",`. You need the Optifine tweaker even though there is no Optifine involved, for reasons I don't quite understand.
|
||||||
|
- Add the Baritone library. Insert `{ "name": "cabaletta:baritone:1.0.0" },` between Impact and ClientAPI, which should be between lines 15 and 16.
|
||||||
|
|
||||||
|
Restart the Minecraft launcher, then load Impact 4.3 as normal, and it should now include Baritone.
|
54
README.md
54
README.md
@ -1,3 +1,57 @@
|
|||||||
# Baritone
|
# Baritone
|
||||||
|
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
|
||||||
|
|
||||||
A Minecraft bot. This project is an updated version of [Minebot](https://github.com/leijurv/MineBot/),
|
A Minecraft bot. 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.
|
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2.
|
||||||
|
|
||||||
|
<a href="https://github.com/cabaletta/baritone/blob/master/FEATURES.md">Features</a>
|
||||||
|
|
||||||
|
<a href="https://github.com/cabaletta/baritone/blob/master/IMPACT.md">Baritone + Impact</a>
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
- Open the project in IntelliJ as a Gradle project
|
||||||
|
- Run the Gradle task `setupDecompWorkspace`
|
||||||
|
- Run the Gradle task `genIntellijRuns`
|
||||||
|
- Refresh the Gradle project (or just restart IntelliJ)
|
||||||
|
- Select the "Minecraft Client" launch config and run
|
||||||
|
|
||||||
|
## Command Line
|
||||||
|
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||||
|
|
||||||
|
Running Baritone:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gradlew run
|
||||||
|
```
|
||||||
|
|
||||||
|
Setting up for IntelliJ:
|
||||||
|
```
|
||||||
|
$ gradlew setupDecompWorkspace
|
||||||
|
$ gradlew --refresh-dependencies
|
||||||
|
$ gradlew genIntellijRuns
|
||||||
|
```
|
||||||
|
|
||||||
|
# Chat control
|
||||||
|
<a href="https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java">Defined here</a>
|
||||||
|
|
||||||
|
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
|
||||||
|
|
||||||
|
# API example
|
||||||
|
|
||||||
|
```
|
||||||
|
Baritone.settings().allowSprint.value = true;
|
||||||
|
Baritone.settings().pathTimeoutMS.value = 2000L;
|
||||||
|
|
||||||
|
PathingBehavior.INSTANCE.setGoal(new GoalXZ(10000, 20000));
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
|
```
|
||||||
|
|
||||||
|
# FAQ
|
||||||
|
|
||||||
|
## Can I use Baritone as a library in my hacked client?
|
||||||
|
|
||||||
|
Sure!
|
||||||
|
|
||||||
|
## How is it so fast?
|
||||||
|
|
||||||
|
Magic
|
||||||
|
17
build.gradle
17
build.gradle
@ -38,14 +38,19 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||||
|
apply plugin: 'org.spongepowered.mixin'
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = '1.8'
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
compileJava {
|
compileJava {
|
||||||
sourceCompatibility = targetCompatibility = '1.8'
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
sourceSets {
|
||||||
apply plugin: 'org.spongepowered.mixin'
|
launch {
|
||||||
|
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = '1.12.2'
|
version = '1.12.2'
|
||||||
@ -65,7 +70,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation ('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
||||||
// Mixin includes a lot of dependencies that are too up-to-date
|
// Mixin includes a lot of dependencies that are too up-to-date
|
||||||
exclude module: 'launchwrapper'
|
exclude module: 'launchwrapper'
|
||||||
exclude module: 'guava'
|
exclude module: 'guava'
|
||||||
@ -78,5 +83,9 @@ dependencies {
|
|||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
defaultObfuscationEnv notch
|
defaultObfuscationEnv notch
|
||||||
add sourceSets.main, 'mixins.baritone.refmap.json'
|
add sourceSets.launch, 'mixins.baritone.refmap.json'
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
from sourceSets.launch.output
|
||||||
}
|
}
|
||||||
|
369
proguard.pro
vendored
Normal file
369
proguard.pro
vendored
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
-injars baritone-1.0.0.jar
|
||||||
|
-outjars Obfuscated
|
||||||
|
|
||||||
|
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
|
||||||
|
-optimizationpasses 20
|
||||||
|
-verbose
|
||||||
|
|
||||||
|
-allowaccessmodification # anything not kept can be changed from public to private and inlined etc
|
||||||
|
-mergeinterfacesaggressively
|
||||||
|
-overloadaggressively
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
|
||||||
|
# instead of obfing to a, b, c, obf to baritone.a, baritone.b, baritone.c so as to not conflict with mcp
|
||||||
|
-flattenpackagehierarchy
|
||||||
|
-repackageclasses 'baritone'
|
||||||
|
|
||||||
|
#-keep class baritone.behavior.** { *; }
|
||||||
|
#-keep class baritone.api.** { *; }
|
||||||
|
#-keep class baritone.* { *; }
|
||||||
|
#-keep class baritone.pathing.goals.** { *; }
|
||||||
|
|
||||||
|
# setting names are reflected from field names, so keep field names
|
||||||
|
-keepclassmembers class baritone.Settings {
|
||||||
|
public <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# need to keep mixin names
|
||||||
|
-keep class baritone.launch.** { *; }
|
||||||
|
|
||||||
|
# copy all necessary libraries into tempLibraries to build
|
||||||
|
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/1.12.2.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||||
|
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||||
|
-libraryjars 'tempLibraries/codecwav-20101023.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-codec-1.10.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-compress-1.8.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-io-2.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-lang3-3.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-logging-1.1.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/fastutil-7.1.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/gson-2.8.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/guava-21.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||||
|
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||||
|
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0-natives-osx.jar'
|
||||||
|
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/jinput-platform-2.0.5-natives-osx.jar'
|
||||||
|
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/jsr305-3.0.1-sources.jar'
|
||||||
|
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
||||||
|
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
||||||
|
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/lwjgl-2.9.2-nightly-20140822.jar'
|
||||||
|
-libraryjars 'tempLibraries/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar'
|
||||||
|
-libraryjars 'tempLibraries/lwjgl_util-2.9.2-nightly-20140822.jar'
|
||||||
|
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||||
|
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/patchy-1.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/platform-3.4.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/realms-1.10.22.jar'
|
||||||
|
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
||||||
|
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/mixin-0.7.8-SNAPSHOT.jar'
|
||||||
|
-libraryjars 'tempLibraries/launchwrapper-1.12.jar'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||||
|
# methods.
|
||||||
|
-keepclasseswithmembers public class * {
|
||||||
|
public static void main(java.lang.String[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Also keep - Enumerations. Keep the special static methods that are required in
|
||||||
|
# enumeration classes.
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Also keep - Database drivers. Keep all implementations of java.sql.Driver.
|
||||||
|
-keep class * extends java.sql.Driver
|
||||||
|
|
||||||
|
# Also keep - Swing UI L&F. Keep all extensions of javax.swing.plaf.ComponentUI,
|
||||||
|
# along with the special 'createUI' method.
|
||||||
|
-keep class * extends javax.swing.plaf.ComponentUI {
|
||||||
|
public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep names - Native method names. Keep all native class/method names.
|
||||||
|
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - System method calls. Remove all invocations of System
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.System {
|
||||||
|
public static long currentTimeMillis();
|
||||||
|
static java.lang.Class getCallerClass();
|
||||||
|
public static int identityHashCode(java.lang.Object);
|
||||||
|
public static java.lang.SecurityManager getSecurityManager();
|
||||||
|
public static java.util.Properties getProperties();
|
||||||
|
public static java.lang.String getProperty(java.lang.String);
|
||||||
|
public static java.lang.String getenv(java.lang.String);
|
||||||
|
public static java.lang.String mapLibraryName(java.lang.String);
|
||||||
|
public static java.lang.String getProperty(java.lang.String,java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - Math method calls. Remove all invocations of Math
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.Math {
|
||||||
|
public static double sin(double);
|
||||||
|
public static double cos(double);
|
||||||
|
public static double tan(double);
|
||||||
|
public static double asin(double);
|
||||||
|
public static double acos(double);
|
||||||
|
public static double atan(double);
|
||||||
|
public static double toRadians(double);
|
||||||
|
public static double toDegrees(double);
|
||||||
|
public static double exp(double);
|
||||||
|
public static double log(double);
|
||||||
|
public static double log10(double);
|
||||||
|
public static double sqrt(double);
|
||||||
|
public static double cbrt(double);
|
||||||
|
public static double IEEEremainder(double,double);
|
||||||
|
public static double ceil(double);
|
||||||
|
public static double floor(double);
|
||||||
|
public static double rint(double);
|
||||||
|
public static double atan2(double,double);
|
||||||
|
public static double pow(double,double);
|
||||||
|
public static int round(float);
|
||||||
|
public static long round(double);
|
||||||
|
public static double random();
|
||||||
|
public static int abs(int);
|
||||||
|
public static long abs(long);
|
||||||
|
public static float abs(float);
|
||||||
|
public static double abs(double);
|
||||||
|
public static int max(int,int);
|
||||||
|
public static long max(long,long);
|
||||||
|
public static float max(float,float);
|
||||||
|
public static double max(double,double);
|
||||||
|
public static int min(int,int);
|
||||||
|
public static long min(long,long);
|
||||||
|
public static float min(float,float);
|
||||||
|
public static double min(double,double);
|
||||||
|
public static double ulp(double);
|
||||||
|
public static float ulp(float);
|
||||||
|
public static double signum(double);
|
||||||
|
public static float signum(float);
|
||||||
|
public static double sinh(double);
|
||||||
|
public static double cosh(double);
|
||||||
|
public static double tanh(double);
|
||||||
|
public static double hypot(double,double);
|
||||||
|
public static double expm1(double);
|
||||||
|
public static double log1p(double);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - Number method calls. Remove all invocations of Number
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.* extends java.lang.Number {
|
||||||
|
public static java.lang.String toString(byte);
|
||||||
|
public static java.lang.Byte valueOf(byte);
|
||||||
|
public static byte parseByte(java.lang.String);
|
||||||
|
public static byte parseByte(java.lang.String,int);
|
||||||
|
public static java.lang.Byte valueOf(java.lang.String,int);
|
||||||
|
public static java.lang.Byte valueOf(java.lang.String);
|
||||||
|
public static java.lang.Byte decode(java.lang.String);
|
||||||
|
public int compareTo(java.lang.Byte);
|
||||||
|
public static java.lang.String toString(short);
|
||||||
|
public static short parseShort(java.lang.String);
|
||||||
|
public static short parseShort(java.lang.String,int);
|
||||||
|
public static java.lang.Short valueOf(java.lang.String,int);
|
||||||
|
public static java.lang.Short valueOf(java.lang.String);
|
||||||
|
public static java.lang.Short valueOf(short);
|
||||||
|
public static java.lang.Short decode(java.lang.String);
|
||||||
|
public static short reverseBytes(short);
|
||||||
|
public int compareTo(java.lang.Short);
|
||||||
|
public static java.lang.String toString(int,int);
|
||||||
|
public static java.lang.String toHexString(int);
|
||||||
|
public static java.lang.String toOctalString(int);
|
||||||
|
public static java.lang.String toBinaryString(int);
|
||||||
|
public static java.lang.String toString(int);
|
||||||
|
public static int parseInt(java.lang.String,int);
|
||||||
|
public static int parseInt(java.lang.String);
|
||||||
|
public static java.lang.Integer valueOf(java.lang.String,int);
|
||||||
|
public static java.lang.Integer valueOf(java.lang.String);
|
||||||
|
public static java.lang.Integer valueOf(int);
|
||||||
|
public static java.lang.Integer getInteger(java.lang.String);
|
||||||
|
public static java.lang.Integer getInteger(java.lang.String,int);
|
||||||
|
public static java.lang.Integer getInteger(java.lang.String,java.lang.Integer);
|
||||||
|
public static java.lang.Integer decode(java.lang.String);
|
||||||
|
public static int highestOneBit(int);
|
||||||
|
public static int lowestOneBit(int);
|
||||||
|
public static int numberOfLeadingZeros(int);
|
||||||
|
public static int numberOfTrailingZeros(int);
|
||||||
|
public static int bitCount(int);
|
||||||
|
public static int rotateLeft(int,int);
|
||||||
|
public static int rotateRight(int,int);
|
||||||
|
public static int reverse(int);
|
||||||
|
public static int signum(int);
|
||||||
|
public static int reverseBytes(int);
|
||||||
|
public int compareTo(java.lang.Integer);
|
||||||
|
public static java.lang.String toString(long,int);
|
||||||
|
public static java.lang.String toHexString(long);
|
||||||
|
public static java.lang.String toOctalString(long);
|
||||||
|
public static java.lang.String toBinaryString(long);
|
||||||
|
public static java.lang.String toString(long);
|
||||||
|
public static long parseLong(java.lang.String,int);
|
||||||
|
public static long parseLong(java.lang.String);
|
||||||
|
public static java.lang.Long valueOf(java.lang.String,int);
|
||||||
|
public static java.lang.Long valueOf(java.lang.String);
|
||||||
|
public static java.lang.Long valueOf(long);
|
||||||
|
public static java.lang.Long decode(java.lang.String);
|
||||||
|
public static java.lang.Long getLong(java.lang.String);
|
||||||
|
public static java.lang.Long getLong(java.lang.String,long);
|
||||||
|
public static java.lang.Long getLong(java.lang.String,java.lang.Long);
|
||||||
|
public static long highestOneBit(long);
|
||||||
|
public static long lowestOneBit(long);
|
||||||
|
public static int numberOfLeadingZeros(long);
|
||||||
|
public static int numberOfTrailingZeros(long);
|
||||||
|
public static int bitCount(long);
|
||||||
|
public static long rotateLeft(long,int);
|
||||||
|
public static long rotateRight(long,int);
|
||||||
|
public static long reverse(long);
|
||||||
|
public static int signum(long);
|
||||||
|
public static long reverseBytes(long);
|
||||||
|
public int compareTo(java.lang.Long);
|
||||||
|
public static java.lang.String toString(float);
|
||||||
|
public static java.lang.String toHexString(float);
|
||||||
|
public static java.lang.Float valueOf(java.lang.String);
|
||||||
|
public static java.lang.Float valueOf(float);
|
||||||
|
public static float parseFloat(java.lang.String);
|
||||||
|
public static boolean isNaN(float);
|
||||||
|
public static boolean isInfinite(float);
|
||||||
|
public static int floatToIntBits(float);
|
||||||
|
public static int floatToRawIntBits(float);
|
||||||
|
public static float intBitsToFloat(int);
|
||||||
|
public static int compare(float,float);
|
||||||
|
public boolean isNaN();
|
||||||
|
public boolean isInfinite();
|
||||||
|
public int compareTo(java.lang.Float);
|
||||||
|
public static java.lang.String toString(double);
|
||||||
|
public static java.lang.String toHexString(double);
|
||||||
|
public static java.lang.Double valueOf(java.lang.String);
|
||||||
|
public static java.lang.Double valueOf(double);
|
||||||
|
public static double parseDouble(java.lang.String);
|
||||||
|
public static boolean isNaN(double);
|
||||||
|
public static boolean isInfinite(double);
|
||||||
|
public static long doubleToLongBits(double);
|
||||||
|
public static long doubleToRawLongBits(double);
|
||||||
|
public static double longBitsToDouble(long);
|
||||||
|
public static int compare(double,double);
|
||||||
|
public boolean isNaN();
|
||||||
|
public boolean isInfinite();
|
||||||
|
public int compareTo(java.lang.Double);
|
||||||
|
public byte byteValue();
|
||||||
|
public short shortValue();
|
||||||
|
public int intValue();
|
||||||
|
public long longValue();
|
||||||
|
public float floatValue();
|
||||||
|
public double doubleValue();
|
||||||
|
public int compareTo(java.lang.Object);
|
||||||
|
public boolean equals(java.lang.Object);
|
||||||
|
public int hashCode();
|
||||||
|
public java.lang.String toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - String method calls. Remove all invocations of String
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.String {
|
||||||
|
public static java.lang.String copyValueOf(char[]);
|
||||||
|
public static java.lang.String copyValueOf(char[],int,int);
|
||||||
|
public static java.lang.String valueOf(boolean);
|
||||||
|
public static java.lang.String valueOf(char);
|
||||||
|
public static java.lang.String valueOf(char[]);
|
||||||
|
public static java.lang.String valueOf(char[],int,int);
|
||||||
|
public static java.lang.String valueOf(double);
|
||||||
|
public static java.lang.String valueOf(float);
|
||||||
|
public static java.lang.String valueOf(int);
|
||||||
|
public static java.lang.String valueOf(java.lang.Object);
|
||||||
|
public static java.lang.String valueOf(long);
|
||||||
|
public boolean contentEquals(java.lang.StringBuffer);
|
||||||
|
public boolean endsWith(java.lang.String);
|
||||||
|
public boolean equalsIgnoreCase(java.lang.String);
|
||||||
|
public boolean equals(java.lang.Object);
|
||||||
|
public boolean matches(java.lang.String);
|
||||||
|
public boolean regionMatches(boolean,int,java.lang.String,int,int);
|
||||||
|
public boolean regionMatches(int,java.lang.String,int,int);
|
||||||
|
public boolean startsWith(java.lang.String);
|
||||||
|
public boolean startsWith(java.lang.String,int);
|
||||||
|
public byte[] getBytes();
|
||||||
|
public byte[] getBytes(java.lang.String);
|
||||||
|
public char charAt(int);
|
||||||
|
public char[] toCharArray();
|
||||||
|
public int compareToIgnoreCase(java.lang.String);
|
||||||
|
public int compareTo(java.lang.Object);
|
||||||
|
public int compareTo(java.lang.String);
|
||||||
|
public int hashCode();
|
||||||
|
public int indexOf(int);
|
||||||
|
public int indexOf(int,int);
|
||||||
|
public int indexOf(java.lang.String);
|
||||||
|
public int indexOf(java.lang.String,int);
|
||||||
|
public int lastIndexOf(int);
|
||||||
|
public int lastIndexOf(int,int);
|
||||||
|
public int lastIndexOf(java.lang.String);
|
||||||
|
public int lastIndexOf(java.lang.String,int);
|
||||||
|
public int length();
|
||||||
|
public java.lang.CharSequence subSequence(int,int);
|
||||||
|
public java.lang.String concat(java.lang.String);
|
||||||
|
public java.lang.String replaceAll(java.lang.String,java.lang.String);
|
||||||
|
public java.lang.String replace(char,char);
|
||||||
|
public java.lang.String replaceFirst(java.lang.String,java.lang.String);
|
||||||
|
public java.lang.String[] split(java.lang.String);
|
||||||
|
public java.lang.String[] split(java.lang.String,int);
|
||||||
|
public java.lang.String substring(int);
|
||||||
|
public java.lang.String substring(int,int);
|
||||||
|
public java.lang.String toLowerCase();
|
||||||
|
public java.lang.String toLowerCase(java.util.Locale);
|
||||||
|
public java.lang.String toString();
|
||||||
|
public java.lang.String toUpperCase();
|
||||||
|
public java.lang.String toUpperCase(java.util.Locale);
|
||||||
|
public java.lang.String trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - StringBuffer method calls. Remove all invocations of StringBuffer
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.StringBuffer {
|
||||||
|
public java.lang.String toString();
|
||||||
|
public char charAt(int);
|
||||||
|
public int capacity();
|
||||||
|
public int codePointAt(int);
|
||||||
|
public int codePointBefore(int);
|
||||||
|
public int indexOf(java.lang.String,int);
|
||||||
|
public int lastIndexOf(java.lang.String);
|
||||||
|
public int lastIndexOf(java.lang.String,int);
|
||||||
|
public int length();
|
||||||
|
public java.lang.String substring(int);
|
||||||
|
public java.lang.String substring(int,int);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove - StringBuilder method calls. Remove all invocations of StringBuilder
|
||||||
|
# methods without side effects whose return values are not used.
|
||||||
|
-assumenosideeffects public class java.lang.StringBuilder {
|
||||||
|
public java.lang.String toString();
|
||||||
|
public char charAt(int);
|
||||||
|
public int capacity();
|
||||||
|
public int codePointAt(int);
|
||||||
|
public int codePointBefore(int);
|
||||||
|
public int indexOf(java.lang.String,int);
|
||||||
|
public int lastIndexOf(java.lang.String);
|
||||||
|
public int lastIndexOf(java.lang.String,int);
|
||||||
|
public int length();
|
||||||
|
public java.lang.String substring(int);
|
||||||
|
public java.lang.String substring(int,int);
|
||||||
|
}
|
0
src/main/java/baritone/launch/BaritoneTweaker.java → src/launch/java/baritone/launch/BaritoneTweaker.java
Executable file → Normal file
0
src/main/java/baritone/launch/BaritoneTweaker.java → src/launch/java/baritone/launch/BaritoneTweaker.java
Executable file → Normal file
0
src/main/java/baritone/launch/BaritoneTweakerForge.java → src/launch/java/baritone/launch/BaritoneTweakerForge.java
Executable file → Normal file
0
src/main/java/baritone/launch/BaritoneTweakerForge.java → src/launch/java/baritone/launch/BaritoneTweakerForge.java
Executable file → Normal file
0
src/main/java/baritone/launch/BaritoneTweakerOptifine.java → src/launch/java/baritone/launch/BaritoneTweakerOptifine.java
Executable file → Normal file
0
src/main/java/baritone/launch/BaritoneTweakerOptifine.java → src/launch/java/baritone/launch/BaritoneTweakerOptifine.java
Executable file → Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||||
|
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/4/2018
|
||||||
|
*/
|
||||||
|
@Mixin(AnvilChunkLoader.class)
|
||||||
|
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
||||||
|
|
||||||
|
@Shadow @Final private File chunkSaveLocation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getChunkSaveLocation() {
|
||||||
|
return this.chunkSaveLocation;
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ import javax.annotation.Nonnull;
|
|||||||
* @since 8/25/2018
|
* @since 8/25/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(BlockPos.class)
|
@Mixin(BlockPos.class)
|
||||||
public abstract class MixinBlockPos extends Vec3i {
|
public class MixinBlockPos extends Vec3i {
|
||||||
|
|
||||||
public MixinBlockPos(int xIn, int yIn, int zIn) {
|
public MixinBlockPos(int xIn, int yIn, int zIn) {
|
||||||
super(xIn, yIn, zIn);
|
super(xIn, yIn, zIn);
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
|
import net.minecraft.world.chunk.storage.IChunkLoader;
|
||||||
|
import net.minecraft.world.gen.ChunkProviderServer;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/4/2018
|
||||||
|
*/
|
||||||
|
@Mixin(ChunkProviderServer.class)
|
||||||
|
public class MixinChunkProviderServer implements IChunkProviderServer {
|
||||||
|
|
||||||
|
@Shadow @Final private IChunkLoader chunkLoader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkLoader getChunkLoader() {
|
||||||
|
return this.chunkLoader;
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,8 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.RelativeMoveEvent;
|
import baritone.api.event.events.RelativeMoveEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
@ -18,9 +18,9 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.ChatEvent;
|
import baritone.api.event.events.ChatEvent;
|
||||||
import baritone.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
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;
|
@ -18,7 +18,7 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.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;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
0
src/main/java/baritone/launch/mixins/MixinGameSettings.java → src/launch/java/baritone/launch/mixins/MixinGameSettings.java
Executable file → Normal file
0
src/main/java/baritone/launch/mixins/MixinGameSettings.java → src/launch/java/baritone/launch/mixins/MixinGameSettings.java
Executable file → Normal file
0
src/main/java/baritone/launch/mixins/MixinGuiContainer.java → src/launch/java/baritone/launch/mixins/MixinGuiContainer.java
Executable file → Normal file
0
src/main/java/baritone/launch/mixins/MixinGuiContainer.java → src/launch/java/baritone/launch/mixins/MixinGuiContainer.java
Executable file → Normal file
0
src/main/java/baritone/launch/mixins/MixinGuiScreen.java → src/launch/java/baritone/launch/mixins/MixinGuiScreen.java
Executable file → Normal file
0
src/main/java/baritone/launch/mixins/MixinGuiScreen.java → src/launch/java/baritone/launch/mixins/MixinGuiScreen.java
Executable file → Normal file
2
src/main/java/baritone/launch/mixins/MixinKeyBinding.java → src/launch/java/baritone/launch/mixins/MixinKeyBinding.java
Executable file → Normal file
2
src/main/java/baritone/launch/mixins/MixinKeyBinding.java → src/launch/java/baritone/launch/mixins/MixinKeyBinding.java
Executable file → Normal file
@ -29,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
* @since 7/31/2018 11:44 PM
|
* @since 7/31/2018 11:44 PM
|
||||||
*/
|
*/
|
||||||
@Mixin(KeyBinding.class)
|
@Mixin(KeyBinding.class)
|
||||||
public abstract class MixinKeyBinding {
|
public class MixinKeyBinding {
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "isKeyDown",
|
method = "isKeyDown",
|
24
src/main/java/baritone/launch/mixins/MixinMinecraft.java → src/launch/java/baritone/launch/mixins/MixinMinecraft.java
Executable file → Normal file
24
src/main/java/baritone/launch/mixins/MixinMinecraft.java → src/launch/java/baritone/launch/mixins/MixinMinecraft.java
Executable file → Normal file
@ -18,11 +18,11 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.BlockInteractEvent;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.event.events.WorldEvent;
|
||||||
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.behavior.impl.PathingBehavior;
|
import baritone.behavior.impl.PathingBehavior;
|
||||||
import baritone.event.events.BlockInteractEvent;
|
|
||||||
import baritone.event.events.TickEvent;
|
|
||||||
import baritone.event.events.WorldEvent;
|
|
||||||
import baritone.event.events.type.EventState;
|
|
||||||
import baritone.utils.ExampleBaritoneControl;
|
import baritone.utils.ExampleBaritoneControl;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
@ -48,9 +48,12 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class MixinMinecraft {
|
public class MixinMinecraft {
|
||||||
|
|
||||||
@Shadow private int leftClickCounter;
|
@Shadow
|
||||||
@Shadow public EntityPlayerSP player;
|
private int leftClickCounter;
|
||||||
@Shadow public WorldClient world;
|
@Shadow
|
||||||
|
public EntityPlayerSP player;
|
||||||
|
@Shadow
|
||||||
|
public WorldClient world;
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "init",
|
method = "init",
|
||||||
@ -108,8 +111,9 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||||
// If we're unloading the world but one doesn't exist, ignore it
|
// If we're unloading the world but one doesn't exist, ignore it
|
||||||
if (this.world == null && world == null)
|
if (this.world == null && world == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
||||||
new WorldEvent(
|
new WorldEvent(
|
||||||
@ -124,9 +128,7 @@ public class MixinMinecraft {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||||
// If we're unloading the world but one doesn't exist, ignore it
|
// still fire event for both null, as that means we've just finished exiting a world
|
||||||
if (this.world == null && world == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
||||||
new WorldEvent(
|
new WorldEvent(
|
@ -18,8 +18,8 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.ChunkEvent;
|
import baritone.api.event.events.ChunkEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||||
import net.minecraft.network.play.server.SPacketChunkData;
|
import net.minecraft.network.play.server.SPacketChunkData;
|
||||||
import net.minecraft.network.play.server.SPacketCombatEvent;
|
import net.minecraft.network.play.server.SPacketCombatEvent;
|
@ -18,8 +18,8 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.PacketEvent;
|
import baritone.api.event.events.PacketEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
@ -37,12 +37,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
* @since 8/6/2018 9:30 PM
|
* @since 8/6/2018 9:30 PM
|
||||||
*/
|
*/
|
||||||
@Mixin(NetworkManager.class)
|
@Mixin(NetworkManager.class)
|
||||||
public abstract class MixinNetworkManager {
|
public class MixinNetworkManager {
|
||||||
|
|
||||||
@Shadow private Channel channel;
|
@Shadow private Channel channel;
|
||||||
|
|
||||||
@Shadow protected abstract void channelRead0(ChannelHandlerContext p_channelRead0_1_, Packet<?> p_channelRead0_2_) throws Exception;
|
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "dispatchPacket",
|
method = "dispatchPacket",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
@ -18,8 +18,8 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.ChunkEvent;
|
import baritone.api.event.events.ChunkEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
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;
|
8
src/main/resources/mixins.baritone.json → src/launch/resources/mixins.baritone.json
Executable file → Normal file
8
src/main/resources/mixins.baritone.json → src/launch/resources/mixins.baritone.json
Executable file → Normal file
@ -8,21 +8,19 @@
|
|||||||
"maxShiftBy": 2
|
"maxShiftBy": 2
|
||||||
},
|
},
|
||||||
"client": [
|
"client": [
|
||||||
|
"MixinAnvilChunkLoader",
|
||||||
"MixinBlockPos",
|
"MixinBlockPos",
|
||||||
|
"MixinChunkProviderServer",
|
||||||
"MixinEntity",
|
"MixinEntity",
|
||||||
"MixinEntityPlayerSP",
|
"MixinEntityPlayerSP",
|
||||||
"MixinEntityRenderer",
|
"MixinEntityRenderer",
|
||||||
"MixinGameSettings",
|
"MixinGameSettings",
|
||||||
"MixinGuiContainer",
|
"MixinGuiContainer",
|
||||||
"MixinGuiScreen",
|
"MixinGuiScreen",
|
||||||
"MixinInventoryPlayer",
|
|
||||||
"MixinKeyBinding",
|
"MixinKeyBinding",
|
||||||
"MixinMinecraft",
|
"MixinMinecraft",
|
||||||
"MixinNetHandlerPlayClient",
|
"MixinNetHandlerPlayClient",
|
||||||
"MixinNetworkManager",
|
"MixinNetworkManager",
|
||||||
"MixinWorldClient",
|
"MixinWorldClient"
|
||||||
|
|
||||||
"accessor.IAnvilChunkLoader",
|
|
||||||
"accessor.IChunkProviderServer"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -17,12 +17,9 @@
|
|||||||
|
|
||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
|
import baritone.api.event.GameEventHandler;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.behavior.impl.LookBehavior;
|
import baritone.behavior.impl.*;
|
||||||
import baritone.behavior.impl.MemoryBehavior;
|
|
||||||
import baritone.behavior.impl.PathingBehavior;
|
|
||||||
import baritone.behavior.impl.LocationTrackingBehavior;
|
|
||||||
import baritone.event.GameEventHandler;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
@ -31,6 +28,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@ -54,11 +52,20 @@ public enum Baritone {
|
|||||||
private List<Behavior> behaviors;
|
private List<Behavior> behaviors;
|
||||||
private File dir;
|
private File dir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of consumers to be called after Baritone has initialized
|
||||||
|
*/
|
||||||
|
private List<Consumer<Baritone>> onInitConsumers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not Baritone is active
|
* Whether or not Baritone is active
|
||||||
*/
|
*/
|
||||||
private boolean active;
|
private boolean active;
|
||||||
|
|
||||||
|
Baritone() {
|
||||||
|
this.onInitConsumers = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void init() {
|
public synchronized void init() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return;
|
return;
|
||||||
@ -72,6 +79,8 @@ public enum Baritone {
|
|||||||
registerBehavior(LookBehavior.INSTANCE);
|
registerBehavior(LookBehavior.INSTANCE);
|
||||||
registerBehavior(MemoryBehavior.INSTANCE);
|
registerBehavior(MemoryBehavior.INSTANCE);
|
||||||
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
||||||
|
registerBehavior(FollowBehavior.INSTANCE);
|
||||||
|
registerBehavior(MineBehavior.INSTANCE);
|
||||||
}
|
}
|
||||||
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||||
if (!Files.exists(dir.toPath())) {
|
if (!Files.exists(dir.toPath())) {
|
||||||
@ -82,6 +91,8 @@ public enum Baritone {
|
|||||||
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
|
||||||
|
this.onInitConsumers.forEach(consumer -> consumer.accept(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isInitialized() {
|
public final boolean isInitialized() {
|
||||||
@ -120,4 +131,8 @@ public enum Baritone {
|
|||||||
public final File getDir() {
|
public final File getDir() {
|
||||||
return this.dir;
|
return this.dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void registerInitListener(Consumer<Baritone> runnable) {
|
||||||
|
this.onInitConsumers.add(runnable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,14 +56,20 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow Baritone to assume it can walk on still water just like any other block.
|
||||||
|
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||||
*/
|
*/
|
||||||
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(Arrays.asList(
|
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||||
Item.getItemFromBlock(Blocks.DIRT),
|
Item.getItemFromBlock(Blocks.DIRT),
|
||||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||||
Item.getItemFromBlock(Blocks.NETHERRACK)
|
Item.getItemFromBlock(Blocks.NETHERRACK)
|
||||||
));
|
)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
||||||
@ -71,6 +77,17 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowVines = new Setting<>(false);
|
public Setting<Boolean> allowVines = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
|
||||||
|
* everywhere in your base.
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the big A* setting.
|
* This is the big A* setting.
|
||||||
* As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
|
* As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
|
||||||
@ -116,8 +133,16 @@ public class Settings {
|
|||||||
/**
|
/**
|
||||||
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
|
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
|
||||||
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
|
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
|
||||||
|
* See issue #114 for why this is disabled.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(true);
|
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop 5 movements before anything that made the path COST_INF.
|
||||||
|
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
|
||||||
|
* still be spreading lol
|
||||||
|
*/
|
||||||
|
public Setting<Integer> costVerificationLookahead = new Setting<>(5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
|
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
|
||||||
@ -147,6 +172,13 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
|
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is it okay to sprint through a descend followed by a diagonal?
|
||||||
|
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
|
||||||
|
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
|
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
|
||||||
* doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path.
|
* doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path.
|
||||||
@ -164,7 +196,12 @@ public class Settings {
|
|||||||
/**
|
/**
|
||||||
* Pathing can never take longer than this
|
* Pathing can never take longer than this
|
||||||
*/
|
*/
|
||||||
public Setting<Number> pathTimeoutMS = new Setting<>(4000L);
|
public Setting<Number> pathTimeoutMS = new Setting<>(2000L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Planning ahead while executing a segment can never take longer than this
|
||||||
|
*/
|
||||||
|
public Setting<Number> planAheadTimeoutMS = new Setting<>(4000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging, consider nodes much much slower
|
* For debugging, consider nodes much much slower
|
||||||
@ -197,6 +234,11 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> chatControl = new Setting<>(true);
|
public Setting<Boolean> chatControl = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A second override over chatControl to force it on
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> removePrefix = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the path
|
* Render the path
|
||||||
*/
|
*/
|
||||||
@ -309,10 +351,10 @@ public class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> List<Setting<T>> getByValueType(Class<T> klass) {
|
public <T> List<Setting<T>> getAllValuesByType(Class<T> klass) {
|
||||||
List<Setting<T>> result = new ArrayList<>();
|
List<Setting<T>> result = new ArrayList<>();
|
||||||
for (Setting<?> setting : allSettings) {
|
for (Setting<?> setting : allSettings) {
|
||||||
if (setting.klass.equals(klass)) {
|
if (setting.getValueClass().equals(klass)) {
|
||||||
result.add((Setting<T>) setting);
|
result.add((Setting<T>) setting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,14 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event;
|
package baritone.api.event;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.*;
|
||||||
|
import baritone.api.event.events.type.EventState;
|
||||||
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
import baritone.chunk.WorldProvider;
|
import baritone.chunk.WorldProvider;
|
||||||
import baritone.event.events.*;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.event.events.type.EventState;
|
|
||||||
import baritone.event.listener.IGameEventListener;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.interfaces.Toggleable;
|
import baritone.utils.interfaces.Toggleable;
|
||||||
@ -133,9 +134,10 @@ public final class GameEventHandler implements IGameEventListener, Helper {
|
|||||||
public final void onWorldEvent(WorldEvent event) {
|
public final void onWorldEvent(WorldEvent event) {
|
||||||
WorldProvider cache = WorldProvider.INSTANCE;
|
WorldProvider cache = WorldProvider.INSTANCE;
|
||||||
|
|
||||||
|
BlockStateInterface.clearCachedChunk();
|
||||||
|
|
||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE:
|
case PRE:
|
||||||
cache.closeWorld();
|
|
||||||
break;
|
break;
|
||||||
case POST:
|
case POST:
|
||||||
cache.closeWorld();
|
cache.closeWorld();
|
||||||
@ -157,11 +159,6 @@ public final class GameEventHandler implements IGameEventListener, Helper {
|
|||||||
dispatch(listener -> listener.onReceivePacket(event));
|
dispatch(listener -> listener.onReceivePacket(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onQueryItemSlotForBlocks(ItemSlotEvent event) {
|
|
||||||
dispatch(listener -> listener.onQueryItemSlotForBlocks(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerRelativeMove(RelativeMoveEvent event) {
|
public void onPlayerRelativeMove(RelativeMoveEvent event) {
|
||||||
dispatch(listener -> listener.onPlayerRelativeMove(event));
|
dispatch(listener -> listener.onPlayerRelativeMove(event));
|
@ -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.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.Cancellable;
|
import baritone.api.event.events.type.Cancellable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in some cases where a player's inventory has it's current slot queried.
|
* Called in some cases where a player's inventory has it's current slot queried.
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
|
|
||||||
/**
|
/**
|
@ -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.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
public enum PathEvent {
|
public enum PathEvent {
|
||||||
CALC_STARTED,
|
CALC_STARTED,
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -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.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
|
||||||
public final class TickEvent {
|
public final class TickEvent {
|
||||||
|
|
@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
|
|
||||||
/**
|
/**
|
@ -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.event.events.type;
|
package baritone.api.event.events.type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -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.event.events.type;
|
package baritone.api.event.events.type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
@ -32,9 +32,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.listener;
|
package baritone.api.event.listener;
|
||||||
|
|
||||||
import baritone.event.events.*;
|
import baritone.api.event.events.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link IGameEventListener} that has all methods
|
* An implementation of {@link IGameEventListener} that has all methods
|
||||||
@ -74,9 +74,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
|
|||||||
@Override
|
@Override
|
||||||
default void onReceivePacket(PacketEvent event) {}
|
default void onReceivePacket(PacketEvent event) {}
|
||||||
|
|
||||||
@Override
|
|
||||||
default void onQueryItemSlotForBlocks(ItemSlotEvent event) {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void onPlayerRelativeMove(RelativeMoveEvent event) {}
|
default void onPlayerRelativeMove(RelativeMoveEvent event) {}
|
||||||
|
|
@ -32,11 +32,10 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.event.listener;
|
package baritone.api.event.listener;
|
||||||
|
|
||||||
import baritone.event.events.*;
|
import baritone.api.event.events.*;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.client.gui.GuiGameOver;
|
import net.minecraft.client.gui.GuiGameOver;
|
||||||
@ -44,7 +43,6 @@ import net.minecraft.client.multiplayer.WorldClient;
|
|||||||
import net.minecraft.client.renderer.EntityRenderer;
|
import net.minecraft.client.renderer.EntityRenderer;
|
||||||
import net.minecraft.client.settings.GameSettings;
|
import net.minecraft.client.settings.GameSettings;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
@ -120,14 +118,6 @@ public interface IGameEventListener {
|
|||||||
*/
|
*/
|
||||||
void onReceivePacket(PacketEvent event);
|
void onReceivePacket(PacketEvent event);
|
||||||
|
|
||||||
/**
|
|
||||||
* Run when a query is made for a player's inventory current slot in the context of blocks
|
|
||||||
*
|
|
||||||
* @see InventoryPlayer#getDestroySpeed(IBlockState)
|
|
||||||
* @see InventoryPlayer#canHarvestBlock(IBlockState)
|
|
||||||
*/
|
|
||||||
void onQueryItemSlotForBlocks(ItemSlotEvent event);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run once per game tick from before and after the player's moveRelative method is called
|
* Run once per game tick from before and after the player's moveRelative method is called
|
||||||
*
|
*
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.event.listener.AbstractGameEventListener;
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.interfaces.Toggleable;
|
import baritone.utils.interfaces.Toggleable;
|
||||||
|
|
||||||
|
60
src/main/java/baritone/behavior/impl/FollowBehavior.java
Normal file
60
src/main/java/baritone/behavior/impl/FollowBehavior.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.behavior.impl;
|
||||||
|
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.behavior.Behavior;
|
||||||
|
import baritone.pathing.goals.GoalNear;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follow an entity
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class FollowBehavior extends Behavior {
|
||||||
|
public static final FollowBehavior INSTANCE = new FollowBehavior();
|
||||||
|
|
||||||
|
private FollowBehavior() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity following;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (following == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// lol this is trashy but it works
|
||||||
|
PathingBehavior.INSTANCE.setGoal(new GoalNear(new BlockPos(following), 3));
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void follow(Entity follow) {
|
||||||
|
this.following = follow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
PathingBehavior.INSTANCE.cancel();
|
||||||
|
follow(null);
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ package baritone.behavior.impl;
|
|||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.chunk.Waypoint;
|
import baritone.chunk.Waypoint;
|
||||||
import baritone.chunk.WorldProvider;
|
import baritone.chunk.WorldProvider;
|
||||||
import baritone.event.events.BlockInteractEvent;
|
import baritone.api.event.events.BlockInteractEvent;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import net.minecraft.block.BlockBed;
|
import net.minecraft.block.BlockBed;
|
||||||
|
|
||||||
|
@ -20,9 +20,8 @@ package baritone.behavior.impl;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.Settings;
|
import baritone.Settings;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.event.events.RelativeMoveEvent;
|
import baritone.api.event.events.RelativeMoveEvent;
|
||||||
import baritone.event.events.type.EventState;
|
|
||||||
import baritone.utils.Rotation;
|
import baritone.utils.Rotation;
|
||||||
|
|
||||||
public class LookBehavior extends Behavior {
|
public class LookBehavior extends Behavior {
|
||||||
|
@ -17,10 +17,7 @@
|
|||||||
|
|
||||||
package baritone.behavior.impl;
|
package baritone.behavior.impl;
|
||||||
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.*;
|
||||||
import baritone.utils.Helper;
|
|
||||||
import baritone.utils.Rotation;
|
|
||||||
import baritone.utils.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.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
@ -87,18 +84,6 @@ public final class LookBehaviorUtils implements Helper {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RayTraceResult rayTraceTowards(Rotation rotation) {
|
|
||||||
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
|
||||||
Vec3d start = mc.player.getPositionEyes(1.0F);
|
|
||||||
Vec3d direction = calcVec3dFromRotation(rotation);
|
|
||||||
Vec3d end = start.add(
|
|
||||||
direction.x * blockReachDistance,
|
|
||||||
direction.y * blockReachDistance,
|
|
||||||
direction.z * blockReachDistance
|
|
||||||
);
|
|
||||||
return mc.world.rayTraceBlocks(start, end, false, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if coordinate is reachable with the given block-face rotation offset
|
* Checks if coordinate is reachable with the given block-face rotation offset
|
||||||
*
|
*
|
||||||
@ -108,7 +93,7 @@ public final class LookBehaviorUtils implements Helper {
|
|||||||
*/
|
*/
|
||||||
protected static Optional<Rotation> reachableOffset(BlockPos pos, Vec3d offsetPos) {
|
protected static Optional<Rotation> reachableOffset(BlockPos pos, Vec3d offsetPos) {
|
||||||
Rotation rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), offsetPos);
|
Rotation rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), offsetPos);
|
||||||
RayTraceResult result = rayTraceTowards(rotation);
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
|
||||||
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)) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package baritone.behavior.impl;
|
package baritone.behavior.impl;
|
||||||
|
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.event.events.PacketEvent;
|
import baritone.api.event.events.PacketEvent;
|
||||||
import baritone.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||||
@ -59,7 +59,7 @@ public class MemoryBehavior extends Behavior {
|
|||||||
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
||||||
int size = lockable.getSizeInventory();
|
int size = lockable.getSizeInventory();
|
||||||
|
|
||||||
this.futureInventories.add(new FutureInventory(System.currentTimeMillis(), size, lockable.getGuiID(), tileEntity.getPos()));
|
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), tileEntity.getPos()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ public class MemoryBehavior extends Behavior {
|
|||||||
SPacketOpenWindow packet = event.cast();
|
SPacketOpenWindow packet = event.cast();
|
||||||
|
|
||||||
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
||||||
this.futureInventories.removeIf(i -> System.currentTimeMillis() - i.time > 1000);
|
this.futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
||||||
|
|
||||||
this.futureInventories.stream()
|
this.futureInventories.stream()
|
||||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
||||||
|
111
src/main/java/baritone/behavior/impl/MineBehavior.java
Normal file
111
src/main/java/baritone/behavior/impl/MineBehavior.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.behavior.impl;
|
||||||
|
|
||||||
|
import baritone.api.event.events.PathEvent;
|
||||||
|
import baritone.behavior.Behavior;
|
||||||
|
import baritone.chunk.CachedChunk;
|
||||||
|
import baritone.chunk.ChunkPacker;
|
||||||
|
import baritone.chunk.WorldProvider;
|
||||||
|
import baritone.chunk.WorldScanner;
|
||||||
|
import baritone.pathing.goals.Goal;
|
||||||
|
import baritone.pathing.goals.GoalComposite;
|
||||||
|
import baritone.pathing.goals.GoalTwoBlocks;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mine blocks of a certain type
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class MineBehavior extends Behavior {
|
||||||
|
public static final MineBehavior INSTANCE = new MineBehavior();
|
||||||
|
|
||||||
|
private MineBehavior() {
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> mining;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPathEvent(PathEvent event) {
|
||||||
|
updateGoal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateGoal() {
|
||||||
|
if (mining == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<BlockPos> locs = scanFor(mining, 64);
|
||||||
|
if (locs.isEmpty()) {
|
||||||
|
displayChatMessageRaw("No locations for " + mining + " known, cancelling");
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalTwoBlocks::new).toArray(Goal[]::new)));
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BlockPos> scanFor(List<String> mining, int max) {
|
||||||
|
List<BlockPos> locs = new ArrayList<>();
|
||||||
|
List<String> uninteresting = new ArrayList<>();
|
||||||
|
//long b = System.currentTimeMillis();
|
||||||
|
for (String m : mining) {
|
||||||
|
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(ChunkPacker.stringToBlock(m))) {
|
||||||
|
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(m, 1, 1));
|
||||||
|
} else {
|
||||||
|
uninteresting.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
||||||
|
if (!uninteresting.isEmpty()) {
|
||||||
|
//long before = System.currentTimeMillis();
|
||||||
|
locs.addAll(WorldScanner.INSTANCE.scanLoadedChunks(uninteresting, max));
|
||||||
|
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||||
|
}
|
||||||
|
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
|
||||||
|
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
||||||
|
|
||||||
|
// remove any that are within loaded chunks that aren't actually what we want
|
||||||
|
locs.removeAll(locs.stream()
|
||||||
|
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
|
||||||
|
.filter(pos -> !mining.contains(ChunkPacker.blockToString(BlockStateInterface.get(pos).getBlock()).toLowerCase()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
if (locs.size() > max) {
|
||||||
|
locs = locs.subList(0, max);
|
||||||
|
}
|
||||||
|
return locs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mine(String... mining) {
|
||||||
|
this.mining = mining == null || mining.length == 0 ? null : new ArrayList<>(Arrays.asList(mining));
|
||||||
|
updateGoal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
PathingBehavior.INSTANCE.cancel();
|
||||||
|
mine();
|
||||||
|
}
|
||||||
|
}
|
@ -18,17 +18,16 @@
|
|||||||
package baritone.behavior.impl;
|
package baritone.behavior.impl;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.PathEvent;
|
||||||
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
|
import baritone.api.event.events.RenderEvent;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.event.events.PathEvent;
|
|
||||||
import baritone.event.events.PlayerUpdateEvent;
|
|
||||||
import baritone.event.events.RenderEvent;
|
|
||||||
import baritone.event.events.TickEvent;
|
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
import baritone.pathing.calc.AStarPathFinder;
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.calc.IPathFinder;
|
import baritone.pathing.calc.IPathFinder;
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.pathing.goals.*;
|
||||||
import baritone.pathing.goals.GoalBlock;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.goals.GoalXZ;
|
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
@ -196,27 +195,39 @@ public class PathingBehavior extends Behavior {
|
|||||||
current = null;
|
current = null;
|
||||||
next = null;
|
next = null;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void path() {
|
/**
|
||||||
|
* Start calculating a path if we aren't already
|
||||||
|
*
|
||||||
|
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
||||||
|
*/
|
||||||
|
public boolean path() {
|
||||||
|
if (goal == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (goal.isInGoal(playerFeet())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
displayChatMessageRaw("Currently executing a path. Please cancel it first.");
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (isPathCalcInProgress) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
dispatchPathEvent(PathEvent.CALC_STARTED);
|
dispatchPathEvent(PathEvent.CALC_STARTED);
|
||||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
findPathInNewThread(pathStart(), true, Optional.empty());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPos pathStart() {
|
public BlockPos pathStart() {
|
||||||
BlockPos feet = playerFeet();
|
BlockPos feet = playerFeet();
|
||||||
if (BlockStateInterface.get(feet.down()).getBlock().equals(Blocks.AIR)) {
|
if (BlockStateInterface.get(feet.down()).getBlock().equals(Blocks.AIR) && MovementHelper.canWalkOn(feet.down().down())) {
|
||||||
return feet.down();
|
return feet.down();
|
||||||
}
|
}
|
||||||
return feet;
|
return feet;
|
||||||
@ -293,18 +304,37 @@ public class PathingBehavior extends Behavior {
|
|||||||
displayChatMessageRaw("no goal");
|
displayChatMessageRaw("no goal");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof GoalBlock) {
|
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
|
||||||
BlockPos pos = ((GoalBlock) goal).getGoalPos();
|
BlockPos pos = null;
|
||||||
if (world().getChunk(pos) instanceof EmptyChunk) {
|
if (goal instanceof GoalBlock) {
|
||||||
displayChatMessageRaw("Simplifying GoalBlock to GoalXZ due to distance");
|
pos = ((GoalBlock) goal).getGoalPos();
|
||||||
|
}
|
||||||
|
if (goal instanceof GoalTwoBlocks) {
|
||||||
|
pos = ((GoalTwoBlocks) goal).getGoalPos();
|
||||||
|
}
|
||||||
|
if (goal instanceof GoalNear) {
|
||||||
|
pos = ((GoalNear) goal).getGoalPos();
|
||||||
|
}
|
||||||
|
if (goal instanceof GoalGetToBlock) {
|
||||||
|
pos = ((GoalGetToBlock) goal).getGoalPos();
|
||||||
|
}
|
||||||
|
// TODO simplify each individual goal in a GoalComposite
|
||||||
|
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
|
||||||
|
displayChatMessageRaw("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||||
goal = new GoalXZ(pos.getX(), pos.getZ());
|
goal = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
long timeout;
|
||||||
|
if (current == null) {
|
||||||
|
timeout = Baritone.settings().pathTimeoutMS.<Long>get();
|
||||||
|
} else {
|
||||||
|
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions));
|
IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions));
|
||||||
return pf.calculate();
|
return pf.calculate(timeout);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
displayChatMessageRaw("Exception: " + e);
|
displayChatMessageRaw("Pathing exception: " + e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,10 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
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
|
||||||
IBlockState state = ChunkPacker.stringToBlock(overview[internalPos]).getDefaultState();
|
IBlockState state = ChunkPacker.stringToBlock(overview[internalPos]).getDefaultState();
|
||||||
//System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
||||||
|
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||||
|
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||||
|
}*/
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
PathingBlockType type = getType(x, y, z);
|
PathingBlockType type = getType(x, y, z);
|
||||||
@ -139,7 +142,8 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
int index = z << 4 | x;
|
int index = z << 4 | x;
|
||||||
heightMap[index] = 0;
|
heightMap[index] = 0;
|
||||||
for (int y = 256; y >= 0; y--) {
|
for (int y = 256; y >= 0; y--) {
|
||||||
if (getType(x, y, z) != PathingBlockType.AIR) {
|
int i = getPositionIndex(x, y, z);
|
||||||
|
if (data.get(i) || data.get(i + 1)) {
|
||||||
heightMap[index] = y;
|
heightMap[index] = y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,7 +187,7 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
* @return The bit index
|
* @return The bit index
|
||||||
*/
|
*/
|
||||||
public static int getPositionIndex(int x, int y, int z) {
|
public static int getPositionIndex(int x, int y, int z) {
|
||||||
return (x + (z << 4) + (y << 8)) * 2;
|
return (x << 1) | (z << 5) | (y << 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,6 +77,10 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isCached(int x, int z) {
|
||||||
|
return chunks[x >> 4][z >> 4] != null;
|
||||||
|
}
|
||||||
|
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block) {
|
public final LinkedList<BlockPos> getLocationsOf(String block) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
LinkedList<BlockPos> res = new LinkedList<>();
|
||||||
for (int chunkX = 0; chunkX < 32; chunkX++) {
|
for (int chunkX = 0; chunkX < 32; chunkX++) {
|
||||||
@ -117,8 +121,8 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
Files.createFile(regionFile);
|
Files.createFile(regionFile);
|
||||||
try (
|
try (
|
||||||
FileOutputStream fileOut = new FileOutputStream(regionFile.toFile());
|
FileOutputStream fileOut = new FileOutputStream(regionFile.toFile());
|
||||||
GZIPOutputStream gzipOut = new GZIPOutputStream(fileOut);
|
GZIPOutputStream gzipOut = new GZIPOutputStream(fileOut, 16384);
|
||||||
DataOutputStream out = new DataOutputStream(gzipOut);
|
DataOutputStream out = new DataOutputStream(gzipOut)
|
||||||
) {
|
) {
|
||||||
out.writeInt(CACHED_REGION_MAGIC);
|
out.writeInt(CACHED_REGION_MAGIC);
|
||||||
for (int z = 0; z < 32; z++) {
|
for (int z = 0; z < 32; z++) {
|
||||||
@ -179,12 +183,12 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
System.out.println("Loading region " + x + "," + z + " from disk " + path);
|
System.out.println("Loading region " + x + "," + z + " from disk " + path);
|
||||||
long start = System.currentTimeMillis();
|
long start = System.nanoTime() / 1000000L;
|
||||||
|
|
||||||
try (
|
try (
|
||||||
FileInputStream fileIn = new FileInputStream(regionFile.toFile());
|
FileInputStream fileIn = new FileInputStream(regionFile.toFile());
|
||||||
GZIPInputStream gzipIn = new GZIPInputStream(fileIn);
|
GZIPInputStream gzipIn = new GZIPInputStream(fileIn, 32768);
|
||||||
DataInputStream in = new DataInputStream(gzipIn);
|
DataInputStream in = new DataInputStream(gzipIn)
|
||||||
) {
|
) {
|
||||||
int magic = in.readInt();
|
int magic = in.readInt();
|
||||||
if (magic != CACHED_REGION_MAGIC) {
|
if (magic != CACHED_REGION_MAGIC) {
|
||||||
@ -231,21 +235,23 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
if (tmpCached[x][z] != null) {
|
if (tmpCached[x][z] != null) {
|
||||||
// 16 * 16 * 256 = 65536 so a short is enough
|
// 16 * 16 * 256 = 65536 so a short is enough
|
||||||
// ^ haha jokes on leijurv, java doesn't have unsigned types so that isn't correct
|
// ^ haha jokes on leijurv, java doesn't have unsigned types so that isn't correct
|
||||||
// also ur gay if u have more than 32767 special blocks in a chunk
|
// also why would you have more than 32767 special blocks in a chunk
|
||||||
short numSpecialBlockTypes = in.readShort();
|
// haha double jokes on you now it works for 65535 not just 32767
|
||||||
|
int numSpecialBlockTypes = in.readShort() & 0xffff;
|
||||||
for (int i = 0; i < numSpecialBlockTypes; i++) {
|
for (int i = 0; i < numSpecialBlockTypes; i++) {
|
||||||
String blockName = in.readUTF();
|
String blockName = in.readUTF();
|
||||||
List<BlockPos> locs = new ArrayList<>();
|
List<BlockPos> locs = new ArrayList<>();
|
||||||
location[x][z].put(blockName, locs);
|
location[x][z].put(blockName, locs);
|
||||||
short numLocations = in.readShort();
|
int numLocations = in.readShort() & 0xffff;
|
||||||
|
if (numLocations == 0) {
|
||||||
|
// an entire chunk full of air can happen in the end
|
||||||
|
numLocations = 65536;
|
||||||
|
}
|
||||||
for (int j = 0; j < numLocations; j++) {
|
for (int j = 0; j < numLocations; j++) {
|
||||||
byte xz = in.readByte();
|
byte xz = in.readByte();
|
||||||
int X = xz & 0x0f;
|
int X = xz & 0x0f;
|
||||||
int Z = (xz >>> 4) & 0x0f;
|
int Z = (xz >>> 4) & 0x0f;
|
||||||
int Y = (int) in.readByte();
|
int Y = in.readByte() & 0xff;
|
||||||
if (Y < 0) {
|
|
||||||
Y += 256;
|
|
||||||
}
|
|
||||||
locs.add(new BlockPos(X, Y, Z));
|
locs.add(new BlockPos(X, Y, Z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +266,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hasUnsavedChanges = false;
|
hasUnsavedChanges = false;
|
||||||
long end = System.currentTimeMillis();
|
long end = System.nanoTime() / 1000000L;
|
||||||
System.out.println("Loaded region successfully in " + (end - start) + "ms");
|
System.out.println("Loaded region successfully in " + (end - start) + "ms");
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
@ -59,16 +59,17 @@ public final class CachedWorld implements IBlockTypeAccess {
|
|||||||
if (!Files.exists(directory)) {
|
if (!Files.exists(directory)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(directory);
|
Files.createDirectories(directory);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.directory = directory.toString();
|
this.directory = directory.toString();
|
||||||
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);
|
||||||
new PackerThread().start();
|
new PackerThread().start();
|
||||||
new Thread() {
|
new Thread(() -> {
|
||||||
public void run() {
|
|
||||||
try {
|
try {
|
||||||
|
Thread.sleep(30000);
|
||||||
while (true) {
|
while (true) {
|
||||||
// since a region only saves if it's been modified since its last save
|
// since a region only saves if it's been modified since its last save
|
||||||
// saving every 10 minutes means that once it's time to exit
|
// saving every 10 minutes means that once it's time to exit
|
||||||
@ -79,8 +80,7 @@ public final class CachedWorld implements IBlockTypeAccess {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}).start();
|
||||||
}.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void queueForPacking(Chunk chunk) {
|
public final void queueForPacking(Chunk chunk) {
|
||||||
@ -101,6 +101,17 @@ public final class CachedWorld implements IBlockTypeAccess {
|
|||||||
return region.getBlock(x & 511, y, z & 511);
|
return region.getBlock(x & 511, y, z & 511);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isCached(BlockPos pos) {
|
||||||
|
int x = pos.getX();
|
||||||
|
int z = pos.getZ();
|
||||||
|
CachedRegion region = getRegion(x >> 9, z >> 9);
|
||||||
|
if (region == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return region.isCached(x & 511, z & 511);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block, int minimum, int maxRegionDistanceSq) {
|
public final LinkedList<BlockPos> getLocationsOf(String block, int minimum, int maxRegionDistanceSq) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
LinkedList<BlockPos> res = new LinkedList<>();
|
||||||
int playerRegionX = playerFeet().getX() >> 9;
|
int playerRegionX = playerFeet().getX() >> 9;
|
||||||
@ -140,22 +151,22 @@ public final class CachedWorld implements IBlockTypeAccess {
|
|||||||
System.out.println("Not saving to disk; chunk caching is disabled.");
|
System.out.println("Not saving to disk; chunk caching is disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long start = System.currentTimeMillis();
|
long start = System.nanoTime() / 1000000L;
|
||||||
this.cachedRegions.values().forEach(region -> {
|
this.cachedRegions.values().parallelStream().forEach(region -> {
|
||||||
if (region != null)
|
if (region != null)
|
||||||
region.save(this.directory);
|
region.save(this.directory);
|
||||||
});
|
});
|
||||||
long now = System.currentTimeMillis();
|
long now = System.nanoTime() / 1000000L;
|
||||||
System.out.println("World save took " + (now - start) + "ms");
|
System.out.println("World save took " + (now - start) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void reloadAllFromDisk() {
|
public final void reloadAllFromDisk() {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.nanoTime() / 1000000L;
|
||||||
this.cachedRegions.values().forEach(region -> {
|
this.cachedRegions.values().forEach(region -> {
|
||||||
if (region != null)
|
if (region != null)
|
||||||
region.load(this.directory);
|
region.load(this.directory);
|
||||||
});
|
});
|
||||||
long now = System.currentTimeMillis();
|
long now = System.nanoTime() / 1000000L;
|
||||||
System.out.println("World load took " + (now - start) + "ms");
|
System.out.println("World load took " + (now - start) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,18 +18,19 @@
|
|||||||
package baritone.chunk;
|
package baritone.chunk;
|
||||||
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
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.BlockAir;
|
|
||||||
import net.minecraft.block.BlockDoublePlant;
|
import net.minecraft.block.BlockDoublePlant;
|
||||||
|
import net.minecraft.block.BlockFlower;
|
||||||
import net.minecraft.block.BlockTallGrass;
|
import net.minecraft.block.BlockTallGrass;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.chunk.BlockStateContainer;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -41,20 +42,56 @@ public final class ChunkPacker implements Helper {
|
|||||||
|
|
||||||
private ChunkPacker() {}
|
private ChunkPacker() {}
|
||||||
|
|
||||||
public static CachedChunk pack(Chunk chunk) {
|
private static BitSet originalPacker(Chunk chunk) {
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
|
||||||
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||||
try {
|
|
||||||
for (int y = 0; y < 256; y++) {
|
for (int y = 0; y < 256; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
Block block = chunk.getBlockState(x, y, z).getBlock();
|
IBlockState state = chunk.getBlockState(x, y, z);
|
||||||
boolean[] bits = getPathingBlockType(block).getBits();
|
boolean[] bits = getPathingBlockType(state).getBits();
|
||||||
bitSet.set(index, bits[0]);
|
bitSet.set(index, bits[0]);
|
||||||
bitSet.set(index + 1, bits[1]);
|
bitSet.set(index + 1, bits[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CachedChunk pack(Chunk chunk) {
|
||||||
|
long start = System.nanoTime() / 1000000L;
|
||||||
|
|
||||||
|
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
||||||
|
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||||
|
try {
|
||||||
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
|
if (extendedblockstorage == null) {
|
||||||
|
// any 16x16x16 area that's all air will have null storage
|
||||||
|
// for example, in an ocean biome, with air from y=64 to y=256
|
||||||
|
// the first 4 extended blocks storages will be full
|
||||||
|
// and the remaining 12 will be null
|
||||||
|
|
||||||
|
// since the index into the bitset is calculated from the x y and z
|
||||||
|
// and doesn't function as an append, we can entirely skip the scanning
|
||||||
|
// since a bitset is initialized to all zero, and air is saved as zeros
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
|
int yReal = y0 << 4;
|
||||||
|
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||||
|
// for better cache locality, iterate in that order
|
||||||
|
for (int y1 = 0; y1 < 16; y1++) {
|
||||||
|
int y = y1 | yReal;
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
|
IBlockState state = bsc.get(x, y1, z);
|
||||||
|
boolean[] bits = getPathingBlockType(state).getBits();
|
||||||
|
bitSet.set(index, bits[0]);
|
||||||
|
bitSet.set(index + 1, bits[1]);
|
||||||
|
Block block = state.getBlock();
|
||||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
|
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
|
||||||
String name = blockToString(block);
|
String name = blockToString(block);
|
||||||
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y, z));
|
specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y, z));
|
||||||
@ -62,25 +99,29 @@ public final class ChunkPacker implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/*if (!bitSet.equals(originalPacker(chunk))) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}*/
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
//System.out.println("Packed special blocks: " + specialBlocks);
|
//System.out.println("Packed special blocks: " + specialBlocks);
|
||||||
long end = System.currentTimeMillis();
|
long end = System.nanoTime() / 1000000L;
|
||||||
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
|
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
|
||||||
String[] blockNames = new String[256];
|
String[] blockNames = new String[256];
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
|
outerLoop:
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
int height = chunk.getHeightValue(x, z);
|
for (int y = 255; y >= 0; y--) {
|
||||||
IBlockState blockState = chunk.getBlockState(x, height, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
for (int y = height; y > 0; y--) {
|
if (bitSet.get(index) || bitSet.get(index + 1)) {
|
||||||
blockState = chunk.getBlockState(x, y, z);
|
String name = blockToString(chunk.getBlockState(x, y, z).getBlock());
|
||||||
if (getPathingBlockType(blockState.getBlock()) != PathingBlockType.AIR) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String name = blockToString(blockState.getBlock());
|
|
||||||
blockNames[z << 4 | x] = name;
|
blockNames[z << 4 | x] = name;
|
||||||
|
continue outerLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blockNames[z << 4 | x] = "air";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CachedChunk cached = new CachedChunk(chunk.x, chunk.z, bitSet, blockNames, specialBlocks);
|
CachedChunk cached = new CachedChunk(chunk.x, chunk.z, bitSet, blockNames, specialBlocks);
|
||||||
@ -104,19 +145,21 @@ public final class ChunkPacker implements Helper {
|
|||||||
return Block.getBlockFromName(name);
|
return Block.getBlockFromName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PathingBlockType getPathingBlockType(Block block) {
|
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
||||||
if (BlockStateInterface.isWater(block)) {
|
Block block = state.getBlock();
|
||||||
|
if (block.equals(Blocks.WATER)) {
|
||||||
|
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||||
return PathingBlockType.WATER;
|
return PathingBlockType.WATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MovementHelper.avoidWalkingInto(block)) {
|
if (MovementHelper.avoidWalkingInto(block) || block.equals(Blocks.FLOWING_WATER) || MovementHelper.isBottomSlab(state)) {
|
||||||
return PathingBlockType.AVOID;
|
return PathingBlockType.AVOID;
|
||||||
}
|
}
|
||||||
// We used to do an AABB check here
|
// We used to do an AABB check here
|
||||||
// however, this failed in the nether when you were near a nether fortress
|
// however, this failed in the nether when you were near a nether fortress
|
||||||
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
||||||
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
||||||
if (block instanceof BlockAir || block instanceof BlockTallGrass || block instanceof BlockDoublePlant) {
|
if (block == Blocks.AIR || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
||||||
return PathingBlockType.AIR;
|
return PathingBlockType.AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
|
|
||||||
package baritone.chunk;
|
package baritone.chunk;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single waypoint
|
* A single waypoint
|
||||||
@ -30,6 +29,7 @@ import java.util.Map;
|
|||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class Waypoint {
|
public class Waypoint {
|
||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Tag tag;
|
public final Tag tag;
|
||||||
private final long creationTimestamp;
|
private final long creationTimestamp;
|
||||||
@ -72,19 +72,21 @@ public class Waypoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Tag {
|
public enum Tag {
|
||||||
HOME, DEATH, BED, USER;
|
HOME("home", "base"),
|
||||||
|
DEATH("death"),
|
||||||
|
BED("bed", "spawn"),
|
||||||
|
USER();
|
||||||
|
|
||||||
|
private static final List<Tag> TAG_LIST = ImmutableList.<Tag>builder().add(Tag.values()).build();
|
||||||
|
|
||||||
|
private final String[] names;
|
||||||
|
|
||||||
|
Tag(String... names) {
|
||||||
|
this.names = names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<String, Tag> TAG_MAP;
|
public static Tag fromString(String name) {
|
||||||
|
return TAG_LIST.stream().filter(tag -> ArrayUtils.contains(tag.names, name.toLowerCase())).findFirst().orElse(null);
|
||||||
static {
|
}
|
||||||
HashMap<String, Tag> map = new HashMap<>();
|
|
||||||
map.put("home", Tag.HOME);
|
|
||||||
map.put("base", Tag.HOME);
|
|
||||||
map.put("bed", Tag.BED);
|
|
||||||
map.put("spawn", Tag.BED);
|
|
||||||
map.put("death", Tag.DEATH);
|
|
||||||
TAG_MAP = Collections.unmodifiableMap(map);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
package baritone.chunk;
|
package baritone.chunk;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.launch.mixins.accessor.IAnvilChunkLoader;
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||||
import baritone.launch.mixins.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
|
100
src/main/java/baritone/chunk/WorldScanner.java
Normal file
100
src/main/java/baritone/chunk/WorldScanner.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.chunk;
|
||||||
|
|
||||||
|
import baritone.utils.Helper;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.chunk.BlockStateContainer;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public enum WorldScanner implements Helper {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public List<BlockPos> scanLoadedChunks(List<String> blockTypes, int max) {
|
||||||
|
List<Block> asBlocks = blockTypes.stream().map(ChunkPacker::stringToBlock).collect(Collectors.toList());
|
||||||
|
if (asBlocks.contains(null)) {
|
||||||
|
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blockTypes.toString());
|
||||||
|
}
|
||||||
|
LinkedList<BlockPos> res = new LinkedList<>();
|
||||||
|
if (asBlocks.isEmpty()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
ChunkProviderClient chunkProvider = world().getChunkProvider();
|
||||||
|
|
||||||
|
int playerChunkX = playerFeet().getX() >> 4;
|
||||||
|
int playerChunkZ = playerFeet().getZ() >> 4;
|
||||||
|
|
||||||
|
int searchRadius = 2;
|
||||||
|
while (true) {
|
||||||
|
boolean allUnloaded = true;
|
||||||
|
for (int xoff = -searchRadius; xoff <= searchRadius; xoff++) {
|
||||||
|
for (int zoff = -searchRadius; zoff <= searchRadius; zoff++) {
|
||||||
|
int distance = xoff * xoff + zoff * zoff;
|
||||||
|
if (distance != searchRadius) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int chunkX = xoff + playerChunkX;
|
||||||
|
int chunkZ = zoff + playerChunkZ;
|
||||||
|
Chunk chunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
|
||||||
|
if (chunk == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allUnloaded = false;
|
||||||
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
|
chunkX = chunkX << 4;
|
||||||
|
chunkZ = chunkZ << 4;
|
||||||
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
|
if (extendedblockstorage == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int yReal = y0 << 4;
|
||||||
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
|
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||||
|
// for better cache locality, iterate in that order
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
IBlockState state = bsc.get(x, y, z);
|
||||||
|
if (asBlocks.contains(state.getBlock())) {
|
||||||
|
res.add(new BlockPos(chunkX | x, yReal | y, chunkZ | z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allUnloaded) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (res.size() >= max) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
searchRadius++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,62 +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 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package baritone.launch.mixins;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.event.events.ItemSlotEvent;
|
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
|
||||||
import org.spongepowered.asm.lib.Opcodes;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 8/20/2018
|
|
||||||
*/
|
|
||||||
@Mixin(InventoryPlayer.class)
|
|
||||||
public class MixinInventoryPlayer {
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "getDestroySpeed",
|
|
||||||
at = @At(
|
|
||||||
value = "FIELD",
|
|
||||||
opcode = Opcodes.GETFIELD,
|
|
||||||
target = "net/minecraft/entity/player/InventoryPlayer.currentItem:I"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private int getDestroySpeed$getCurrentItem(InventoryPlayer inventory) {
|
|
||||||
ItemSlotEvent event = new ItemSlotEvent(inventory.currentItem);
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onQueryItemSlotForBlocks(event);
|
|
||||||
return event.getSlot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "canHarvestBlock",
|
|
||||||
at = @At(
|
|
||||||
value = "FIELD",
|
|
||||||
opcode = Opcodes.GETFIELD,
|
|
||||||
target = "net/minecraft/entity/player/InventoryPlayer.currentItem:I"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private int canHarvestBlock$getCurrentItem(InventoryPlayer inventory) {
|
|
||||||
ItemSlotEvent event = new ItemSlotEvent(inventory.currentItem);
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onQueryItemSlotForBlocks(event);
|
|
||||||
return event.getSlot();
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,9 +18,9 @@
|
|||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.chunk.CachedWorld;
|
||||||
import baritone.chunk.WorldProvider;
|
import baritone.chunk.WorldProvider;
|
||||||
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
||||||
import baritone.pathing.calc.openset.IOpenSet;
|
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.pathing.goals.Goal;
|
||||||
import baritone.pathing.movement.ActionCosts;
|
import baritone.pathing.movement.ActionCosts;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
@ -31,9 +31,9 @@ import baritone.pathing.path.IPath;
|
|||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
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.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -55,11 +55,11 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Optional<IPath> calculate0() {
|
protected Optional<IPath> calculate0(long timeout) {
|
||||||
startNode = getNodeAtPosition(start);
|
startNode = getNodeAtPosition(start);
|
||||||
startNode.cost = 0;
|
startNode.cost = 0;
|
||||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||||
IOpenSet openSet = new BinaryHeapOpenSet();
|
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
||||||
openSet.insert(startNode);
|
openSet.insert(startNode);
|
||||||
startNode.isOpen = true;
|
startNode.isOpen = true;
|
||||||
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
||||||
@ -70,17 +70,23 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
CalculationContext calcContext = new CalculationContext();
|
CalculationContext calcContext = new CalculationContext();
|
||||||
HashSet<BetterBlockPos> favored = favoredPositions.orElse(null);
|
HashSet<BetterBlockPos> favored = favoredPositions.orElse(null);
|
||||||
currentlyRunning = this;
|
currentlyRunning = this;
|
||||||
long startTime = System.currentTimeMillis();
|
CachedWorld cachedWorld = Optional.ofNullable(WorldProvider.INSTANCE.getCurrentWorld()).map(w -> w.cache).orElse(null);
|
||||||
|
ChunkProviderClient chunkProvider = Minecraft.getMinecraft().world.getChunkProvider();
|
||||||
|
long startTime = System.nanoTime() / 1000000L;
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS : Baritone.settings().pathTimeoutMS).<Long>get();
|
if (slowPath) {
|
||||||
long lastPrintout = 0;
|
displayChatMessageRaw("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + timeout + "ms");
|
||||||
|
}
|
||||||
|
long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : timeout);
|
||||||
|
//long lastPrintout = 0;
|
||||||
int numNodes = 0;
|
int numNodes = 0;
|
||||||
|
int numMovementsConsidered = 0;
|
||||||
int numEmptyChunk = 0;
|
int numEmptyChunk = 0;
|
||||||
boolean favoring = favoredPositions.isPresent();
|
boolean favoring = favoredPositions.isPresent();
|
||||||
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();
|
||||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.currentTimeMillis() < timeoutTime) {
|
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.nanoTime() / 1000000L - timeoutTime < 0 && !cancelRequested) {
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
||||||
@ -92,39 +98,33 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
mostRecentConsidered = currentNode;
|
mostRecentConsidered = currentNode;
|
||||||
BetterBlockPos currentNodePos = currentNode.pos;
|
BetterBlockPos currentNodePos = currentNode.pos;
|
||||||
numNodes++;
|
numNodes++;
|
||||||
if (System.currentTimeMillis() > lastPrintout + 1000) {//print once a second
|
|
||||||
System.out.println("searching... at " + currentNodePos + ", considered " + numNodes + " nodes so far");
|
|
||||||
lastPrintout = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
if (goal.isInGoal(currentNodePos)) {
|
if (goal.isInGoal(currentNodePos)) {
|
||||||
currentlyRunning = null;
|
currentlyRunning = null;
|
||||||
|
displayChatMessageRaw("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes));
|
return Optional.of(new Path(startNode, currentNode, numNodes));
|
||||||
}
|
}
|
||||||
//long constructStart = System.nanoTime();
|
|
||||||
Movement[] possibleMovements = getConnectedPositions(currentNodePos, calcContext);//movement that we could take that start at currentNodePos, in random order
|
Movement[] possibleMovements = getConnectedPositions(currentNodePos, calcContext);//movement that we could take that start at currentNodePos, in random order
|
||||||
shuffle(possibleMovements);
|
shuffle(possibleMovements);
|
||||||
//long constructEnd = System.nanoTime();
|
|
||||||
//System.out.println(constructEnd - constructStart);
|
|
||||||
for (Movement movementToGetToNeighbor : possibleMovements) {
|
for (Movement movementToGetToNeighbor : possibleMovements) {
|
||||||
if (movementToGetToNeighbor == null) {
|
if (movementToGetToNeighbor == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BetterBlockPos dest = (BetterBlockPos) movementToGetToNeighbor.getDest();
|
BetterBlockPos dest = (BetterBlockPos) movementToGetToNeighbor.getDest();
|
||||||
boolean isPositionCached = false;
|
int chunkX = currentNodePos.x >> 4;
|
||||||
if (WorldProvider.INSTANCE.getCurrentWorld() != null) {
|
int chunkZ = currentNodePos.z >> 4;
|
||||||
if (WorldProvider.INSTANCE.getCurrentWorld().cache.getBlock(dest) != null) {
|
if (dest.x >> 4 != chunkX || dest.z >> 4 != chunkZ) {
|
||||||
isPositionCached = true;
|
// 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 (chunkProvider.getLoadedChunk(chunkX, chunkZ) == null) {
|
||||||
}
|
// see issue #106
|
||||||
if (!isPositionCached && Minecraft.getMinecraft().world.getChunk(dest) instanceof EmptyChunk) {
|
if (cachedWorld == null || !cachedWorld.isCached(dest)) {
|
||||||
numEmptyChunk++;
|
numEmptyChunk++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//long costStart = System.nanoTime();
|
}
|
||||||
|
}
|
||||||
// TODO cache cost
|
// TODO cache cost
|
||||||
double actionCost = movementToGetToNeighbor.getCost(calcContext);
|
double actionCost = movementToGetToNeighbor.getCost(calcContext);
|
||||||
//long costEnd = System.nanoTime();
|
numMovementsConsidered++;
|
||||||
//System.out.println(movementToGetToNeighbor.getClass() + "" + (costEnd - costStart));
|
|
||||||
if (actionCost >= ActionCosts.COST_INF) {
|
if (actionCost >= ActionCosts.COST_INF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -162,6 +162,9 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < bestSoFar.length; i++) {
|
||||||
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
||||||
if (heuristic < bestHeuristicSoFar[i]) {
|
if (heuristic < bestHeuristicSoFar[i]) {
|
||||||
|
if (bestHeuristicSoFar[i] - heuristic < 0.01 && minimumImprovementRepropagation) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
bestHeuristicSoFar[i] = heuristic;
|
bestHeuristicSoFar[i] = heuristic;
|
||||||
bestSoFar[i] = neighbor;
|
bestSoFar[i] = neighbor;
|
||||||
}
|
}
|
||||||
@ -169,6 +172,13 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cancelRequested) {
|
||||||
|
currentlyRunning = null;
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
System.out.println(numMovementsConsidered + " movements considered");
|
||||||
|
System.out.println("Open set size: " + openSet.size());
|
||||||
|
System.out.println((int) (numNodes * 1.0 / ((System.nanoTime() / 1000000L - startTime) / 1000F)) + " nodes per second");
|
||||||
double bestDist = 0;
|
double bestDist = 0;
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < bestSoFar.length; i++) {
|
||||||
if (bestSoFar[i] == null) {
|
if (bestSoFar[i] == null) {
|
||||||
@ -179,18 +189,18 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
bestDist = dist;
|
bestDist = dist;
|
||||||
}
|
}
|
||||||
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
displayChatMessageRaw("Took " + (System.currentTimeMillis() - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i]);
|
displayChatMessageRaw("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered");
|
||||||
if (COEFFICIENTS[i] >= 3) {
|
if (COEFFICIENTS[i] >= 3) {
|
||||||
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
||||||
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
||||||
System.out.println("But I'm going to do it anyway, because yolo");
|
System.out.println("But I'm going to do it anyway, because yolo");
|
||||||
}
|
}
|
||||||
System.out.println("Path goes for " + dist + " blocks");
|
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
||||||
currentlyRunning = null;
|
currentlyRunning = null;
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], numNodes));
|
return Optional.of(new Path(startNode, bestSoFar[i], numNodes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayChatMessageRaw("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + bestDist + " blocks =(");
|
displayChatMessageRaw("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
||||||
displayChatMessageRaw("No path found =(");
|
displayChatMessageRaw("No path found =(");
|
||||||
currentlyRunning = null;
|
currentlyRunning = null;
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
|
import baritone.behavior.impl.PathingBehavior;
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.pathing.goals.Goal;
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +42,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
|
|
||||||
protected final Goal goal;
|
protected final Goal goal;
|
||||||
|
|
||||||
protected final Map<BetterBlockPos, PathNode> map;
|
private final Long2ObjectOpenHashMap<PathNode> map; // see issue #107
|
||||||
|
|
||||||
protected PathNode startNode;
|
protected PathNode startNode;
|
||||||
|
|
||||||
@ -52,6 +52,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
|
|
||||||
private volatile boolean isFinished;
|
private volatile boolean isFinished;
|
||||||
|
|
||||||
|
protected boolean cancelRequested;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so
|
* This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so
|
||||||
* long it was easier as a Google Doc (because I could insert charts).
|
* long it was easier as a Google Doc (because I could insert charts).
|
||||||
@ -67,19 +69,34 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
AbstractNodeCostSearch(BlockPos start, Goal goal) {
|
AbstractNodeCostSearch(BlockPos start, Goal goal) {
|
||||||
this.start = new BetterBlockPos(start.getX(), start.getY(), start.getZ());
|
this.start = new BetterBlockPos(start.getX(), start.getY(), start.getZ());
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
this.map = new HashMap<>();
|
this.map = new Long2ObjectOpenHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Optional<IPath> calculate() {
|
public void cancel() {
|
||||||
|
cancelRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Optional<IPath> calculate(long timeout) {
|
||||||
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!");
|
||||||
}
|
}
|
||||||
Optional<IPath> path = calculate0();
|
this.cancelRequested = false;
|
||||||
|
try {
|
||||||
|
Optional<IPath> path = calculate0(timeout);
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
return path;
|
return path;
|
||||||
|
} catch (Exception e) {
|
||||||
|
currentlyRunning = null;
|
||||||
|
isFinished = true;
|
||||||
|
if (e instanceof RuntimeException) {
|
||||||
|
throw (RuntimeException) e;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Optional<IPath> calculate0();
|
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
|
||||||
@ -105,7 +122,19 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
* @return The associated node
|
* @return The associated node
|
||||||
*/
|
*/
|
||||||
protected PathNode getNodeAtPosition(BetterBlockPos pos) {
|
protected PathNode getNodeAtPosition(BetterBlockPos pos) {
|
||||||
return map.computeIfAbsent(pos, p -> new PathNode(p, goal));
|
// see issue #107
|
||||||
|
long hashCode = pos.hashCode;
|
||||||
|
PathNode node = map.get(hashCode);
|
||||||
|
if (node == null) {
|
||||||
|
node = new PathNode(pos, goal);
|
||||||
|
map.put(hashCode, node);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void forceCancel() {
|
||||||
|
PathingBehavior.INSTANCE.cancel();
|
||||||
|
currentlyRunning = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +39,7 @@ public interface IPathFinder {
|
|||||||
*
|
*
|
||||||
* @return The final path
|
* @return The final path
|
||||||
*/
|
*/
|
||||||
Optional<IPath> calculate();
|
Optional<IPath> calculate(long timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -26,7 +26,7 @@ import java.util.Arrays;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class BinaryHeapOpenSet implements IOpenSet {
|
public final class BinaryHeapOpenSet implements IOpenSet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initial capacity of the heap (2^10)
|
* The initial capacity of the heap (2^10)
|
||||||
@ -52,6 +52,10 @@ public class BinaryHeapOpenSet implements IOpenSet {
|
|||||||
this.array = new PathNode[size];
|
this.array = new PathNode[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void insert(PathNode value) {
|
public final void insert(PathNode value) {
|
||||||
if (size >= array.length - 1) {
|
if (size >= array.length - 1) {
|
||||||
@ -104,14 +108,13 @@ public class BinaryHeapOpenSet implements IOpenSet {
|
|||||||
int smallerChild = 2;
|
int smallerChild = 2;
|
||||||
double cost = val.combinedCost;
|
double cost = val.combinedCost;
|
||||||
do {
|
do {
|
||||||
int right = smallerChild + 1;
|
|
||||||
PathNode smallerChildNode = array[smallerChild];
|
PathNode smallerChildNode = array[smallerChild];
|
||||||
double smallerChildCost = smallerChildNode.combinedCost;
|
double smallerChildCost = smallerChildNode.combinedCost;
|
||||||
if (right <= size) {
|
if (smallerChild < size) {
|
||||||
PathNode rightChildNode = array[right];
|
PathNode rightChildNode = array[smallerChild + 1];
|
||||||
double rightChildCost = rightChildNode.combinedCost;
|
double rightChildCost = rightChildNode.combinedCost;
|
||||||
if (smallerChildCost > rightChildCost) {
|
if (smallerChildCost > rightChildCost) {
|
||||||
smallerChild = right;
|
smallerChild++;
|
||||||
smallerChildCost = rightChildCost;
|
smallerChildCost = rightChildCost;
|
||||||
smallerChildNode = rightChildNode;
|
smallerChildNode = rightChildNode;
|
||||||
}
|
}
|
||||||
@ -124,8 +127,7 @@ public class BinaryHeapOpenSet implements IOpenSet {
|
|||||||
val.heapPosition = smallerChild;
|
val.heapPosition = smallerChild;
|
||||||
smallerChildNode.heapPosition = index;
|
smallerChildNode.heapPosition = index;
|
||||||
index = smallerChild;
|
index = smallerChild;
|
||||||
smallerChild = index << 1;
|
} while ((smallerChild <<= 1) <= size);
|
||||||
} while (smallerChild <= size);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,11 @@ import baritone.pathing.calc.PathNode;
|
|||||||
/**
|
/**
|
||||||
* A linked list implementation of an open set. This is the original implementation from MineBot.
|
* A linked list implementation of an open set. This is the original implementation from MineBot.
|
||||||
* It has incredibly fast insert performance, at the cost of O(n) removeLowest.
|
* It has incredibly fast insert performance, at the cost of O(n) removeLowest.
|
||||||
|
* It sucks. BinaryHeapOpenSet results in more than 10x more nodes considered in 4 seconds.
|
||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class LinkedListOpenSet implements IOpenSet {
|
class LinkedListOpenSet implements IOpenSet {
|
||||||
private Node first = null;
|
private Node first = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,25 +17,47 @@
|
|||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.pathing.goals;
|
||||||
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't get into the block, but get directly adjacent to it. Useful for chests.
|
* Don't get into the block, but get directly adjacent to it. Useful for chests.
|
||||||
*
|
*
|
||||||
* @author avecowa
|
* @author avecowa
|
||||||
*/
|
*/
|
||||||
public class GoalGetToBlock extends GoalComposite {
|
public class GoalGetToBlock implements Goal {
|
||||||
|
|
||||||
|
private final int x;
|
||||||
|
private final int y;
|
||||||
|
private final int z;
|
||||||
|
|
||||||
public GoalGetToBlock(BlockPos pos) {
|
public GoalGetToBlock(BlockPos pos) {
|
||||||
super(adjacentBlocks(pos));
|
this.x = pos.getX();
|
||||||
|
this.y = pos.getY();
|
||||||
|
this.z = pos.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockPos[] adjacentBlocks(BlockPos pos) {
|
public BlockPos getGoalPos() {
|
||||||
BlockPos[] sides = new BlockPos[6];
|
return new BetterBlockPos(x, y, z);
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
sides[i] = pos.offset(EnumFacing.values()[i]);
|
|
||||||
}
|
}
|
||||||
return sides;
|
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(BlockPos pos) {
|
||||||
|
int xDiff = pos.getX() - this.x;
|
||||||
|
int yDiff = pos.getY() - this.y;
|
||||||
|
int zDiff = pos.getZ() - this.z;
|
||||||
|
if (yDiff < 0) {
|
||||||
|
yDiff++;
|
||||||
|
}
|
||||||
|
return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double heuristic(BlockPos pos) {
|
||||||
|
int xDiff = pos.getX() - this.x;
|
||||||
|
int yDiff = pos.getY() - this.y;
|
||||||
|
int zDiff = pos.getZ() - this.z;
|
||||||
|
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
64
src/main/java/baritone/pathing/goals/GoalNear.java
Normal file
64
src/main/java/baritone/pathing/goals/GoalNear.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.pathing.goals;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class GoalNear implements Goal {
|
||||||
|
final int x;
|
||||||
|
final int y;
|
||||||
|
final int z;
|
||||||
|
final int rangeSq;
|
||||||
|
|
||||||
|
public GoalNear(BlockPos pos, int range) {
|
||||||
|
this.x = pos.getX();
|
||||||
|
this.y = pos.getY();
|
||||||
|
this.z = pos.getZ();
|
||||||
|
this.rangeSq = range * range;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(BlockPos pos) {
|
||||||
|
int diffX = x - pos.getX();
|
||||||
|
int diffY = y - pos.getY();
|
||||||
|
int diffZ = z - pos.getZ();
|
||||||
|
return diffX * diffX + diffY * diffY + diffZ * diffZ <= rangeSq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double heuristic(BlockPos pos) {
|
||||||
|
int diffX = x - pos.getX();
|
||||||
|
int diffY = y - pos.getY();
|
||||||
|
int diffZ = z - pos.getZ();
|
||||||
|
return GoalBlock.calculate(diffX, diffY, diffZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getGoalPos() {
|
||||||
|
return new BlockPos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GoalNear{" +
|
||||||
|
"x=" + x +
|
||||||
|
", y=" + y +
|
||||||
|
", z=" + z +
|
||||||
|
", rangeSq=" + rangeSq +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -68,6 +68,10 @@ public class GoalTwoBlocks implements Goal {
|
|||||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockPos getGoalPos() {
|
||||||
|
return new BlockPos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GoalTwoBlocks{x=" + x + ",y=" + y + ",z=" + z + "}";
|
return "GoalTwoBlocks{x=" + x + ",y=" + y + ",z=" + z + "}";
|
||||||
|
@ -20,6 +20,7 @@ package baritone.pathing.goals;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,9 +89,9 @@ public class GoalXZ implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
||||||
double theta = Utils.degToRad(yaw);
|
float theta = (float) Utils.degToRad(yaw);
|
||||||
double x = origin.x - Math.sin(theta) * distance;
|
double x = origin.x - MathHelper.sin(theta) * distance;
|
||||||
double z = origin.z + Math.cos(theta) * distance;
|
double z = origin.z + MathHelper.cos(theta) * distance;
|
||||||
return new GoalXZ((int) x, (int) z);
|
return new GoalXZ((int) x, (int) z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ public interface ActionCosts extends ActionCostsButOnlyTheOnesThatMakeMickeyDieI
|
|||||||
*/
|
*/
|
||||||
double WALK_ONE_BLOCK_COST = 20 / 4.317; // 4.633
|
double WALK_ONE_BLOCK_COST = 20 / 4.317; // 4.633
|
||||||
double WALK_ONE_IN_WATER_COST = 20 / 2.2;
|
double WALK_ONE_IN_WATER_COST = 20 / 2.2;
|
||||||
double WALK_ONE_OVER_SOUL_SAND_COST = WALK_ONE_IN_WATER_COST; // TODO issue #7
|
double WALK_ONE_OVER_SOUL_SAND_COST = WALK_ONE_BLOCK_COST * 0.5; // 0.4 in BlockSoulSand but effectively about half
|
||||||
|
double SPRINT_ONE_OVER_SOUL_SAND_COST = WALK_ONE_OVER_SOUL_SAND_COST / 0.75;
|
||||||
double LADDER_UP_ONE_COST = 20 / 2.35;
|
double LADDER_UP_ONE_COST = 20 / 2.35;
|
||||||
double LADDER_DOWN_ONE_COST = 20 / 3.0;
|
double LADDER_DOWN_ONE_COST = 20 / 3.0;
|
||||||
double SNEAK_ONE_BLOCK_COST = 20 / 1.3;
|
double SNEAK_ONE_BLOCK_COST = 20 / 1.3;
|
||||||
|
@ -46,7 +46,6 @@ public class CalculationContext implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CalculationContext(ToolSet toolSet) {
|
public CalculationContext(ToolSet toolSet) {
|
||||||
player().setSprinting(true);
|
|
||||||
this.toolSet = toolSet;
|
this.toolSet = toolSet;
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
|
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
|
||||||
|
@ -21,18 +21,13 @@ import baritone.Baritone;
|
|||||||
import baritone.behavior.impl.LookBehavior;
|
import baritone.behavior.impl.LookBehavior;
|
||||||
import baritone.behavior.impl.LookBehaviorUtils;
|
import baritone.behavior.impl.LookBehaviorUtils;
|
||||||
import baritone.pathing.movement.MovementState.MovementStatus;
|
import baritone.pathing.movement.MovementState.MovementStatus;
|
||||||
import baritone.pathing.movement.movements.MovementDownward;
|
|
||||||
import baritone.pathing.movement.movements.MovementPillar;
|
|
||||||
import baritone.pathing.movement.movements.MovementTraverse;
|
|
||||||
import baritone.utils.*;
|
import baritone.utils.*;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.block.BlockLadder;
|
|
||||||
import net.minecraft.block.BlockVine;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -40,6 +35,8 @@ import static baritone.utils.InputOverrideHandler.Input;
|
|||||||
|
|
||||||
public abstract class Movement implements Helper, MovementHelper {
|
public abstract class Movement implements Helper, MovementHelper {
|
||||||
|
|
||||||
|
protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST};
|
||||||
|
|
||||||
private MovementState currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
private MovementState currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
||||||
|
|
||||||
protected final BlockPos src;
|
protected final BlockPos src;
|
||||||
@ -52,44 +49,34 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
protected final BlockPos[] positionsToBreak;
|
protected final BlockPos[] positionsToBreak;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The positions where we need to place a block before this movement can ensue
|
* The position where we need to place a block before this movement can ensue
|
||||||
*/
|
*/
|
||||||
protected final BlockPos[] positionsToPlace;
|
protected final BlockPos positionToPlace;
|
||||||
|
|
||||||
private boolean didBreakLastTick;
|
private boolean didBreakLastTick;
|
||||||
|
|
||||||
private Double cost;
|
private Double cost;
|
||||||
|
|
||||||
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak, BlockPos[] toPlace) {
|
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak, BlockPos toPlace) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.positionsToBreak = toBreak;
|
this.positionsToBreak = toBreak;
|
||||||
this.positionsToPlace = toPlace;
|
this.positionToPlace = toPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak, BlockPos[] toPlace, Vec3d rotationTarget) {
|
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak) {
|
||||||
this(src, dest, toBreak, toPlace);
|
this(src, dest, toBreak, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCost(CalculationContext context) {
|
public double getCost(CalculationContext context) {
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
if (context == null)
|
if (context == null)
|
||||||
context = new CalculationContext();
|
context = new CalculationContext();
|
||||||
cost = calculateCost0(context);
|
cost = calculateCost(context);
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateCost0(CalculationContext context) {
|
|
||||||
if (!(this instanceof MovementPillar) && !(this instanceof MovementTraverse) && !(this instanceof MovementDownward)) {
|
|
||||||
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
|
||||||
if (fromDown instanceof BlockLadder || fromDown instanceof BlockVine) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return calculateCost(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract double calculateCost(CalculationContext context);
|
protected abstract double calculateCost(CalculationContext context);
|
||||||
|
|
||||||
public double recalculateCost() {
|
public double recalculateCost() {
|
||||||
@ -97,6 +84,10 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return getCost(null);
|
return getCost(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double calculateCostWithoutCaching() {
|
||||||
|
return calculateCost(new CalculationContext());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the execution of the latest Movement
|
* Handles the execution of the latest Movement
|
||||||
* State, and offers a Status to the calling class.
|
* State, and offers a Status to the calling class.
|
||||||
@ -104,7 +95,6 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
* @return Status
|
* @return Status
|
||||||
*/
|
*/
|
||||||
public MovementStatus update() {
|
public MovementStatus update() {
|
||||||
player().setSprinting(false);
|
|
||||||
MovementState latestState = updateState(currentState);
|
MovementState latestState = updateState(currentState);
|
||||||
if (BlockStateInterface.isLiquid(playerFeet())) {
|
if (BlockStateInterface.isLiquid(playerFeet())) {
|
||||||
latestState.setInput(Input.JUMP, true);
|
latestState.setInput(Input.JUMP, true);
|
||||||
@ -159,7 +149,7 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
somethingInTheWay = true;
|
somethingInTheWay = true;
|
||||||
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
||||||
if (reachable.isPresent()) {
|
if (reachable.isPresent()) {
|
||||||
player().inventory.currentItem = new ToolSet().getBestSlot(BlockStateInterface.get(blockPos));
|
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
|
||||||
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
|
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -215,39 +205,53 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double getTotalHardnessOfBlocksToBreak(CalculationContext ctx) {
|
public double getTotalHardnessOfBlocksToBreak(CalculationContext ctx) {
|
||||||
/*
|
if (positionsToBreak.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (positionsToBreak.length == 1) {
|
||||||
|
return MovementHelper.getMiningDurationTicks(ctx, positionsToBreak[0], true);
|
||||||
|
}
|
||||||
|
int firstColumnX = positionsToBreak[0].getX();
|
||||||
|
int firstColumnZ = positionsToBreak[0].getZ();
|
||||||
|
int firstColumnMaxY = positionsToBreak[0].getY();
|
||||||
|
int firstColumnMaximalIndex = 0;
|
||||||
|
boolean hasSecondColumn = false;
|
||||||
|
int secondColumnX = -1;
|
||||||
|
int secondColumnZ = -1;
|
||||||
|
int secondColumnMaxY = -1;
|
||||||
|
int secondColumnMaximalIndex = -1;
|
||||||
|
for (int i = 0; i < positionsToBreak.length; i++) {
|
||||||
|
BlockPos pos = positionsToBreak[i];
|
||||||
|
if (pos.getX() == firstColumnX && pos.getZ() == firstColumnZ) {
|
||||||
|
if (pos.getY() > firstColumnMaxY) {
|
||||||
|
firstColumnMaxY = pos.getY();
|
||||||
|
firstColumnMaximalIndex = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!hasSecondColumn || (pos.getX() == secondColumnX && pos.getZ() == secondColumnZ)) {
|
||||||
|
if (hasSecondColumn) {
|
||||||
|
if (pos.getY() > secondColumnMaxY) {
|
||||||
|
secondColumnMaxY = pos.getY();
|
||||||
|
secondColumnMaximalIndex = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasSecondColumn = true;
|
||||||
|
secondColumnX = pos.getX();
|
||||||
|
secondColumnZ = pos.getZ();
|
||||||
|
secondColumnMaxY = pos.getY();
|
||||||
|
secondColumnMaximalIndex = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("I literally have no idea " + Arrays.asList(positionsToBreak));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
HashSet<BlockPos> toBreak = new HashSet();
|
for (int i = 0; i < positionsToBreak.length; i++) {
|
||||||
for (BlockPos positionsToBreak1 : positionsToBreak) {
|
sum += MovementHelper.getMiningDurationTicks(ctx, positionsToBreak[i], firstColumnMaximalIndex == i || secondColumnMaximalIndex == i);
|
||||||
toBreak.add(positionsToBreak1);
|
|
||||||
if (this instanceof ActionFall) {//if we are digging straight down, assume we have already broken the sand above us
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BlockPos tmp = positionsToBreak1.up();
|
|
||||||
while (canFall(tmp)) {
|
|
||||||
toBreak.add(tmp);
|
|
||||||
tmp = tmp.up();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (BlockPos pos : toBreak) {
|
|
||||||
sum += getHardness(ts, Baritone.get(pos), pos);
|
|
||||||
if (sum >= COST_INF) {
|
if (sum >= COST_INF) {
|
||||||
return COST_INF;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Baritone.allowBreakOrPlace || !Baritone.hasThrowaway) {
|
|
||||||
for (int i = 0; i < blocksToPlace.length; i++) {
|
|
||||||
if (!canWalkOn(positionsToPlace[i])) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
//^ the above implementation properly deals with falling blocks, TODO integrate
|
|
||||||
double sum = 0;
|
|
||||||
for (BlockPos pos : positionsToBreak) {
|
|
||||||
sum += MovementHelper.getMiningDurationTicks(ctx, pos);
|
|
||||||
if (sum >= COST_INF) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
@ -274,6 +278,10 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockPos getDirection() {
|
||||||
|
return getDest().subtract(getSrc());
|
||||||
|
}
|
||||||
|
|
||||||
public List<BlockPos> toBreakCached = null;
|
public List<BlockPos> toBreakCached = null;
|
||||||
public List<BlockPos> toPlaceCached = null;
|
public List<BlockPos> toPlaceCached = null;
|
||||||
public List<BlockPos> toWalkIntoCached = null;
|
public List<BlockPos> toWalkIntoCached = null;
|
||||||
@ -297,10 +305,8 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return toPlaceCached;
|
return toPlaceCached;
|
||||||
}
|
}
|
||||||
List<BlockPos> result = new ArrayList<>();
|
List<BlockPos> result = new ArrayList<>();
|
||||||
for (BlockPos positionToBreak : positionsToPlace) {
|
if (positionToPlace != null && !MovementHelper.canWalkOn(positionToPlace)) {
|
||||||
if (!MovementHelper.canWalkOn(positionToBreak)) {
|
result.add(positionToPlace);
|
||||||
result.add(positionToBreak);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
toPlaceCached = result;
|
toPlaceCached = result;
|
||||||
return result;
|
return result;
|
||||||
|
@ -48,16 +48,14 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|
|
||||||
static boolean avoidBreaking(BlockPos pos, IBlockState state) {
|
static boolean avoidBreaking(BlockPos pos, IBlockState state) {
|
||||||
Block b = state.getBlock();
|
Block b = state.getBlock();
|
||||||
BlockPos below = new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ());
|
Block below = BlockStateInterface.get(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
||||||
return Blocks.ICE.equals(b) // ice becomes water, and water can mess up the path
|
return Blocks.ICE.equals(b) // ice becomes water, and water can mess up the path
|
||||||
|| b instanceof BlockSilverfish // obvious reasons
|
|| b instanceof BlockSilverfish // obvious reasons
|
||||||
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY() + 1, pos.getZ()))//don't break anything touching liquid on any side
|
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY() + 1, pos.getZ()))//don't break anything touching liquid on any side
|
||||||
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX() + 1, pos.getY(), pos.getZ()))
|
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX() + 1, pos.getY(), pos.getZ()))
|
||||||
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX() - 1, pos.getY(), pos.getZ()))
|
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX() - 1, pos.getY(), pos.getZ()))
|
||||||
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() + 1))
|
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() + 1))
|
||||||
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() - 1))
|
|| BlockStateInterface.isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() - 1));
|
||||||
|| (!(b instanceof BlockLilyPad && BlockStateInterface.isWater(below)) && BlockStateInterface.isLiquid(below));//if it's a lilypad above water, it's ok to break, otherwise don't break if its liquid
|
|
||||||
// TODO revisit this. why is it not okay to break non-lilypads that are right above water?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,10 +91,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IBlockState up = BlockStateInterface.get(pos.up());
|
if (BlockStateInterface.isFlowing(state)) {
|
||||||
if (BlockStateInterface.isFlowing(state) || up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
|
||||||
return false; // Don't walk through flowing liquids
|
return false; // Don't walk through flowing liquids
|
||||||
}
|
}
|
||||||
|
if (block instanceof BlockLiquid) {
|
||||||
|
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
IBlockState up = BlockStateInterface.get(pos.up());
|
||||||
|
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return block.isPassable(mc.world, pos);
|
return block.isPassable(mc.world, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +164,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (facing == playerFacing) == open;
|
return facing == playerFacing == open;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean avoidWalkingInto(Block block) {
|
static boolean avoidWalkingInto(Block block) {
|
||||||
@ -178,6 +184,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
*/
|
*/
|
||||||
static boolean canWalkOn(BlockPos pos, IBlockState state) {
|
static boolean canWalkOn(BlockPos pos, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
|
if (block == Blocks.AIR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (block instanceof BlockLadder || (Baritone.settings().allowVines.get() && block instanceof BlockVine)) { // TODO reconsider this
|
if (block instanceof BlockLadder || (Baritone.settings().allowVines.get() && block instanceof BlockVine)) { // TODO reconsider this
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -187,12 +196,33 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (Blocks.FARMLAND.equals(block) || Blocks.GRASS_PATH.equals(block)) {
|
if (Blocks.FARMLAND.equals(block) || Blocks.GRASS_PATH.equals(block)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockAir) {
|
if (Blocks.ENDER_CHEST.equals(block) || Blocks.CHEST.equals(block)) {
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
if (block instanceof BlockSlab) {
|
||||||
|
if (!Baritone.settings().allowWalkOnBottomSlab.get()) {
|
||||||
|
if (((BlockSlab) block).isDouble()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return state.getValue(BlockSlab.HALF) != BlockSlab.EnumBlockHalf.BOTTOM;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (block instanceof BlockStairs) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.isWater(block)) {
|
if (BlockStateInterface.isWater(block)) {
|
||||||
Block up = BlockStateInterface.get(pos.up()).getBlock();
|
Block up = BlockStateInterface.get(pos.up()).getBlock();
|
||||||
return BlockStateInterface.isWater(up) || up instanceof BlockLilyPad; // You can only walk on water if there is water above it
|
if (up instanceof BlockLilyPad) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (BlockStateInterface.isFlowing(state)) {
|
||||||
|
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
||||||
|
return BlockStateInterface.isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
|
||||||
|
}
|
||||||
|
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
||||||
|
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
||||||
|
return BlockStateInterface.isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
|
||||||
}
|
}
|
||||||
if (Blocks.MAGMA.equals(block)) {
|
if (Blocks.MAGMA.equals(block)) {
|
||||||
return false;
|
return false;
|
||||||
@ -208,12 +238,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return BlockStateInterface.get(pos).getBlock() instanceof BlockFalling;
|
return BlockStateInterface.get(pos).getBlock() instanceof BlockFalling;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, BlockPos position) {
|
static boolean canPlaceAgainst(BlockPos pos) {
|
||||||
IBlockState state = BlockStateInterface.get(position);
|
IBlockState state = BlockStateInterface.get(pos);
|
||||||
return getMiningDurationTicks(context, position, state);
|
// TODO isBlockNormalCube isn't the best check for whether or not we can place a block against it. e.g. glass isn't normalCube but we can place against it
|
||||||
|
return state.isBlockNormalCube();
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, BlockPos position, IBlockState state) {
|
static double getMiningDurationTicks(CalculationContext context, BlockPos position, boolean includeFalling) {
|
||||||
|
IBlockState state = BlockStateInterface.get(position);
|
||||||
|
return getMiningDurationTicks(context, position, state, includeFalling);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getMiningDurationTicks(CalculationContext context, BlockPos position, IBlockState state, boolean includeFalling) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (!block.equals(Blocks.AIR) && !canWalkThrough(position, state)) { // TODO is the air check really necessary? Isn't air canWalkThrough?
|
if (!block.equals(Blocks.AIR) && !canWalkThrough(position, state)) { // TODO is the air check really necessary? Isn't air canWalkThrough?
|
||||||
if (!context.allowBreak()) {
|
if (!context.allowBreak()) {
|
||||||
@ -223,9 +259,31 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
||||||
return m / context.getToolSet().getStrVsBlock(state, position);
|
double strVsBlock = context.getToolSet().getStrVsBlock(state);
|
||||||
|
if (strVsBlock < 0)
|
||||||
|
return COST_INF;
|
||||||
|
|
||||||
|
double result = m / strVsBlock;
|
||||||
|
if (includeFalling) {
|
||||||
|
BlockPos up = position.up();
|
||||||
|
IBlockState above = BlockStateInterface.get(up);
|
||||||
|
if (above.getBlock() instanceof BlockFalling) {
|
||||||
|
result += getMiningDurationTicks(context, up, above, true);
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return 0; // we won't actually mine it, so don't check fallings above
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isBottomSlab(IBlockState state) {
|
||||||
|
return state.getBlock() instanceof BlockSlab
|
||||||
|
&& !((BlockSlab) state.getBlock()).isDouble()
|
||||||
|
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isBottomSlab(BlockPos pos) {
|
||||||
|
return isBottomSlab(BlockStateInterface.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,22 +362,22 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
static Movement generateMovementFallOrDescend(BlockPos pos, BlockPos dest, CalculationContext calcContext) {
|
static Movement generateMovementFallOrDescend(BlockPos pos, BlockPos dest, CalculationContext calcContext) {
|
||||||
// A
|
// A
|
||||||
//SA
|
//SA
|
||||||
// B
|
// A
|
||||||
// B
|
// B
|
||||||
// C
|
// C
|
||||||
// D
|
// D
|
||||||
//if S is where you start, both of B need to be air for a movementfall
|
//if S is where you start, B needs to be air for a movementfall
|
||||||
//A is plausibly breakable by either descend or fall
|
//A is plausibly breakable by either descend or fall
|
||||||
//C, D, etc determine the length of the fall
|
//C, D, etc determine the length of the fall
|
||||||
for (int i = 1; i < 3; i++) {
|
|
||||||
if (!canWalkThrough(dest.down(i))) {
|
if (!canWalkThrough(dest.down(2))) {
|
||||||
//if any of these two (B in the diagram) aren't air
|
//if B in the diagram aren't air
|
||||||
//have to do a descend, because fall is impossible
|
//have to do a descend, because fall is impossible
|
||||||
|
|
||||||
//this doesn't guarantee descend is possible, it just guarantees fall is impossible
|
//this doesn't guarantee descend is possible, it just guarantees fall is impossible
|
||||||
return new MovementDescend(pos, dest.down()); // standard move out by 1 and descend by 1
|
return new MovementDescend(pos, dest.down()); // standard move out by 1 and descend by 1
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// we're clear for a fall 2
|
// we're clear for a fall 2
|
||||||
// let's see how far we can fall
|
// let's see how far we can fall
|
||||||
for (int fallHeight = 3; true; fallHeight++) {
|
for (int fallHeight = 3; true; fallHeight++) {
|
||||||
|
@ -39,29 +39,10 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class MovementAscend extends Movement {
|
public class MovementAscend extends Movement {
|
||||||
|
|
||||||
private BlockPos[] against = new BlockPos[3];
|
|
||||||
private int ticksWithoutPlacement = 0;
|
private int ticksWithoutPlacement = 0;
|
||||||
|
|
||||||
public MovementAscend(BlockPos src, BlockPos dest) {
|
public MovementAscend(BlockPos src, BlockPos dest) {
|
||||||
super(src, dest, new BlockPos[]{dest, src.up(2), dest.up()}, new BlockPos[]{dest.down()});
|
super(src, dest, new BlockPos[]{dest, src.up(2), dest.up()}, dest.down());
|
||||||
|
|
||||||
BlockPos placementLocation = positionsToPlace[0]; // dest.down()
|
|
||||||
int i = 0;
|
|
||||||
if (!placementLocation.north().equals(src))
|
|
||||||
against[i++] = placementLocation.north();
|
|
||||||
|
|
||||||
if (!placementLocation.south().equals(src))
|
|
||||||
against[i++] = placementLocation.south();
|
|
||||||
|
|
||||||
if (!placementLocation.east().equals(src))
|
|
||||||
against[i++] = placementLocation.east();
|
|
||||||
|
|
||||||
if (!placementLocation.west().equals(src))
|
|
||||||
against[i] = placementLocation.west();
|
|
||||||
|
|
||||||
// TODO: add ability to place against .down() as well as the cardinal directions
|
|
||||||
// useful for when you are starting a staircase without anything to place against
|
|
||||||
// Counterpoint to the above TODO ^ you should move then pillar instead of ascend
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,16 +53,34 @@ public class MovementAscend extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
IBlockState toPlace = BlockStateInterface.get(positionsToPlace[0]);
|
IBlockState srcDown = BlockStateInterface.get(src.down());
|
||||||
if (!MovementHelper.canWalkOn(positionsToPlace[0], toPlace)) {
|
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
// we can jump from soul sand, but not from a bottom slab
|
||||||
|
boolean jumpingFromBottomSlab = MovementHelper.isBottomSlab(srcDown);
|
||||||
|
IBlockState toPlace = BlockStateInterface.get(positionToPlace);
|
||||||
|
boolean jumpingToBottomSlab = MovementHelper.isBottomSlab(toPlace);
|
||||||
|
|
||||||
|
if (jumpingFromBottomSlab && !jumpingToBottomSlab) {
|
||||||
|
return COST_INF;// the only thing we can ascend onto from a bottom slab is another bottom slab
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(positionToPlace, toPlace)) {
|
||||||
if (!context.hasThrowaway()) {
|
if (!context.hasThrowaway()) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!BlockStateInterface.isAir(toPlace) && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionsToPlace[0], toPlace)) {
|
if (!BlockStateInterface.isAir(toPlace) && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
for (BlockPos against1 : against) {
|
// TODO: add ability to place against .down() as well as the cardinal directions
|
||||||
if (BlockStateInterface.get(against1).isBlockNormalCube()) {
|
// useful for when you are starting a staircase without anything to place against
|
||||||
|
// Counterpoint to the above TODO ^ you should move then pillar instead of ascend
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
BlockPos against1 = positionToPlace.offset(HORIZONTALS[i]);
|
||||||
|
if (against1.equals(src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (MovementHelper.canPlaceAgainst(against1)) {
|
||||||
return JUMP_ONE_BLOCK_COST + WALK_ONE_BLOCK_COST + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
return JUMP_ONE_BLOCK_COST + WALK_ONE_BLOCK_COST + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,9 +107,11 @@ public class MovementAscend extends Movement {
|
|||||||
// it's possible srcUp is AIR from the start, and srcUp2 is falling
|
// it's possible srcUp is AIR from the start, and srcUp2 is falling
|
||||||
// and in that scenario, when we arrive and break srcUp2, that lets srcUp3 fall on us and suffocate us
|
// and in that scenario, when we arrive and break srcUp2, that lets srcUp3 fall on us and suffocate us
|
||||||
}
|
}
|
||||||
// TODO maybe change behavior if src.down() is soul sand?
|
|
||||||
double walk = WALK_ONE_BLOCK_COST;
|
double walk = WALK_ONE_BLOCK_COST;
|
||||||
if (toPlace.getBlock().equals(Blocks.SOUL_SAND)) {
|
if (jumpingToBottomSlab && !jumpingFromBottomSlab) {
|
||||||
|
return walk + getTotalHardnessOfBlocksToBreak(context); // we don't hit space we just walk into the slab
|
||||||
|
}
|
||||||
|
if (!jumpingToBottomSlab && toPlace.getBlock().equals(Blocks.SOUL_SAND)) {
|
||||||
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
||||||
}
|
}
|
||||||
// we hit space immediately on entering this action
|
// we hit space immediately on entering this action
|
||||||
@ -129,9 +130,14 @@ public class MovementAscend extends Movement {
|
|||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MovementHelper.canWalkOn(positionsToPlace[0])) {
|
IBlockState jumpingOnto = BlockStateInterface.get(positionToPlace);
|
||||||
for (BlockPos anAgainst : against) {
|
if (!MovementHelper.canWalkOn(positionToPlace, jumpingOnto)) {
|
||||||
if (BlockStateInterface.get(anAgainst).isBlockNormalCube()) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
BlockPos anAgainst = positionToPlace.offset(HORIZONTALS[i]);
|
||||||
|
if (anAgainst.equals(src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (MovementHelper.canPlaceAgainst(anAgainst)) {
|
||||||
if (!MovementHelper.throwaway(true)) {//get ready to place a throwaway block
|
if (!MovementHelper.throwaway(true)) {//get ready to place a throwaway block
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
@ -142,7 +148,7 @@ public class MovementAscend extends Movement {
|
|||||||
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
||||||
|
|
||||||
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
|
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
|
||||||
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionsToPlace[0])) {
|
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) {
|
||||||
ticksWithoutPlacement++;
|
ticksWithoutPlacement++;
|
||||||
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
if (player().isSneaking()) {
|
if (player().isSneaking()) {
|
||||||
@ -152,6 +158,8 @@ public class MovementAscend extends Movement {
|
|||||||
// After 20 ticks without placement, we might be standing in the way, move back
|
// After 20 ticks without placement, we might be standing in the way, move back
|
||||||
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
|
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true); // break whatever replaceable block is in the way
|
||||||
}
|
}
|
||||||
System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
|
System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
|
||||||
});
|
});
|
||||||
@ -161,6 +169,11 @@ public class MovementAscend extends Movement {
|
|||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
MovementHelper.moveTowards(state, dest);
|
MovementHelper.moveTowards(state, dest);
|
||||||
|
if (MovementHelper.isBottomSlab(jumpingOnto)) {
|
||||||
|
if (!MovementHelper.isBottomSlab(src.down())) {
|
||||||
|
return state; // don't jump while walking from a non double slab into a bottom slab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (headBonkClear()) {
|
if (headBonkClear()) {
|
||||||
return state.setInput(InputOverrideHandler.Input.JUMP, true);
|
return state.setInput(InputOverrideHandler.Input.JUMP, true);
|
||||||
|
@ -25,15 +25,13 @@ import baritone.pathing.movement.MovementState.MovementStatus;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockLadder;
|
|
||||||
import net.minecraft.block.BlockVine;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class MovementDescend extends Movement {
|
public class MovementDescend extends Movement {
|
||||||
|
|
||||||
public MovementDescend(BlockPos start, BlockPos end) {
|
public MovementDescend(BlockPos start, BlockPos end) {
|
||||||
super(start, end, new BlockPos[]{end.up(2), end.up(), end}, new BlockPos[]{end.down()});
|
super(start, end, new BlockPos[]{end.up(2), end.up(), end}, end.down());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,18 +42,22 @@ public class MovementDescend extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
if (!MovementHelper.canWalkOn(positionsToPlace[0])) {
|
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
||||||
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(positionToPlace)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
Block tmp1 = BlockStateInterface.get(dest).getBlock();
|
Block tmp1 = BlockStateInterface.get(dest).getBlock();
|
||||||
if (tmp1 instanceof BlockLadder || tmp1 instanceof BlockVine) {
|
if (tmp1 == Blocks.LADDER || tmp1 == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
|
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
|
||||||
double walk = WALK_OFF_BLOCK_COST;
|
double walk = WALK_OFF_BLOCK_COST;
|
||||||
if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
// use this ratio to apply the soul sand speed penalty to our 0.8 block distance
|
// use this ratio to apply the soul sand speed penalty to our 0.8 block distance
|
||||||
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
||||||
}
|
}
|
||||||
return walk + Math.max(FALL_N_BLOCKS_COST[1], CENTER_AFTER_FALL_COST) + getTotalHardnessOfBlocksToBreak(context);
|
return walk + Math.max(FALL_N_BLOCKS_COST[1], CENTER_AFTER_FALL_COST) + getTotalHardnessOfBlocksToBreak(context);
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import baritone.utils.InputOverrideHandler;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockMagma;
|
import net.minecraft.block.BlockMagma;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
@ -49,66 +50,52 @@ public class MovementDiagonal extends Movement {
|
|||||||
super(start, end, new BlockPos[]{dir1, dir1.up(), dir2, dir2.up(), end, end.up()}, new BlockPos[]{end.down()});
|
super(start, end, new BlockPos[]{dir1, dir1.up(), dir2, dir2.up(), end, end.up()}, new BlockPos[]{end.down()});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MovementState updateState(MovementState state) {
|
|
||||||
super.updateState(state);
|
|
||||||
if (state.getStatus() != MovementState.MovementStatus.RUNNING)
|
|
||||||
return state;
|
|
||||||
|
|
||||||
if (playerFeet().equals(dest)) {
|
|
||||||
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
if (!BlockStateInterface.isLiquid(playerFeet()) && Baritone.settings().allowSprint.get()) {
|
|
||||||
player().setSprinting(true);
|
|
||||||
}
|
|
||||||
MovementHelper.moveTowards(state, dest);
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
|
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
||||||
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
if (!MovementHelper.canWalkThrough(positionsToBreak[4]) || !MovementHelper.canWalkThrough(positionsToBreak[5])) {
|
if (!MovementHelper.canWalkThrough(positionsToBreak[4]) || !MovementHelper.canWalkThrough(positionsToBreak[5])) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState destWalkOn = BlockStateInterface.get(positionsToPlace[0]);
|
BlockPos destDown = dest.down();
|
||||||
if (!MovementHelper.canWalkOn(positionsToPlace[0], destWalkOn)) {
|
IBlockState destWalkOn = BlockStateInterface.get(destDown);
|
||||||
|
if (!MovementHelper.canWalkOn(destDown, destWalkOn)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double multiplier = WALK_ONE_BLOCK_COST;
|
double multiplier = WALK_ONE_BLOCK_COST;
|
||||||
|
|
||||||
// For either possible soul sand, that affects half of our walking
|
// For either possible soul sand, that affects half of our walking
|
||||||
if (destWalkOn.getBlock().equals(Blocks.SOUL_SAND)) {
|
if (destWalkOn.getBlock().equals(Blocks.SOUL_SAND)) {
|
||||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
|
Block cuttingOver1 = BlockStateInterface.get(positionsToBreak[2].down()).getBlock();
|
||||||
if (BlockStateInterface.get(positionsToBreak[2].down()).getBlock() instanceof BlockMagma) {
|
if (cuttingOver1 instanceof BlockMagma || BlockStateInterface.isLava(cuttingOver1)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(positionsToBreak[4].down()).getBlock() instanceof BlockMagma) {
|
Block cuttingOver2 = BlockStateInterface.get(positionsToBreak[4].down()).getBlock();
|
||||||
|
if (cuttingOver2 instanceof BlockMagma || BlockStateInterface.isLava(cuttingOver2)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double optionA = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0]) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[1]);
|
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
||||||
double optionB = MovementHelper.getMiningDurationTicks(context, positionsToBreak[2]) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[3]);
|
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
||||||
|
IBlockState pb2 = BlockStateInterface.get(positionsToBreak[2]);
|
||||||
|
IBlockState pb3 = BlockStateInterface.get(positionsToBreak[3]);
|
||||||
|
double optionA = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0], pb0, false) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[1], pb1, true);
|
||||||
|
double optionB = MovementHelper.getMiningDurationTicks(context, positionsToBreak[2], pb2, false) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[3], pb3, true);
|
||||||
if (optionA != 0 && optionB != 0) {
|
if (optionA != 0 && optionB != 0) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (optionA == 0) {
|
if (optionA == 0) {
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(positionsToBreak[2]))) {
|
if (MovementHelper.avoidWalkingInto(pb2.getBlock()) || MovementHelper.avoidWalkingInto(pb3.getBlock())) {
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(positionsToBreak[3]))) {
|
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (optionB == 0) {
|
if (optionB == 0) {
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(positionsToBreak[0]))) {
|
if (MovementHelper.avoidWalkingInto(pb0.getBlock()) || MovementHelper.avoidWalkingInto(pb1.getBlock())) {
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(positionsToBreak[1]))) {
|
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,6 +116,23 @@ public class MovementDiagonal extends Movement {
|
|||||||
return multiplier * SQRT_2;
|
return multiplier * SQRT_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MovementState updateState(MovementState state) {
|
||||||
|
super.updateState(state);
|
||||||
|
if (state.getStatus() != MovementState.MovementStatus.RUNNING)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
if (playerFeet().equals(dest)) {
|
||||||
|
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
if (!BlockStateInterface.isLiquid(playerFeet())) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||||
|
}
|
||||||
|
MovementHelper.moveTowards(state, dest);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean prepared(MovementState state) {
|
protected boolean prepared(MovementState state) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -23,9 +23,8 @@ import baritone.pathing.movement.MovementHelper;
|
|||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockLadder;
|
|
||||||
import net.minecraft.block.BlockVine;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class MovementDownward extends Movement {
|
public class MovementDownward extends Movement {
|
||||||
@ -33,7 +32,7 @@ public class MovementDownward extends Movement {
|
|||||||
private int numTicks = 0;
|
private int numTicks = 0;
|
||||||
|
|
||||||
public MovementDownward(BlockPos start, BlockPos end) {
|
public MovementDownward(BlockPos start, BlockPos end) {
|
||||||
super(start, end, new BlockPos[]{end}, new BlockPos[0]);
|
super(start, end, new BlockPos[]{end});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,11 +48,12 @@ public class MovementDownward extends Movement {
|
|||||||
}
|
}
|
||||||
IBlockState d = BlockStateInterface.get(dest);
|
IBlockState d = BlockStateInterface.get(dest);
|
||||||
Block td = d.getBlock();
|
Block td = d.getBlock();
|
||||||
boolean ladder = td instanceof BlockLadder || td instanceof BlockVine;
|
boolean ladder = td == Blocks.LADDER || td == Blocks.VINE;
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
return LADDER_DOWN_ONE_COST;
|
return LADDER_DOWN_ONE_COST;
|
||||||
} else {
|
} else {
|
||||||
return FALL_N_BLOCKS_COST[1] + MovementHelper.getMiningDurationTicks(context, dest, d);
|
// we're standing on it, while it might be block falling, it'll be air by the time we get here in the movement
|
||||||
|
return FALL_N_BLOCKS_COST[1] + MovementHelper.getMiningDurationTicks(context, dest, d, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,11 @@ import baritone.pathing.movement.MovementState;
|
|||||||
import baritone.pathing.movement.MovementState.MovementStatus;
|
import baritone.pathing.movement.MovementState.MovementStatus;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
import baritone.utils.*;
|
import baritone.utils.*;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockFalling;
|
import net.minecraft.block.BlockFalling;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -38,14 +42,22 @@ public class MovementFall extends Movement {
|
|||||||
private static final ItemStack STACK_BUCKET_EMPTY = new ItemStack(Items.BUCKET);
|
private static final ItemStack STACK_BUCKET_EMPTY = new ItemStack(Items.BUCKET);
|
||||||
|
|
||||||
public MovementFall(BlockPos src, BlockPos dest) {
|
public MovementFall(BlockPos src, BlockPos dest) {
|
||||||
super(src, dest, MovementFall.buildPositionsToBreak(src, dest), new BlockPos[]{dest.down()});
|
super(src, dest, MovementFall.buildPositionsToBreak(src, dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
if (!MovementHelper.canWalkOn(positionsToPlace[0])) {
|
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
||||||
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
IBlockState fallOnto = BlockStateInterface.get(dest.down());
|
||||||
|
if (!MovementHelper.canWalkOn(dest.down(), fallOnto)) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
if (MovementHelper.isBottomSlab(fallOnto)) {
|
||||||
|
return COST_INF; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||||
|
}
|
||||||
double placeBucketCost = 0.0;
|
double placeBucketCost = 0.0;
|
||||||
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > context.maxFallHeightNoWater()) {
|
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > context.maxFallHeightNoWater()) {
|
||||||
if (!context.hasWaterBucket()) {
|
if (!context.hasWaterBucket()) {
|
||||||
@ -56,25 +68,29 @@ public class MovementFall extends Movement {
|
|||||||
}
|
}
|
||||||
placeBucketCost = context.placeBlockCost();
|
placeBucketCost = context.placeBlockCost();
|
||||||
}
|
}
|
||||||
double frontTwo = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0]) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[1]);
|
double frontThree = 0;
|
||||||
if (frontTwo >= COST_INF) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
frontThree += MovementHelper.getMiningDurationTicks(context, positionsToBreak[i], false);
|
||||||
|
// don't include falling because we will check falling right after this, and if it's there it's COST_INF
|
||||||
|
if (frontThree >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (BlockStateInterface.get(positionsToBreak[0].up()).getBlock() instanceof BlockFalling) {
|
if (BlockStateInterface.get(positionsToBreak[0].up()).getBlock() instanceof BlockFalling) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
for (int i = 2; i < positionsToBreak.length; i++) {
|
for (int i = 3; i < positionsToBreak.length; i++) {
|
||||||
// TODO is this the right check here?
|
// TODO is this the right check here?
|
||||||
// MiningDurationTicks is all right, but shouldn't it be canWalkThrough instead?
|
// MiningDurationTicks is all right, but shouldn't it be canWalkThrough instead?
|
||||||
// Lilypads (i think?) are 0 ticks to mine, but they definitely cause fall damage
|
// Lilypads (i think?) are 0 ticks to mine, but they definitely cause fall damage
|
||||||
// Same thing for falling through water... we can't actually do that
|
// Same thing for falling through water... we can't actually do that
|
||||||
// And falling through signs is possible, but they do have a mining duration, right?
|
// And falling through signs is possible, but they do have a mining duration, right?
|
||||||
if (MovementHelper.getMiningDurationTicks(context, positionsToBreak[i]) > 0) {
|
if (MovementHelper.getMiningDurationTicks(context, positionsToBreak[i], false) > 0) {
|
||||||
//can't break while falling
|
//can't break while falling
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[positionsToBreak.length - 1] + placeBucketCost + frontTwo;
|
return WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[positionsToBreak.length - 1] + placeBucketCost + frontThree;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -86,7 +102,7 @@ public class MovementFall extends Movement {
|
|||||||
BlockPos playerFeet = playerFeet();
|
BlockPos playerFeet = playerFeet();
|
||||||
Rotation targetRotation = null;
|
Rotation targetRotation = null;
|
||||||
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
||||||
if (!player().inventory.hasItemStack(STACK_BUCKET_WATER) || world().provider.isNether()) {
|
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
|
||||||
state.setStatus(MovementStatus.UNREACHABLE);
|
state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -109,7 +125,7 @@ public class MovementFall extends Movement {
|
|||||||
}
|
}
|
||||||
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 // lilypads
|
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 // lilypads
|
||||||
|| BlockStateInterface.isWater(dest))) {
|
|| BlockStateInterface.isWater(dest))) {
|
||||||
if (BlockStateInterface.isWater(dest) && player().inventory.hasItemStack(STACK_BUCKET_EMPTY)) {
|
if (BlockStateInterface.isWater(dest) && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
||||||
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
||||||
if (player().motionY >= 0) {
|
if (player().motionY >= 0) {
|
||||||
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
|
@ -28,14 +28,13 @@ import baritone.utils.Utils;
|
|||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class MovementPillar extends Movement {
|
public class MovementPillar extends Movement {
|
||||||
private int numTicks = 0;
|
private int numTicks = 0;
|
||||||
|
|
||||||
public MovementPillar(BlockPos start, BlockPos end) {
|
public MovementPillar(BlockPos start, BlockPos end) {
|
||||||
super(start, end, new BlockPos[]{start.up(2)}, new BlockPos[]{start});
|
super(start, end, new BlockPos[]{start.up(2)}, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,11 +47,16 @@ public class MovementPillar extends Movement {
|
|||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
Block fromDown = BlockStateInterface.get(src).getBlock();
|
Block fromDown = BlockStateInterface.get(src).getBlock();
|
||||||
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
||||||
Block fromDownDown = BlockStateInterface.get(src.down()).getBlock();
|
IBlockState fromDownDown = BlockStateInterface.get(src.down());
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
if (fromDownDown instanceof BlockLadder || fromDownDown instanceof BlockVine) {
|
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
if (fromDownDown.getBlock() instanceof BlockSlab) {
|
||||||
|
if (!((BlockSlab) fromDownDown.getBlock()).isDouble() && fromDownDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
|
||||||
|
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!context.hasThrowaway() && !ladder) {
|
if (!context.hasThrowaway() && !ladder) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@ -63,6 +67,9 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
double hardness = getTotalHardnessOfBlocksToBreak(context);
|
double hardness = getTotalHardnessOfBlocksToBreak(context);
|
||||||
|
if (hardness >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
if (hardness != 0) {
|
if (hardness != 0) {
|
||||||
Block tmp = BlockStateInterface.get(src.up(2)).getBlock();
|
Block tmp = BlockStateInterface.get(src.up(2)).getBlock();
|
||||||
if (tmp instanceof BlockLadder || tmp instanceof BlockVine) {
|
if (tmp instanceof BlockLadder || tmp instanceof BlockVine) {
|
||||||
@ -70,15 +77,22 @@ public class MovementPillar extends Movement {
|
|||||||
} else {
|
} else {
|
||||||
BlockPos chkPos = src.up(3);
|
BlockPos chkPos = src.up(3);
|
||||||
IBlockState check = BlockStateInterface.get(chkPos);
|
IBlockState check = BlockStateInterface.get(chkPos);
|
||||||
if (!MovementHelper.canWalkOn(chkPos, check) || MovementHelper.canWalkThrough(chkPos, check) || check.getBlock() instanceof BlockFalling) {//if the block above where we want to break is not a full block, don't do it
|
if (check.getBlock() instanceof BlockFalling) {
|
||||||
// TODO why does canWalkThrough mean this action is COST_INF?
|
// see MovementAscend's identical check for breaking a falling block above our head
|
||||||
// BlockFalling makes sense, and !canWalkOn deals with weird cases like if it were lava
|
if (!(tmp instanceof BlockFalling) || !(BlockStateInterface.get(src.up(1)).getBlock() instanceof BlockFalling)) {
|
||||||
// but I don't understand why canWalkThrough makes it impossible
|
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// this is commented because it may have had a purpose, but it's very unclear what it was. it's from the minebot era.
|
||||||
|
//if (!MovementHelper.canWalkOn(chkPos, check) || MovementHelper.canWalkThrough(chkPos, check)) {//if the block above where we want to break is not a full block, don't do it
|
||||||
|
// TODO why does canWalkThrough mean this action is COST_INF?
|
||||||
|
// BlockFalling makes sense, and !canWalkOn deals with weird cases like if it were lava
|
||||||
|
// but I don't understand why canWalkThrough makes it impossible
|
||||||
|
// return COST_INF;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
if (fromDown instanceof BlockLiquid || fromDownDown instanceof BlockLiquid) {//can't pillar on water or in water
|
}
|
||||||
|
if (fromDown instanceof BlockLiquid || fromDownDown.getBlock() instanceof BlockLiquid) {//can't pillar on water or in water
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
@ -115,7 +129,7 @@ public class MovementPillar extends Movement {
|
|||||||
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
||||||
Utils.getBlockPosCenter(positionsToPlace[0]),
|
Utils.getBlockPosCenter(positionToPlace),
|
||||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
|
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +141,12 @@ public class MovementPillar extends Movement {
|
|||||||
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerFeet().equals(against.up()) || playerFeet().equals(dest))
|
if (playerFeet().equals(against.up()) || playerFeet().equals(dest)) {
|
||||||
return state.setStatus(MovementState.MovementStatus.SUCCESS);
|
return state.setStatus(MovementState.MovementStatus.SUCCESS);
|
||||||
|
}
|
||||||
|
if (MovementHelper.isBottomSlab(src.down())) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.JUMP, true);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
if (thePlayer.getPosition0().getX() != from.getX() || thePlayer.getPosition0().getZ() != from.getZ()) {
|
if (thePlayer.getPosition0().getX() != from.getX() || thePlayer.getPosition0().getZ() != from.getZ()) {
|
||||||
Baritone.moveTowardsBlock(from);
|
Baritone.moveTowardsBlock(from);
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.behavior.impl.LookBehaviorUtils;
|
import baritone.behavior.impl.LookBehaviorUtils;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
@ -38,30 +37,13 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class MovementTraverse extends Movement {
|
public class MovementTraverse extends Movement {
|
||||||
|
|
||||||
private BlockPos[] against = new BlockPos[3];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Did we have to place a bridge block or was it always there
|
* Did we have to place a bridge block or was it always there
|
||||||
*/
|
*/
|
||||||
private boolean wasTheBridgeBlockAlwaysThere = true;
|
private boolean wasTheBridgeBlockAlwaysThere = true;
|
||||||
|
|
||||||
public MovementTraverse(BlockPos from, BlockPos to) {
|
public MovementTraverse(BlockPos from, BlockPos to) {
|
||||||
super(from, to, new BlockPos[]{to.up(), to}, new BlockPos[]{to.down()});
|
super(from, to, new BlockPos[]{to.up(), to}, to.down());
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (!to.north().equals(from))
|
|
||||||
against[i++] = to.north().down();
|
|
||||||
|
|
||||||
if (!to.south().equals(from))
|
|
||||||
against[i++] = to.south().down();
|
|
||||||
|
|
||||||
if (!to.east().equals(from))
|
|
||||||
against[i++] = to.east().down();
|
|
||||||
|
|
||||||
if (!to.west().equals(from))
|
|
||||||
against[i] = to.west().down();
|
|
||||||
|
|
||||||
//note: do NOT add ability to place against .down().down()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,20 +56,26 @@ public class MovementTraverse extends Movement {
|
|||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
||||||
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
||||||
IBlockState destOn = BlockStateInterface.get(positionsToPlace[0]);
|
IBlockState destOn = BlockStateInterface.get(positionToPlace);
|
||||||
if (MovementHelper.canWalkOn(positionsToPlace[0], destOn)) {//this is a walk, not a bridge
|
Block srcDown = BlockStateInterface.getBlock(src.down());
|
||||||
|
if (MovementHelper.canWalkOn(positionToPlace, destOn)) {//this is a walk, not a bridge
|
||||||
double WC = WALK_ONE_BLOCK_COST;
|
double WC = WALK_ONE_BLOCK_COST;
|
||||||
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
||||||
WC = WALK_ONE_IN_WATER_COST;
|
WC = WALK_ONE_IN_WATER_COST;
|
||||||
} else {
|
} else {
|
||||||
if (Blocks.SOUL_SAND.equals(destOn.getBlock())) {
|
if (destOn.getBlock() == Blocks.SOUL_SAND) {
|
||||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
if (Blocks.SOUL_SAND.equals(BlockStateInterface.get(src.down()).getBlock())) {
|
if (srcDown == Blocks.SOUL_SAND) {
|
||||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkThrough(positionsToBreak[0], pb0) && MovementHelper.canWalkThrough(positionsToBreak[1], pb1)) {
|
double hardness1 = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0], pb0, true);
|
||||||
|
if (hardness1 >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
double hardness2 = MovementHelper.getMiningDurationTicks(context, positionsToBreak[1], pb1, false);
|
||||||
|
if (hardness1 == 0 && hardness2 == 0) {
|
||||||
if (WC == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
if (WC == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
||||||
// If there's nothing in the way, and this isn't water or soul sand, and we aren't sneak placing
|
// If there's nothing in the way, and this isn't water or soul sand, and we aren't sneak placing
|
||||||
// We can sprint =D
|
// We can sprint =D
|
||||||
@ -95,28 +83,36 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
return WC;
|
return WC;
|
||||||
}
|
}
|
||||||
// double hardness1 = blocksToBreak[0].getBlockHardness(Minecraft.getMinecraft().world, positionsToBreak[0]);
|
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
||||||
// double hardness2 = blocksToBreak[1].getBlockHardness(Minecraft.getMinecraft().world, positionsToBreak[1]);
|
hardness1 *= 5;
|
||||||
// Out.log("Can't walk through " + blocksToBreak[0] + " (hardness" + hardness1 + ") or " + blocksToBreak[1] + " (hardness " + hardness2 + ")");
|
hardness2 *= 5;
|
||||||
return WC + getTotalHardnessOfBlocksToBreak(context);
|
}
|
||||||
|
return WC + hardness1 + hardness2;
|
||||||
} else {//this is a bridge, so we need to place a block
|
} else {//this is a bridge, so we need to place a block
|
||||||
Block srcDown = BlockStateInterface.get(src.down()).getBlock();
|
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
||||||
if (srcDown instanceof BlockLadder || srcDown instanceof BlockVine) {
|
return COST_INF;
|
||||||
|
}
|
||||||
|
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(positionToPlace, destOn)) {
|
||||||
|
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
|
||||||
|
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState pp0 = BlockStateInterface.get(positionsToPlace[0]);
|
|
||||||
if (pp0.getBlock().equals(Blocks.AIR) || (!BlockStateInterface.isWater(pp0.getBlock()) && MovementHelper.isReplacable(positionsToPlace[0], pp0))) {
|
|
||||||
if (!context.hasThrowaway()) {
|
if (!context.hasThrowaway()) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double WC = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock()) ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST;
|
double WC = throughWater ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST;
|
||||||
for (BlockPos against1 : against) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (BlockStateInterface.get(against1).isBlockNormalCube()) {
|
BlockPos against1 = dest.offset(HORIZONTALS[i]);
|
||||||
|
if (against1.equals(src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
against1 = against1.down();
|
||||||
|
if (MovementHelper.canPlaceAgainst(against1)) {
|
||||||
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Blocks.SOUL_SAND.equals(srcDown)) {
|
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
||||||
return COST_INF; // can't sneak and backplace against soul sand =/
|
return COST_INF; // can't sneak and backplace against soul sand or half slabs =/
|
||||||
}
|
}
|
||||||
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking
|
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking
|
||||||
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
||||||
@ -132,6 +128,8 @@ public class MovementTraverse extends Movement {
|
|||||||
if (state.getStatus() != MovementState.MovementStatus.RUNNING)
|
if (state.getStatus() != MovementState.MovementStatus.RUNNING)
|
||||||
return state;
|
return state;
|
||||||
|
|
||||||
|
state.setInput(InputOverrideHandler.Input.SNEAK, false);
|
||||||
|
|
||||||
Block fd = BlockStateInterface.get(src.down()).getBlock();
|
Block fd = BlockStateInterface.get(src.down()).getBlock();
|
||||||
boolean ladder = fd instanceof BlockLadder || fd instanceof BlockVine;
|
boolean ladder = fd instanceof BlockLadder || fd instanceof BlockVine;
|
||||||
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
||||||
@ -169,7 +167,7 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(positionsToPlace[0]) || ladder;
|
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(positionToPlace) || ladder;
|
||||||
BlockPos whereAmI = playerFeet();
|
BlockPos whereAmI = playerFeet();
|
||||||
if (whereAmI.getY() != dest.getY() && !ladder) {
|
if (whereAmI.getY() != dest.getY() && !ladder) {
|
||||||
displayChatMessageRaw("Wrong Y coordinate");
|
displayChatMessageRaw("Wrong Y coordinate");
|
||||||
@ -184,11 +182,11 @@ public class MovementTraverse extends Movement {
|
|||||||
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet()) && Baritone.settings().allowSprint.get()) {
|
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
|
||||||
player().setSprinting(true);
|
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
|
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
|
||||||
if (ladder && (destDown instanceof BlockVine || destDown instanceof BlockLadder)) {
|
if (whereAmI.getY() != dest.getY() && ladder && (destDown instanceof BlockVine || destDown instanceof BlockLadder)) {
|
||||||
new MovementPillar(dest.down(), dest).updateState(state); // i'm sorry
|
new MovementPillar(dest.down(), dest).updateState(state); // i'm sorry
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -196,13 +194,29 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
wasTheBridgeBlockAlwaysThere = false;
|
wasTheBridgeBlockAlwaysThere = false;
|
||||||
for (BlockPos against1 : against) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (BlockStateInterface.get(against1).isBlockNormalCube()) {
|
BlockPos against1 = dest.offset(HORIZONTALS[i]);
|
||||||
|
if (against1.equals(src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
against1 = against1.down();
|
||||||
|
if (MovementHelper.canPlaceAgainst(against1)) {
|
||||||
if (!MovementHelper.throwaway(true)) { // get ready to place a throwaway block
|
if (!MovementHelper.throwaway(true)) { // get ready to place a throwaway block
|
||||||
displayChatMessageRaw("bb pls get me some blocks. dirt or cobble");
|
displayChatMessageRaw("bb pls get me some blocks. dirt or cobble");
|
||||||
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
|
Block standingOn = BlockStateInterface.get(playerFeet().down()).getBlock();
|
||||||
|
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
|
||||||
|
double dist = Math.max(Math.abs(dest.getX() + 0.5 - player().posX), Math.abs(dest.getZ() + 0.5 - player().posZ));
|
||||||
|
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
|
||||||
|
MovementHelper.moveTowards(state, dest);
|
||||||
|
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, false);
|
||||||
|
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.setInput(InputOverrideHandler.Input.MOVE_BACK, false);
|
||||||
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
|
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
|
||||||
double faceY = (dest.getY() + against1.getY()) * 0.5D;
|
double faceY = (dest.getY() + against1.getY()) * 0.5D;
|
||||||
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
||||||
@ -210,7 +224,7 @@ public class MovementTraverse extends Movement {
|
|||||||
|
|
||||||
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
||||||
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && Minecraft.getMinecraft().player.isSneaking()) {
|
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && Minecraft.getMinecraft().player.isSneaking()) {
|
||||||
if (LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionsToPlace[0])) {
|
if (LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
||||||
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
} else {
|
} else {
|
||||||
// Out.gui("Wrong. " + side + " " + LookBehaviorUtils.getSelectedBlock().get().offset(side) + " " + positionsToPlace[0], Out.Mode.Debug);
|
// Out.gui("Wrong. " + side + " " + LookBehaviorUtils.getSelectedBlock().get().offset(side) + " " + positionsToPlace[0], Out.Mode.Debug);
|
||||||
@ -242,7 +256,7 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
|
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
|
||||||
return state;
|
return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||||
} else {
|
} else {
|
||||||
MovementHelper.moveTowards(state, positionsToBreak[0]);
|
MovementHelper.moveTowards(state, positionsToBreak[0]);
|
||||||
return state;
|
return state;
|
||||||
@ -250,4 +264,15 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean prepared(MovementState state) {
|
||||||
|
if (playerFeet().equals(src) || playerFeet().equals(src.down())) {
|
||||||
|
Block block = BlockStateInterface.getBlock(src.down());
|
||||||
|
if (block == Blocks.LADDER || block == Blocks.VINE) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.prepared(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,12 @@
|
|||||||
package baritone.pathing.path;
|
package baritone.pathing.path;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.pathing.movement.ActionCosts;
|
import baritone.pathing.movement.*;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.movements.MovementDescend;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.movements.MovementDiagonal;
|
||||||
|
import baritone.pathing.movement.movements.MovementFall;
|
||||||
|
import baritone.pathing.movement.movements.MovementTraverse;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
@ -42,8 +44,9 @@ import static baritone.pathing.movement.MovementState.MovementStatus.*;
|
|||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class PathExecutor implements Helper {
|
public class PathExecutor implements Helper {
|
||||||
|
private static final double MAX_MAX_DIST_FROM_PATH = 3;
|
||||||
private static final double MAX_DIST_FROM_PATH = 2;
|
private static final double MAX_DIST_FROM_PATH = 2;
|
||||||
private static final double MAX_TICKS_AWAY = 200; // ten seconds
|
private static final double MAX_TICKS_AWAY = 200; // ten seconds. ok to decrease this, but it must be at least 110, see issue #102
|
||||||
private final IPath path;
|
private final IPath path;
|
||||||
private int pathPosition;
|
private int pathPosition;
|
||||||
private int ticksAway;
|
private int ticksAway;
|
||||||
@ -128,6 +131,17 @@ public class PathExecutor implements Helper {
|
|||||||
} else {
|
} else {
|
||||||
ticksAway = 0;
|
ticksAway = 0;
|
||||||
}
|
}
|
||||||
|
if (distanceFromPath > MAX_MAX_DIST_FROM_PATH) {
|
||||||
|
if (!(path.movements().get(pathPosition) instanceof MovementFall)) { // might be midair
|
||||||
|
if (pathPosition == 0 || !(path.movements().get(pathPosition - 1) instanceof MovementFall)) { // might have overshot the landing
|
||||||
|
displayChatMessageRaw("too far from path");
|
||||||
|
pathPosition = path.length() + 3;
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
failed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//this commented block is literally cursed.
|
//this commented block is literally cursed.
|
||||||
/*Out.log(actions.get(pathPosition));
|
/*Out.log(actions.get(pathPosition));
|
||||||
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
|
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
|
||||||
@ -160,7 +174,7 @@ public class PathExecutor implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
long start = System.currentTimeMillis();
|
long start = System.nanoTime() / 1000000L;
|
||||||
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
|
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
|
||||||
if (i >= 0 && i < path.movements().size()) {
|
if (i >= 0 && i < path.movements().size()) {
|
||||||
Movement m = path.movements().get(i);
|
Movement m = path.movements().get(i);
|
||||||
@ -195,11 +209,25 @@ public class PathExecutor implements Helper {
|
|||||||
toWalkInto = newWalkInto;
|
toWalkInto = newWalkInto;
|
||||||
recalcBP = false;
|
recalcBP = false;
|
||||||
}
|
}
|
||||||
long end = System.currentTimeMillis();
|
long end = System.nanoTime() / 1000000L;
|
||||||
if (end - start > 0) {
|
if (end - start > 0) {
|
||||||
//displayChatMessageRaw("Recalculating break and place took " + (end - start) + "ms");
|
//displayChatMessageRaw("Recalculating break and place took " + (end - start) + "ms");
|
||||||
}
|
}
|
||||||
Movement movement = path.movements().get(pathPosition);
|
Movement movement = path.movements().get(pathPosition);
|
||||||
|
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
|
||||||
|
costEstimateIndex = pathPosition;
|
||||||
|
// do this only once, when the movement starts, and deliberately get the cost as cached when this path was calculated, not the cost as it is right now
|
||||||
|
currentMovementInitialCostEstimate = movement.getCost(null);
|
||||||
|
for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) {
|
||||||
|
if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF) {
|
||||||
|
displayChatMessageRaw("Something has changed in the world and a future movement has become impossible. Cancelling.");
|
||||||
|
pathPosition = path.length() + 3;
|
||||||
|
failed = true;
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
double currentCost = movement.recalculateCost();
|
double currentCost = movement.recalculateCost();
|
||||||
if (currentCost >= ActionCosts.COST_INF) {
|
if (currentCost >= ActionCosts.COST_INF) {
|
||||||
displayChatMessageRaw("Something has changed in the world and this movement has become impossible. Cancelling.");
|
displayChatMessageRaw("Something has changed in the world and this movement has become impossible. Cancelling.");
|
||||||
@ -208,10 +236,6 @@ public class PathExecutor implements Helper {
|
|||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
|
|
||||||
costEstimateIndex = pathPosition;
|
|
||||||
currentMovementInitialCostEstimate = currentCost; // do this only once, when the movement starts
|
|
||||||
}
|
|
||||||
MovementState.MovementStatus movementStatus = movement.update();
|
MovementState.MovementStatus movementStatus = movement.update();
|
||||||
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
|
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
|
||||||
displayChatMessageRaw("Movement returns status " + movementStatus);
|
displayChatMessageRaw("Movement returns status " + movementStatus);
|
||||||
@ -228,6 +252,7 @@ public class PathExecutor implements Helper {
|
|||||||
onTick(event);
|
onTick(event);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
sprintIfRequested();
|
||||||
ticksOnCurrent++;
|
ticksOnCurrent++;
|
||||||
if (ticksOnCurrent > currentMovementInitialCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
|
if (ticksOnCurrent > currentMovementInitialCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
|
||||||
// only fail if the total time has exceeded the initial estimate
|
// only fail if the total time has exceeded the initial estimate
|
||||||
@ -245,6 +270,59 @@ public class PathExecutor implements Helper {
|
|||||||
return false; // movement is in progress
|
return false; // movement is in progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sprintIfRequested() {
|
||||||
|
if (!new CalculationContext().canSprint()) {
|
||||||
|
player().setSprinting(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown(mc.gameSettings.keyBindSprint)) {
|
||||||
|
if (!player().isSprinting()) {
|
||||||
|
player().setSprinting(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Movement movement = path.movements().get(pathPosition);
|
||||||
|
if (movement instanceof MovementDescend && pathPosition < path.length() - 2) {
|
||||||
|
Movement next = path.movements().get(pathPosition + 1);
|
||||||
|
if (next instanceof MovementDescend) {
|
||||||
|
if (next.getDirection().equals(movement.getDirection())) {
|
||||||
|
if (playerFeet().equals(movement.getDest())) {
|
||||||
|
pathPosition++;
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
|
if (!player().isSprinting()) {
|
||||||
|
player().setSprinting(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next instanceof MovementTraverse) {
|
||||||
|
if (next.getDirection().down().equals(movement.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
|
||||||
|
if (playerFeet().equals(movement.getDest())) {
|
||||||
|
pathPosition++;
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
|
if (!player().isSprinting()) {
|
||||||
|
player().setSprinting(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
|
||||||
|
if (playerFeet().equals(movement.getDest())) {
|
||||||
|
pathPosition++;
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
|
if (!player().isSprinting()) {
|
||||||
|
player().setSprinting(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//displayChatMessageRaw("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
|
||||||
|
}
|
||||||
|
player().setSprinting(false);
|
||||||
|
}
|
||||||
|
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
return pathPosition;
|
return pathPosition;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ import net.minecraft.world.chunk.Chunk;
|
|||||||
|
|
||||||
public class BlockStateInterface implements Helper {
|
public class BlockStateInterface implements Helper {
|
||||||
|
|
||||||
|
private static Chunk prev = null;
|
||||||
|
|
||||||
public static IBlockState get(BlockPos pos) { // wrappers for chunk caching capability
|
public static IBlockState get(BlockPos pos) { // wrappers for chunk caching capability
|
||||||
|
|
||||||
// Invalid vertical position
|
// Invalid vertical position
|
||||||
@ -37,8 +39,18 @@ public class BlockStateInterface implements Helper {
|
|||||||
return Blocks.AIR.getDefaultState();
|
return Blocks.AIR.getDefaultState();
|
||||||
|
|
||||||
if (!Baritone.settings().pathThroughCachedOnly.get()) {
|
if (!Baritone.settings().pathThroughCachedOnly.get()) {
|
||||||
|
Chunk cached = prev;
|
||||||
|
// there's great cache locality in block state lookups
|
||||||
|
// generally it's within each movement
|
||||||
|
// if it's the same chunk as last time
|
||||||
|
// we can just skip the mc.world.getChunk lookup
|
||||||
|
// which is a Long2ObjectOpenHashMap.get
|
||||||
|
if (cached != null && cached.x == pos.getX() >> 4 && cached.z == pos.getZ() >> 4) {
|
||||||
|
return cached.getBlockState(pos);
|
||||||
|
}
|
||||||
Chunk chunk = mc.world.getChunk(pos);
|
Chunk chunk = mc.world.getChunk(pos);
|
||||||
if (chunk.isLoaded()) {
|
if (chunk.isLoaded()) {
|
||||||
|
prev = chunk;
|
||||||
return chunk.getBlockState(pos);
|
return chunk.getBlockState(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,6 +66,10 @@ public class BlockStateInterface implements Helper {
|
|||||||
return Blocks.AIR.getDefaultState();
|
return Blocks.AIR.getDefaultState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void clearCachedChunk() {
|
||||||
|
prev = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static Block getBlock(BlockPos pos) {
|
public static Block getBlock(BlockPos pos) {
|
||||||
return get(pos).getBlock();
|
return get(pos).getBlock();
|
||||||
}
|
}
|
||||||
|
@ -19,24 +19,27 @@ package baritone.utils;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.Settings;
|
import baritone.Settings;
|
||||||
|
import baritone.api.event.events.ChatEvent;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
|
import baritone.behavior.impl.FollowBehavior;
|
||||||
|
import baritone.behavior.impl.MineBehavior;
|
||||||
import baritone.behavior.impl.PathingBehavior;
|
import baritone.behavior.impl.PathingBehavior;
|
||||||
import baritone.chunk.ChunkPacker;
|
import baritone.chunk.ChunkPacker;
|
||||||
import baritone.chunk.Waypoint;
|
import baritone.chunk.Waypoint;
|
||||||
import baritone.chunk.WorldProvider;
|
import baritone.chunk.WorldProvider;
|
||||||
import baritone.event.events.ChatEvent;
|
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
import baritone.pathing.calc.AStarPathFinder;
|
||||||
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.goals.*;
|
import baritone.pathing.goals.*;
|
||||||
import baritone.pathing.movement.ActionCosts;
|
import baritone.pathing.movement.ActionCosts;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ExampleBaritoneControl extends Behavior {
|
public class ExampleBaritoneControl extends Behavior {
|
||||||
public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl();
|
public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl();
|
||||||
@ -52,8 +55,10 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
@Override
|
@Override
|
||||||
public void onSendChatMessage(ChatEvent event) {
|
public void onSendChatMessage(ChatEvent event) {
|
||||||
if (!Baritone.settings().chatControl.get()) {
|
if (!Baritone.settings().chatControl.get()) {
|
||||||
|
if (!Baritone.settings().removePrefix.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
String msg = event.getMessage();
|
String msg = event.getMessage();
|
||||||
if (Baritone.settings().prefix.get()) {
|
if (Baritone.settings().prefix.get()) {
|
||||||
if (!msg.startsWith("#")) {
|
if (!msg.startsWith("#")) {
|
||||||
@ -99,16 +104,30 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("path")) {
|
if (msg.equals("path")) {
|
||||||
PathingBehavior.INSTANCE.path();
|
if (!PathingBehavior.INSTANCE.path()) {
|
||||||
|
if (PathingBehavior.INSTANCE.getGoal() == null) {
|
||||||
|
displayChatMessageRaw("No goal.");
|
||||||
|
} else {
|
||||||
|
displayChatMessageRaw("Currently executing a path. Please cancel it first.");
|
||||||
|
}
|
||||||
|
}
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.toLowerCase().equals("cancel")) {
|
if (msg.toLowerCase().equals("cancel")) {
|
||||||
PathingBehavior.INSTANCE.cancel();
|
PathingBehavior.INSTANCE.cancel();
|
||||||
|
FollowBehavior.INSTANCE.cancel();
|
||||||
|
MineBehavior.INSTANCE.cancel();
|
||||||
event.cancel();
|
event.cancel();
|
||||||
displayChatMessageRaw("ok canceled");
|
displayChatMessageRaw("ok canceled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msg.toLowerCase().equals("forcecancel")) {
|
||||||
|
AbstractNodeCostSearch.forceCancel();
|
||||||
|
event.cancel();
|
||||||
|
displayChatMessageRaw("ok force canceled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (msg.toLowerCase().equals("invert")) {
|
if (msg.toLowerCase().equals("invert")) {
|
||||||
Goal goal = PathingBehavior.INSTANCE.getGoal();
|
Goal goal = PathingBehavior.INSTANCE.getGoal();
|
||||||
BlockPos runAwayFrom;
|
BlockPos runAwayFrom;
|
||||||
@ -127,7 +146,21 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
PathingBehavior.INSTANCE.path();
|
if (!PathingBehavior.INSTANCE.path()) {
|
||||||
|
displayChatMessageRaw("Currently executing a path. Please cancel it first.");
|
||||||
|
}
|
||||||
|
event.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (msg.toLowerCase().equals("follow")) {
|
||||||
|
Optional<Entity> entity = MovementHelper.whatEntityAmILookingAt();
|
||||||
|
if (!entity.isPresent()) {
|
||||||
|
displayChatMessageRaw("You aren't looking at an entity bruh");
|
||||||
|
event.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FollowBehavior.INSTANCE.follow(entity.get());
|
||||||
|
displayChatMessageRaw("Following " + entity.get());
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -157,28 +190,16 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.toLowerCase().startsWith("mine")) {
|
if (msg.toLowerCase().startsWith("mine")) {
|
||||||
String blockType = msg.toLowerCase().substring(4).trim();
|
String[] blockTypes = msg.toLowerCase().substring(4).trim().split(" ");
|
||||||
List<BlockPos> locs = new ArrayList<>(WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(blockType, 1, 1));
|
for (String s : blockTypes) {
|
||||||
if (locs.isEmpty()) {
|
if (ChunkPacker.stringToBlock(s) == null) {
|
||||||
displayChatMessageRaw("No locations known");
|
displayChatMessageRaw(s + " isn't a valid block name");
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BlockPos playerFeet = playerFeet();
|
|
||||||
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
|
||||||
|
|
||||||
// remove any that are within loaded chunks that aren't actually what we want
|
|
||||||
locs.removeAll(locs.stream()
|
|
||||||
.filter(pos -> !(world().getChunk(pos) instanceof EmptyChunk))
|
|
||||||
.filter(pos -> !ChunkPacker.blockToString(BlockStateInterface.get(pos).getBlock()).equalsIgnoreCase(blockType))
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
|
|
||||||
if (locs.size() > 30) {
|
|
||||||
displayChatMessageRaw("Pathing to any of closest 30");
|
|
||||||
locs = locs.subList(0, 30);
|
|
||||||
}
|
}
|
||||||
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalTwoBlocks::new).toArray(Goal[]::new)));
|
MineBehavior.INSTANCE.mine(blockTypes);
|
||||||
PathingBehavior.INSTANCE.path();
|
displayChatMessageRaw("Started mining blocks of type " + Arrays.toString(blockTypes));
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -195,7 +216,7 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
// for example, "show deaths"
|
// for example, "show deaths"
|
||||||
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
||||||
}
|
}
|
||||||
Waypoint.Tag tag = Waypoint.TAG_MAP.get(waypointType);
|
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
displayChatMessageRaw("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
displayChatMessageRaw("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||||
event.cancel();
|
event.cancel();
|
||||||
@ -214,14 +235,26 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
}
|
}
|
||||||
if (msg.toLowerCase().startsWith("goto")) {
|
if (msg.toLowerCase().startsWith("goto")) {
|
||||||
String waypointType = msg.toLowerCase().substring(4).trim();
|
String waypointType = msg.toLowerCase().substring(4).trim();
|
||||||
if (waypointType.endsWith("s")) {
|
if (waypointType.endsWith("s") && Waypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
|
||||||
// for example, "show deaths"
|
// for example, "show deaths"
|
||||||
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
||||||
}
|
}
|
||||||
Waypoint.Tag tag = Waypoint.TAG_MAP.get(waypointType);
|
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
displayChatMessageRaw("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
String mining = waypointType;
|
||||||
|
//displayChatMessageRaw("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||||
event.cancel();
|
event.cancel();
|
||||||
|
if (ChunkPacker.stringToBlock(mining) == null) {
|
||||||
|
displayChatMessageRaw("No locations for " + mining + " known, cancelling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<BlockPos> locs = MineBehavior.scanFor(Arrays.asList(mining), 64);
|
||||||
|
if (locs.isEmpty()) {
|
||||||
|
displayChatMessageRaw("No locations for " + mining + " known, cancelling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Waypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().waypoints.getMostRecentByTag(tag);
|
Waypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().waypoints.getMostRecentByTag(tag);
|
||||||
@ -232,7 +265,9 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
}
|
}
|
||||||
Goal goal = new GoalBlock(waypoint.location);
|
Goal goal = new GoalBlock(waypoint.location);
|
||||||
PathingBehavior.INSTANCE.setGoal(goal);
|
PathingBehavior.INSTANCE.setGoal(goal);
|
||||||
PathingBehavior.INSTANCE.path();
|
if (!PathingBehavior.INSTANCE.path()) {
|
||||||
|
displayChatMessageRaw("Currently executing a path. Please cancel it first.");
|
||||||
|
}
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -286,7 +321,7 @@ public class ExampleBaritoneControl extends Behavior {
|
|||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getByValueType(Boolean.class);
|
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
|
||||||
for (Settings.Setting<Boolean> setting : toggleable) {
|
for (Settings.Setting<Boolean> setting : toggleable) {
|
||||||
if (msg.equalsIgnoreCase(setting.getName())) {
|
if (msg.equalsIgnoreCase(setting.getName())) {
|
||||||
setting.value ^= true;
|
setting.value ^= true;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import net.minecraft.block.BlockSlab;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
@ -33,7 +34,13 @@ import net.minecraft.util.text.TextFormatting;
|
|||||||
*/
|
*/
|
||||||
public interface Helper {
|
public interface Helper {
|
||||||
|
|
||||||
ITextComponent MESSAGE_PREFIX = new TextComponentString("§5[§dBaritone§5]§7");
|
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
|
||||||
|
"%s[%sBaritone%s]%s",
|
||||||
|
TextFormatting.DARK_PURPLE,
|
||||||
|
TextFormatting.LIGHT_PURPLE,
|
||||||
|
TextFormatting.DARK_PURPLE,
|
||||||
|
TextFormatting.GRAY
|
||||||
|
));
|
||||||
|
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
@ -47,10 +54,11 @@ public interface Helper {
|
|||||||
|
|
||||||
default BlockPos playerFeet() {
|
default BlockPos playerFeet() {
|
||||||
// TODO find a better way to deal with soul sand!!!!!
|
// TODO find a better way to deal with soul sand!!!!!
|
||||||
return new BlockPos(player().posX, player().posY + 0.1251, player().posZ);
|
BlockPos feet = new BlockPos(player().posX, player().posY + 0.1251, player().posZ);
|
||||||
/*if (BlockStateInterface.get(feet).getBlock().equals(Blocks.SOUL_SAND) && player().posY > feet.getY() + 0.874999) {
|
if (BlockStateInterface.get(feet).getBlock() instanceof BlockSlab) {
|
||||||
return feet.up();
|
return feet.up();
|
||||||
}*/
|
}
|
||||||
|
return feet;
|
||||||
}
|
}
|
||||||
|
|
||||||
default Vec3d playerFeetAsVec() {
|
default Vec3d playerFeetAsVec() {
|
||||||
|
@ -34,6 +34,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
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.MathHelper;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -188,7 +189,7 @@ public final class PathRenderer implements Helper {
|
|||||||
maxX = goalPos.getX() + 1 - 0.002 - renderPosX;
|
maxX = goalPos.getX() + 1 - 0.002 - renderPosX;
|
||||||
minZ = goalPos.getZ() + 0.002 - renderPosZ;
|
minZ = goalPos.getZ() + 0.002 - renderPosZ;
|
||||||
maxZ = goalPos.getZ() + 1 - 0.002 - renderPosZ;
|
maxZ = goalPos.getZ() + 1 - 0.002 - renderPosZ;
|
||||||
double y = Math.sin((System.currentTimeMillis() % 2000L) / 2000F * Math.PI * 2);
|
double y = MathHelper.sin((float) (((float) (System.nanoTime() / 1000000L) % 2000L) / 2000F * Math.PI * 2));
|
||||||
y1 = 1 + y + goalPos.getY() - renderPosY;
|
y1 = 1 + y + goalPos.getY() - renderPosY;
|
||||||
y2 = 1 - y + goalPos.getY() - renderPosY;
|
y2 = 1 - y + goalPos.getY() - renderPosY;
|
||||||
minY = goalPos.getY() - renderPosY;
|
minY = goalPos.getY() - renderPosY;
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
import static baritone.behavior.impl.LookBehaviorUtils.calcVec3dFromRotation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@ -44,4 +47,16 @@ public final class RayTraceUtils implements Helper {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RayTraceResult rayTraceTowards(Rotation rotation) {
|
||||||
|
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
||||||
|
Vec3d start = mc.player.getPositionEyes(1.0F);
|
||||||
|
Vec3d direction = calcVec3dFromRotation(rotation);
|
||||||
|
Vec3d end = start.add(
|
||||||
|
direction.x * blockReachDistance,
|
||||||
|
direction.y * blockReachDistance,
|
||||||
|
direction.z * blockReachDistance
|
||||||
|
);
|
||||||
|
return mc.world.rayTraceBlocks(start, end, false, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,92 +18,33 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.event.events.ItemSlotEvent;
|
|
||||||
import baritone.event.listener.AbstractGameEventListener;
|
|
||||||
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.Minecraft;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.init.Enchantments;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.item.ItemAir;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ItemTool;
|
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cached list of the best tools on the hotbar for any block
|
* A cached list of the best tools on the hotbar for any block
|
||||||
*
|
*
|
||||||
* @author avecowa, Brady
|
* @author avecowa, Brady, leijurv
|
||||||
*/
|
*/
|
||||||
public class ToolSet implements Helper {
|
public class ToolSet implements Helper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of the internal event listener used to hook into Baritone's event bus
|
* A cache mapping a {@link Block} to how long it will take to break
|
||||||
*/
|
|
||||||
private static final InternalEventListener INTERNAL_EVENT_LISTENER = new InternalEventListener();
|
|
||||||
|
|
||||||
static {
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().registerEventListener(INTERNAL_EVENT_LISTENER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of tools on the hotbar that should be considered.
|
|
||||||
* Note that if there are no tools on the hotbar this list will still have one (null) entry.
|
|
||||||
*/
|
|
||||||
private List<ItemTool> tools;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapping from the tools array to what hotbar slots the tool is actually in.
|
|
||||||
* tools.get(i) will be on your hotbar in slot slots.get(i)
|
|
||||||
*/
|
|
||||||
private List<Byte> slots;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapping from a block to which tool index is best for it.
|
|
||||||
* The values in this map are *not* hotbar slots indexes, they need to be looked up in slots
|
|
||||||
* in order to be converted into hotbar slots.
|
|
||||||
*/
|
|
||||||
private Map<Block, Byte> slotCache = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A cache mapping a {@link IBlockState} to how long it will take to break
|
|
||||||
* with this toolset, given the optimum tool is used.
|
* with this toolset, given the optimum tool is used.
|
||||||
*/
|
*/
|
||||||
private Map<IBlockState, Double> breakStrengthCache = new HashMap<>();
|
private Map<Block, Double> breakStrengthCache = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a toolset from the current player's inventory (but don't calculate any hardness values just yet)
|
* Create a toolset from the current player's inventory (but don't calculate any hardness values just yet)
|
||||||
*/
|
*/
|
||||||
public ToolSet() {
|
public ToolSet() {}
|
||||||
EntityPlayerSP p = Minecraft.getMinecraft().player;
|
|
||||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
|
||||||
tools = new ArrayList<>();
|
|
||||||
slots = new ArrayList<>();
|
|
||||||
boolean fnull = false;
|
|
||||||
for (byte i = 0; i < 9; i++) {
|
|
||||||
if (!fnull || ((!(inv.get(i).getItem() instanceof ItemAir)) && inv.get(i).getItem() instanceof ItemTool)) {
|
|
||||||
tools.add(inv.get(i).getItem() instanceof ItemTool ? (ItemTool) inv.get(i).getItem() : null);
|
|
||||||
slots.add(i);
|
|
||||||
fnull |= (inv.get(i).getItem() instanceof ItemAir) || (!inv.get(i).getItem().isDamageable());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A caching wrapper around getBestToolIndex
|
|
||||||
*
|
|
||||||
* @param state the blockstate to be mined
|
|
||||||
* @return get which tool on the hotbar is best for mining it
|
|
||||||
*/
|
|
||||||
public Item getBestTool(IBlockState state) {
|
|
||||||
return tools.get(slotCache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate which tool on the hotbar is best for mining
|
* Calculate which tool on the hotbar is best for mining
|
||||||
@ -111,15 +52,11 @@ public class ToolSet implements Helper {
|
|||||||
* @param b the blockstate to be mined
|
* @param b the blockstate to be mined
|
||||||
* @return a byte indicating the index in the tools array that worked best
|
* @return a byte indicating the index in the tools array that worked best
|
||||||
*/
|
*/
|
||||||
private byte getBestToolIndex(IBlockState b) {
|
public byte getBestSlot(IBlockState b) {
|
||||||
byte best = 0;
|
byte best = 0;
|
||||||
float value = -1;
|
double value = -1;
|
||||||
for (byte i = 0; i < tools.size(); i++) {
|
for (byte i = 0; i < 9; i++) {
|
||||||
Item item = tools.get(i);
|
double v = calculateStrVsBlock(i, b);
|
||||||
if (item == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float v = item.getDestroySpeed(new ItemStack(item), b);
|
|
||||||
if (v > value || value == -1) {
|
if (v > value || value == -1) {
|
||||||
value = v;
|
value = v;
|
||||||
best = i;
|
best = i;
|
||||||
@ -128,62 +65,65 @@ public class ToolSet implements Helper {
|
|||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get which hotbar slot should be selected for fastest mining
|
|
||||||
*
|
|
||||||
* @param state the blockstate to be mined
|
|
||||||
* @return a byte indicating which hotbar slot worked best
|
|
||||||
*/
|
|
||||||
public byte getBestSlot(IBlockState state) {
|
|
||||||
return slots.get(slotCache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using the best tool on the hotbar, how long would it take to mine this block
|
* Using the best tool on the hotbar, how long would it take to mine this block
|
||||||
*
|
*
|
||||||
* @param state the blockstate to be mined
|
* @param state the blockstate to be mined
|
||||||
* @param pos the blockpos to be mined
|
|
||||||
* @return how long it would take in ticks
|
* @return how long it would take in ticks
|
||||||
*/
|
*/
|
||||||
public double getStrVsBlock(IBlockState state, BlockPos pos) {
|
public double getStrVsBlock(IBlockState state) {
|
||||||
return this.breakStrengthCache.computeIfAbsent(state, s -> calculateStrVsBlock(s, pos));
|
return this.breakStrengthCache.computeIfAbsent(state.getBlock(), b -> calculateStrVsBlock(getBestSlot(state), state));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates how long would it take to mine the specified block given the best tool
|
* Calculates how long would it take to mine the specified block given the best tool
|
||||||
* in this toolset is used.
|
* in this toolset is used. A negative value is returned if the specified block is unbreakable.
|
||||||
*
|
*
|
||||||
* @param state the blockstate to be mined
|
* @param state the blockstate to be mined
|
||||||
* @param pos the blockpos to be mined
|
|
||||||
* @return how long it would take in ticks
|
* @return how long it would take in ticks
|
||||||
*/
|
*/
|
||||||
private double calculateStrVsBlock(IBlockState state, BlockPos pos) {
|
private double calculateStrVsBlock(byte slot, IBlockState state) {
|
||||||
// Calculate the slot with the best item
|
// Calculate the slot with the best item
|
||||||
byte slot = this.getBestSlot(state);
|
ItemStack contents = player().inventory.getStackInSlot(slot);
|
||||||
|
|
||||||
INTERNAL_EVENT_LISTENER.setOverrideSlot(slot);
|
float blockHard = state.getBlockHardness(null, null);
|
||||||
|
if (blockHard < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
// Calculate the relative hardness of the block to the player
|
float speed = contents.getDestroySpeed(state);
|
||||||
float hardness = state.getPlayerRelativeBlockHardness(player(), world(), pos);
|
if (speed > 1) {
|
||||||
|
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, contents);
|
||||||
// Restore the old slot
|
if (effLevel > 0 && !contents.isEmpty()) {
|
||||||
INTERNAL_EVENT_LISTENER.setOverrideSlot(-1);
|
speed += effLevel * effLevel + 1;
|
||||||
|
}
|
||||||
return hardness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class InternalEventListener implements AbstractGameEventListener {
|
if (Baritone.settings().considerPotionEffects.get()) {
|
||||||
|
if (player().isPotionActive(MobEffects.HASTE)) {
|
||||||
private int overrideSlot;
|
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onQueryItemSlotForBlocks(ItemSlotEvent event) {
|
|
||||||
if (this.overrideSlot >= 0)
|
|
||||||
event.setSlot(this.overrideSlot);
|
|
||||||
}
|
}
|
||||||
|
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
|
||||||
final void setOverrideSlot(int overrideSlot) {
|
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
||||||
this.overrideSlot = overrideSlot;
|
case 0:
|
||||||
|
speed *= 0.3;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
speed *= 0.09;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
speed *= 0.0027;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
speed *= 0.00081;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
speed /= blockHard;
|
||||||
|
if (state.getMaterial().isToolNotRequired() || (!contents.isEmpty() && contents.canHarvestBlock(state))) {
|
||||||
|
return speed / 30;
|
||||||
|
} else {
|
||||||
|
return speed / 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,9 @@ public final class Utils {
|
|||||||
*/
|
*/
|
||||||
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
|
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
|
||||||
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
|
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
|
||||||
double yaw = Math.atan2(delta[0], -delta[2]);
|
double yaw = MathHelper.atan2(delta[0], -delta[2]);
|
||||||
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
|
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
|
||||||
double pitch = Math.atan2(delta[1], dist);
|
double pitch = MathHelper.atan2(delta[1], dist);
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
(float) radToDeg(yaw),
|
(float) radToDeg(yaw),
|
||||||
(float) radToDeg(pitch)
|
(float) radToDeg(pitch)
|
||||||
|
@ -15,11 +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.launch.mixins.accessor;
|
package baritone.utils.accessor;
|
||||||
|
|
||||||
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@ -27,8 +23,7 @@ import java.io.File;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:36 AM
|
* @since 8/4/2018 11:36 AM
|
||||||
*/
|
*/
|
||||||
@Mixin(AnvilChunkLoader.class)
|
|
||||||
public interface IAnvilChunkLoader {
|
public interface IAnvilChunkLoader {
|
||||||
|
|
||||||
@Accessor File getChunkSaveLocation();
|
File getChunkSaveLocation();
|
||||||
}
|
}
|
@ -15,19 +15,15 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.launch.mixins.accessor;
|
package baritone.utils.accessor;
|
||||||
|
|
||||||
import net.minecraft.world.chunk.storage.IChunkLoader;
|
import net.minecraft.world.chunk.storage.IChunkLoader;
|
||||||
import net.minecraft.world.gen.ChunkProviderServer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:33 AM
|
* @since 8/4/2018 11:33 AM
|
||||||
*/
|
*/
|
||||||
@Mixin(ChunkProviderServer.class)
|
|
||||||
public interface IChunkProviderServer {
|
public interface IChunkProviderServer {
|
||||||
|
|
||||||
@Accessor IChunkLoader getChunkLoader();
|
IChunkLoader getChunkLoader();
|
||||||
}
|
}
|
@ -26,11 +26,11 @@ import net.minecraft.util.math.Vec3i;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class BetterBlockPos extends BlockPos {
|
public final class BetterBlockPos extends BlockPos {
|
||||||
private final int x;
|
public final int x;
|
||||||
private final int y;
|
public final int y;
|
||||||
private final int z;
|
public final int z;
|
||||||
private final int hashCode;
|
public final long hashCode;
|
||||||
|
|
||||||
public BetterBlockPos(int x, int y, int z) {
|
public BetterBlockPos(int x, int y, int z) {
|
||||||
super(x, y, z);
|
super(x, y, z);
|
||||||
@ -48,10 +48,10 @@ public class BetterBlockPos extends BlockPos {
|
|||||||
*
|
*
|
||||||
* That's why we grab out the X, Y, Z and calculate our own hashcode
|
* That's why we grab out the X, Y, Z and calculate our own hashcode
|
||||||
*/
|
*/
|
||||||
int hash = 3241;
|
long hash = 3241;
|
||||||
hash = 3457689 * hash + x;
|
hash = 3457689L * hash + x;
|
||||||
hash = 8734625 * hash + y;
|
hash = 8734625L * hash + y;
|
||||||
hash = 2873465 * hash + z;
|
hash = 2873465L * hash + z;
|
||||||
this.hashCode = hash;
|
this.hashCode = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class BetterBlockPos extends BlockPos {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int hashCode() {
|
public final int hashCode() {
|
||||||
return hashCode;
|
return (int) hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,11 +42,18 @@ public enum PathingBlockType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PathingBlockType fromBits(boolean b1, boolean b2) {
|
public static PathingBlockType fromBits(boolean b1, boolean b2) {
|
||||||
for (PathingBlockType type : values())
|
if (b1) {
|
||||||
if (type.bits[0] == b1 && type.bits[1] == b2)
|
if (b2) {
|
||||||
return type;
|
return PathingBlockType.SOLID;
|
||||||
|
} else {
|
||||||
// This will never happen, but if it does, assume it's just AIR
|
return PathingBlockType.AVOID;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (b2) {
|
||||||
|
return PathingBlockType.WATER;
|
||||||
|
} else {
|
||||||
return PathingBlockType.AIR;
|
return PathingBlockType.AIR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,10 +33,7 @@ public class CachedRegionTest {
|
|||||||
byte xz = part1;
|
byte xz = part1;
|
||||||
int X = xz & 0x0f;
|
int X = xz & 0x0f;
|
||||||
int Z = (xz >>> 4) & 0x0f;
|
int Z = (xz >>> 4) & 0x0f;
|
||||||
int Y = (int) part2;
|
int Y = part2 & 0xff;
|
||||||
if (Y < 0) {
|
|
||||||
Y += 256;
|
|
||||||
}
|
|
||||||
if (x != X || y != Y || z != Z) {
|
if (x != X || y != Y || z != Z) {
|
||||||
System.out.println(x + " " + X + " " + y + " " + Y + " " + z + " " + Z);
|
System.out.println(x + " " + X + " " + y + " " + Y + " " + z + " " + Z);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class OpenSetsTest {
|
|||||||
public void removeAndTest(int amount, IOpenSet[] test, Optional<Collection<PathNode>> mustContain) {
|
public void removeAndTest(int amount, IOpenSet[] test, Optional<Collection<PathNode>> mustContain) {
|
||||||
double[][] results = new double[test.length][amount];
|
double[][] results = new double[test.length][amount];
|
||||||
for (int i = 0; i < test.length; i++) {
|
for (int i = 0; i < test.length; i++) {
|
||||||
long before = System.currentTimeMillis();
|
long before = System.nanoTime() / 1000000L;
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
PathNode pn = test[i].removeLowest();
|
PathNode pn = test[i].removeLowest();
|
||||||
if (mustContain.isPresent() && !mustContain.get().contains(pn)) {
|
if (mustContain.isPresent() && !mustContain.get().contains(pn)) {
|
||||||
@ -50,7 +50,7 @@ public class OpenSetsTest {
|
|||||||
}
|
}
|
||||||
results[i][j] = pn.combinedCost;
|
results[i][j] = pn.combinedCost;
|
||||||
}
|
}
|
||||||
System.out.println(test[i].getClass() + " " + (System.currentTimeMillis() - before));
|
System.out.println(test[i].getClass() + " " + (System.nanoTime() / 1000000L - before));
|
||||||
}
|
}
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
for (int i = 1; i < test.length; i++) {
|
for (int i = 1; i < test.length; i++) {
|
||||||
@ -104,10 +104,10 @@ public class OpenSetsTest {
|
|||||||
|
|
||||||
System.out.println("Insertion");
|
System.out.println("Insertion");
|
||||||
for (IOpenSet set : test) {
|
for (IOpenSet set : test) {
|
||||||
long before = System.currentTimeMillis();
|
long before = System.nanoTime() / 1000000L;
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
set.insert(toInsert[i]);
|
set.insert(toInsert[i]);
|
||||||
System.out.println(set.getClass() + " " + (System.currentTimeMillis() - before));
|
System.out.println(set.getClass() + " " + (System.nanoTime() / 1000000L - before));
|
||||||
//all three take either 0 or 1ms to insert up to 10,000 nodes
|
//all three take either 0 or 1ms to insert up to 10,000 nodes
|
||||||
//linkedlist takes 0ms most often (because there's no array resizing or allocation there, just pointer shuffling)
|
//linkedlist takes 0ms most often (because there's no array resizing or allocation there, just pointer shuffling)
|
||||||
}
|
}
|
||||||
|
49
src/test/java/baritone/pathing/goals/GoalGetToBlockTest.java
Normal file
49
src/test/java/baritone/pathing/goals/GoalGetToBlockTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.pathing.goals;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GoalGetToBlockTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isInGoal() {
|
||||||
|
List<String> acceptableOffsets = new ArrayList<>(Arrays.asList("0,0,0", "0,0,1", "0,0,-1", "1,0,0", "-1,0,0", "0,-1,1", "0,-1,-1", "1,-1,0", "-1,-1,0", "0,1,0", "0,-1,0", "0,-2,0"));
|
||||||
|
for (int x = -10; x <= 10; x++) {
|
||||||
|
for (int y = -10; y <= 10; y++) {
|
||||||
|
for (int z = -10; z <= 10; z++) {
|
||||||
|
boolean inGoal = new GoalGetToBlock(new BlockPos(0, 0, 0)).isInGoal(new BlockPos(x, y, z));
|
||||||
|
String repr = x + "," + y + "," + z;
|
||||||
|
System.out.println(repr + " " + inGoal);
|
||||||
|
if (inGoal) {
|
||||||
|
assertTrue(repr, acceptableOffsets.contains(repr));
|
||||||
|
acceptableOffsets.remove(repr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(acceptableOffsets.toString(), acceptableOffsets.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
@ -44,21 +44,21 @@ public class BetterBlockPosTest {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
long before1 = System.currentTimeMillis();
|
long before1 = System.nanoTime() / 1000000L;
|
||||||
for (int i = 0; i < 1000000; i++) {
|
for (int i = 0; i < 1000000; i++) {
|
||||||
pos.up();
|
pos.up();
|
||||||
}
|
}
|
||||||
long after1 = System.currentTimeMillis();
|
long after1 = System.nanoTime() / 1000000L;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000); // give GC some time
|
Thread.sleep(1000); // give GC some time
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
long before2 = System.currentTimeMillis();
|
long before2 = System.nanoTime() / 1000000L;
|
||||||
for (int i = 0; i < 1000000; i++) {
|
for (int i = 0; i < 1000000; i++) {
|
||||||
pos2.up();
|
pos2.up();
|
||||||
}
|
}
|
||||||
long after2 = System.currentTimeMillis();
|
long after2 = System.nanoTime() / 1000000L;
|
||||||
System.out.println((after1 - before1) + " " + (after2 - before2));
|
System.out.println((after1 - before1) + " " + (after2 - before2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ public class BetterBlockPosTest {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
long before1 = System.currentTimeMillis();
|
long before1 = System.nanoTime() / 1000000L;
|
||||||
for (int i = 0; i < 1000000; i++) {
|
for (int i = 0; i < 1000000; i++) {
|
||||||
pos.up(0);
|
pos.up(0);
|
||||||
pos.up(1);
|
pos.up(1);
|
||||||
@ -78,13 +78,13 @@ public class BetterBlockPosTest {
|
|||||||
pos.up(3);
|
pos.up(3);
|
||||||
pos.up(4);
|
pos.up(4);
|
||||||
}
|
}
|
||||||
long after1 = System.currentTimeMillis();
|
long after1 = System.nanoTime() / 1000000L;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000); // give GC some time
|
Thread.sleep(1000); // give GC some time
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
long before2 = System.currentTimeMillis();
|
long before2 = System.nanoTime() / 1000000L;
|
||||||
for (int i = 0; i < 1000000; i++) {
|
for (int i = 0; i < 1000000; i++) {
|
||||||
pos2.up(0);
|
pos2.up(0);
|
||||||
pos2.up(1);
|
pos2.up(1);
|
||||||
@ -92,7 +92,7 @@ public class BetterBlockPosTest {
|
|||||||
pos2.up(3);
|
pos2.up(3);
|
||||||
pos2.up(4);
|
pos2.up(4);
|
||||||
}
|
}
|
||||||
long after2 = System.currentTimeMillis();
|
long after2 = System.nanoTime() / 1000000L;
|
||||||
System.out.println((after1 - before1) + " " + (after2 - before2));
|
System.out.println((after1 - before1) + " " + (after2 - before2));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user