Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e661330fb6 | |||
| 9b13380b29 | |||
| b48444da8c | |||
| 11a4225eaf | |||
| 0611e3088e | |||
| 73628f09c1 | |||
| a907746f53 | |||
| 8189e90569 | |||
| 9f83677df9 | |||
| 5265c46f60 | |||
| 6d37e14b0e | |||
| fbecff52af | |||
| 4af14cf0a6 | |||
| 16a201255e | |||
| 22bb9f0ec8 | |||
| 654ac1075a | |||
| ffc050668b | |||
| 80f65452e1 | |||
| c614d7ec6a | |||
| c37a5ba956 | |||
| da5969c2fd | |||
| 990107a1fa | |||
| 42eb86b624 | |||
| b65a199e54 | |||
| 88e3bcdf63 | |||
| 0fbfa32e6b | |||
| 20405716bc | |||
| 8da7406e8f | |||
| 97fd3df8f7 | |||
| b9b33b5351 | |||
| 19ecb1bbb3 | |||
| f6043f4ac6 | |||
| ed1941abdb | |||
| 24d24728dc | |||
| 77db4cd19f | |||
| adbb03e5cb | |||
| f0226f1ea7 | |||
| be5df2677b | |||
| 3d4a856bb2 | |||
| 1b1233d26a | |||
| c4b0e0a810 | |||
| 1dee8ef355 | |||
| 8cee173f92 | |||
| 19e0e6d962 | |||
| ef8fd70475 | |||
| 6df05f4b7f | |||
| 4e1491a0cc | |||
| 55091154c4 | |||
| a0b1cb2993 | |||
| 7617081637 | |||
| 96e7f37799 | |||
| a0bf22de86 | |||
| 9a1aecc002 | |||
| ad941fcbb2 | |||
| e5ca30dc26 | |||
| a23eadf5cf | |||
| 82417f4f85 | |||
| af788133c2 | |||
| a6dc156a79 | |||
| 25bebdc172 | |||
| b55d96169f | |||
| 1a809fa7a3 | |||
| 313a5fddbe | |||
| 732d806820 | |||
| 11ed8a2f21 | |||
| 3aa8f51015 | |||
| 85b038dada | |||
| dd25527a62 | |||
| ac372bc6fc | |||
| 63ce4fe0bd | |||
| 398169f68e | |||
| 46a24af373 | |||
| 0cd9bb658f | |||
| b0678fd259 | |||
| 9cb4a1779e |
+4
-4
@@ -15,10 +15,10 @@ RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr
|
||||
|
||||
COPY . /code
|
||||
|
||||
# this .deb is specially patched to support lwjgl
|
||||
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
|
||||
RUN dpkg -i /code/scripts/xvfb_1.16.4-1_amd64.deb
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
# this .deb is specially patched to support lwjgl
|
||||
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
|
||||
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
|
||||
|
||||
RUN ./gradlew build
|
||||
+4
-6
@@ -3,6 +3,8 @@ Impact 4.4 has Baritone included.
|
||||
|
||||
These instructions apply to Impact 4.3 (and potentially other hacked clients).
|
||||
|
||||
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
|
||||
|
||||
|
||||
## An Introduction
|
||||
There are some basic steps to getting Baritone setup with Impact.
|
||||
@@ -12,7 +14,7 @@ There are some basic steps to getting Baritone setup with Impact.
|
||||
- How to use Baritone
|
||||
|
||||
## Acquiring a build of Baritone
|
||||
There are 3 methods of acquiring a build of Baritone (While it is still in development)
|
||||
There are two methods of acquiring a build of Baritone
|
||||
|
||||
### Official Release (Not always up to date)
|
||||
https://github.com/cabaletta/baritone/releases
|
||||
@@ -33,10 +35,6 @@ command line
|
||||
- Mac/Linux: ``./gradlew build``
|
||||
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
|
||||
|
||||
### Cutting Edge Release
|
||||
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
|
||||
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
|
||||
|
||||
## Placing Baritone in the libraries directory
|
||||
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
|
||||
that contains all of the dependencies that are required from the game and some mods. This is where we will be
|
||||
@@ -83,7 +81,7 @@ The final step is "registering" the Baritone library with Impact, so that it loa
|
||||
"name": "cabaletta:baritone:X.Y.Z"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.1",
|
||||
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
```
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# Baritone
|
||||
[](https://travis-ci.com/cabaletta/baritone)
|
||||
[](https://github.com/cabaletta/baritone/releases)
|
||||
[](LICENSE)
|
||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||
|
||||
<!-- Unofficial Jenkins: [](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/) -->
|
||||
[](http://hits.dwyl.com/cabaletta/baritone)
|
||||
[](https://github.com/cabaletta/baritone/issues)
|
||||
[](https://minecraft.gamepedia.com/1.12.2)
|
||||
|
||||
A Minecraft pathfinder 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. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||
|
||||
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4.
|
||||
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
||||
|
||||
Here are some links to help to get started:
|
||||
|
||||
@@ -20,29 +22,30 @@ There's also some useful information down below
|
||||
|
||||
# Setup
|
||||
|
||||
## IntelliJ's Gradle UI
|
||||
- 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
|
||||
$ gradlew runClient
|
||||
```
|
||||
|
||||
Setting up for IntelliJ:
|
||||
Building Baritone:
|
||||
```
|
||||
$ gradlew setupDecompWorkspace
|
||||
$ gradlew --refresh-dependencies
|
||||
$ gradlew genIntellijRuns
|
||||
$ gradlew build
|
||||
```
|
||||
|
||||
For example, to replace out Impact 4.4's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
|
||||
|
||||
## IntelliJ's Gradle UI
|
||||
- Open the project in IntelliJ as a Gradle project
|
||||
- Run the Gradle task `setupDecompWorkspace`
|
||||
- Run the Gradle task `genIntellijRuns`
|
||||
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||
- Select the "Minecraft Client" launch config
|
||||
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
|
||||
|
||||
# Chat control
|
||||
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '1.0.0'
|
||||
version '1.0.0-hotfix-4'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
||||
@@ -34,9 +34,9 @@ import java.util.List;
|
||||
*/
|
||||
class BaritoneGradleTask extends DefaultTask {
|
||||
|
||||
static final JsonParser PARSER = new JsonParser();
|
||||
protected static final JsonParser PARSER = new JsonParser();
|
||||
|
||||
static final String
|
||||
protected static final String
|
||||
PROGUARD_ZIP = "proguard.zip",
|
||||
PROGUARD_JAR = "proguard.jar",
|
||||
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
|
||||
@@ -54,10 +54,10 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
ARTIFACT_API = "%s-api-%s.jar",
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
|
||||
|
||||
String artifactName, artifactVersion;
|
||||
Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
||||
protected String artifactName, artifactVersion;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
||||
|
||||
void verifyArtifacts() throws Exception {
|
||||
protected void verifyArtifacts() throws IllegalStateException {
|
||||
this.artifactName = getProject().getName();
|
||||
this.artifactVersion = getProject().getVersion().toString();
|
||||
|
||||
@@ -69,34 +69,34 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
||||
|
||||
if (!Files.exists(this.artifactPath)) {
|
||||
throw new Exception("Artifact not found! Run build first!");
|
||||
throw new IllegalStateException("Artifact not found! Run build first!");
|
||||
}
|
||||
}
|
||||
|
||||
void write(InputStream stream, Path file) throws Exception {
|
||||
protected void write(InputStream stream, Path file) throws Exception {
|
||||
if (Files.exists(file)) {
|
||||
Files.delete(file);
|
||||
}
|
||||
Files.copy(stream, file);
|
||||
}
|
||||
|
||||
String formatVersion(String string) {
|
||||
protected String formatVersion(String string) {
|
||||
return String.format(string, this.artifactName, this.artifactVersion);
|
||||
}
|
||||
|
||||
Path getRelativeFile(String file) {
|
||||
protected Path getRelativeFile(String file) {
|
||||
return Paths.get(new File(file).getAbsolutePath());
|
||||
}
|
||||
|
||||
Path getTemporaryFile(String file) {
|
||||
protected Path getTemporaryFile(String file) {
|
||||
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
|
||||
}
|
||||
|
||||
Path getBuildFile(String file) {
|
||||
protected Path getBuildFile(String file) {
|
||||
return getRelativeFile("build/libs/" + file);
|
||||
}
|
||||
|
||||
JsonElement readJson(List<String> lines) {
|
||||
protected JsonElement readJson(List<String> lines) {
|
||||
return PARSER.parse(String.join("\n", lines));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
shasum.forEach(System.out::println);
|
||||
|
||||
// Write the checksums to a file
|
||||
Files.write(getRelativeFile("dist/checksums.txt"), shasum);
|
||||
}
|
||||
@@ -74,7 +76,7 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
|
||||
} catch (Exception e) {
|
||||
// haha no thanks
|
||||
throw new RuntimeException(e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
||||
int exitCode = p.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new Exception("Proguard exited with code " + exitCode);
|
||||
throw new IllegalStateException("Proguard exited with code " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.jar.JarOutputStream;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0.
|
||||
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 42069.
|
||||
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
|
||||
*
|
||||
* @author leijurv
|
||||
|
||||
Vendored
+5
@@ -13,9 +13,14 @@
|
||||
-repackageclasses 'baritone'
|
||||
|
||||
-keep class baritone.api.** { *; } # this is the keep api
|
||||
|
||||
# service provider needs these class names
|
||||
-keep class baritone.BaritoneProvider
|
||||
-keep class baritone.api.IBaritoneProvider
|
||||
|
||||
# hack
|
||||
-keep class baritone.utils.ExampleBaritoneControl { *; }
|
||||
|
||||
# setting names are reflected from field names, so keep field names
|
||||
-keepclassmembers class baritone.api.Settings {
|
||||
public <fields>;
|
||||
|
||||
@@ -376,6 +376,11 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||
*/
|
||||
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||
* <p>
|
||||
@@ -396,6 +401,18 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Integer> axisHeight = new Setting<>(120);
|
||||
|
||||
/**
|
||||
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
|
||||
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
|
||||
* couldn't. If you don't want it to look like you're X-Raying, turn this off
|
||||
*/
|
||||
public Setting<Boolean> legitMine = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* What Y level to go to for legit strip mining
|
||||
*/
|
||||
public Setting<Integer> legitMineYLevel = new Setting<>(11);
|
||||
|
||||
/**
|
||||
* When mining block of a certain type, try to mine two at once instead of one.
|
||||
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
|
||||
|
||||
@@ -105,8 +105,9 @@ public interface IPath {
|
||||
default double ticksRemainingFrom(int pathPosition) {
|
||||
double sum = 0;
|
||||
//this is fast because we aren't requesting recalculation, it's just cached
|
||||
for (int i = pathPosition; i < movements().size(); i++) {
|
||||
sum += movements().get(i).getCost();
|
||||
List<IMovement> movements = movements();
|
||||
for (int i = pathPosition; i < movements.size(); i++) {
|
||||
sum += movements.get(i).getCost();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@@ -30,14 +30,13 @@ import java.util.Optional;
|
||||
* @since 8/25/2018
|
||||
*/
|
||||
public final class RayTraceUtils {
|
||||
|
||||
private RayTraceUtils() {}
|
||||
|
||||
/**
|
||||
* The {@link Minecraft} instance
|
||||
*/
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private RayTraceUtils() {}
|
||||
|
||||
/**
|
||||
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
|
||||
* will be that of the next render pass given that the local player's yaw and
|
||||
@@ -46,7 +45,7 @@ public final class RayTraceUtils {
|
||||
* thing to achieve the desired outcome (whether it is hitting and entity or placing
|
||||
* a block) can be done just by modifying user input.
|
||||
*
|
||||
* @param yaw The yaw to raytrace with
|
||||
* @param yaw The yaw to raytrace with
|
||||
* @param pitch The pitch to raytrace with
|
||||
* @return The calculated raytrace result
|
||||
*/
|
||||
|
||||
@@ -31,8 +31,6 @@ import java.util.Optional;
|
||||
*/
|
||||
public final class RotationUtils {
|
||||
|
||||
private RotationUtils() {}
|
||||
|
||||
/**
|
||||
* The {@link Minecraft} instance
|
||||
*/
|
||||
@@ -60,6 +58,8 @@ public final class RotationUtils {
|
||||
new Vec3d(1, 0.5, 0.5) // East
|
||||
};
|
||||
|
||||
private RotationUtils() {}
|
||||
|
||||
/**
|
||||
* Clamps the specified pitch value between -90 and 90.
|
||||
*
|
||||
@@ -177,6 +177,8 @@ public final class RotationUtils {
|
||||
* is by setting the desired pitch to the current pitch
|
||||
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
|
||||
* just what it currently is
|
||||
*
|
||||
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
|
||||
*/
|
||||
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
||||
}
|
||||
@@ -218,10 +220,8 @@ public final class RotationUtils {
|
||||
if (result.getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire) {
|
||||
if (result.getBlockPos().equals(pos.down())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
|
||||
@@ -30,21 +30,19 @@ import net.minecraft.util.math.Vec3d;
|
||||
* @since 10/13/2018
|
||||
*/
|
||||
public final class VecUtils {
|
||||
|
||||
private VecUtils() {}
|
||||
|
||||
/**
|
||||
* The {@link Minecraft} instance
|
||||
*/
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private VecUtils() {}
|
||||
|
||||
/**
|
||||
* Calculates the center of the block at the specified position's bounding box
|
||||
*
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*
|
||||
* @param pos The block position
|
||||
* @return The center of the block's bounding box
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static Vec3d calculateBlockCenter(BlockPos pos) {
|
||||
IBlockState b = mc.world.getBlockState(pos);
|
||||
@@ -68,10 +66,9 @@ public final class VecUtils {
|
||||
* <p>
|
||||
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
|
||||
*
|
||||
* @see #calculateBlockCenter(BlockPos)
|
||||
*
|
||||
* @param pos The block position
|
||||
* @return The assumed center of the position
|
||||
* @see #calculateBlockCenter(BlockPos)
|
||||
*/
|
||||
public static Vec3d getBlockPosCenter(BlockPos pos) {
|
||||
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||
@@ -80,19 +77,17 @@ public final class VecUtils {
|
||||
/**
|
||||
* Gets the distance from the specified position to the assumed center of the specified block position.
|
||||
*
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*
|
||||
* @param pos The block position
|
||||
* @param x The x pos
|
||||
* @param y The y pos
|
||||
* @param z The z pos
|
||||
* @param x The x pos
|
||||
* @param y The y pos
|
||||
* @param z The z pos
|
||||
* @return The distance from the assumed block center to the position
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
|
||||
Vec3d center = getBlockPosCenter(pos);
|
||||
double xdiff = x - center.x;
|
||||
double ydiff = y - center.y;
|
||||
double zdiff = z - center.z;
|
||||
double xdiff = pos.getX() + 0.5 - x;
|
||||
double ydiff = pos.getY() + 0.5 - y;
|
||||
double zdiff = pos.getZ() + 0.5 - z;
|
||||
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
||||
}
|
||||
|
||||
@@ -100,11 +95,10 @@ public final class VecUtils {
|
||||
* Gets the distance from the specified entity's position to the assumed
|
||||
* center of the specified block position.
|
||||
*
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*
|
||||
* @param entity The entity
|
||||
* @param pos The block position
|
||||
* @param pos The block position
|
||||
* @return The distance from the entity to the block's assumed center
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
|
||||
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
|
||||
@@ -114,11 +108,10 @@ public final class VecUtils {
|
||||
* Gets the distance from the specified entity's position to the assumed
|
||||
* center of the specified block position, ignoring the Y axis.
|
||||
*
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*
|
||||
* @param entity The entity
|
||||
* @param pos The block position
|
||||
* @param pos The block position
|
||||
* @return The horizontal distance from the entity to the block's assumed center
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
|
||||
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
|
||||
|
||||
@@ -40,6 +40,8 @@ public class MixinEntityLivingBase {
|
||||
)
|
||||
private void preJump(CallbackInfo ci) {
|
||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
||||
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
|
||||
// but proguard isn't smart enough to optimize out this Class.isInstance =)
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
|
||||
}
|
||||
@@ -50,6 +52,7 @@ public class MixinEntityLivingBase {
|
||||
)
|
||||
private void postJump(CallbackInfo ci) {
|
||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
||||
// See above
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
|
||||
}
|
||||
|
||||
@@ -21,10 +21,13 @@ import baritone.Baritone;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.player.PlayerCapabilities;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
@@ -72,4 +75,16 @@ public class MixinEntityPlayerSP {
|
||||
private void onPostUpdate(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
||||
)
|
||||
)
|
||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
|
||||
return (!pathingBehavior.isEnabled() || !pathingBehavior.isPathing()) && capabilities.allowFlying;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ 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.PathingBehavior;
|
||||
import baritone.utils.BaritoneAutoTest;
|
||||
import baritone.utils.ExampleBaritoneControl;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@@ -49,8 +47,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft {
|
||||
|
||||
@Shadow
|
||||
private int leftClickCounter;
|
||||
@Shadow
|
||||
public EntityPlayerSP player;
|
||||
@Shadow
|
||||
@@ -62,7 +58,6 @@ public class MixinMinecraft {
|
||||
)
|
||||
private void postInit(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.init();
|
||||
ExampleBaritoneControl.INSTANCE.initAndRegister();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -147,7 +142,7 @@ public class MixinMinecraft {
|
||||
)
|
||||
)
|
||||
private boolean isAllowUserInput(GuiScreen screen) {
|
||||
return (PathingBehavior.INSTANCE.getCurrent() != null && PathingBehavior.INSTANCE.isEnabled() && player != null) || screen.allowUserInput;
|
||||
return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && Baritone.INSTANCE.getPathingBehavior().isEnabled() && player != null) || screen.allowUserInput;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
package baritone;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritoneProvider;
|
||||
import baritone.api.Settings;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.event.GameEventHandler;
|
||||
import baritone.utils.BaritoneAutoTest;
|
||||
import baritone.utils.ExampleBaritoneControl;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
@@ -40,7 +44,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* @author Brady
|
||||
* @since 7/31/2018 10:50 PM
|
||||
*/
|
||||
public enum Baritone {
|
||||
public enum Baritone implements IBaritoneProvider {
|
||||
|
||||
/**
|
||||
* Singleton instance of this class
|
||||
@@ -55,10 +59,16 @@ public enum Baritone {
|
||||
private GameEventHandler gameEventHandler;
|
||||
private InputOverrideHandler inputOverrideHandler;
|
||||
private Settings settings;
|
||||
private List<Behavior> behaviors;
|
||||
private File dir;
|
||||
private ThreadPoolExecutor threadPool;
|
||||
|
||||
private List<Behavior> behaviors;
|
||||
private PathingBehavior pathingBehavior;
|
||||
private LookBehavior lookBehavior;
|
||||
private MemoryBehavior memoryBehavior;
|
||||
private FollowBehavior followBehavior;
|
||||
private MineBehavior mineBehavior;
|
||||
|
||||
/**
|
||||
* Whether or not Baritone is active
|
||||
*/
|
||||
@@ -81,12 +91,13 @@ public enum Baritone {
|
||||
|
||||
this.behaviors = new ArrayList<>();
|
||||
{
|
||||
registerBehavior(PathingBehavior.INSTANCE);
|
||||
registerBehavior(LookBehavior.INSTANCE);
|
||||
registerBehavior(MemoryBehavior.INSTANCE);
|
||||
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
||||
registerBehavior(FollowBehavior.INSTANCE);
|
||||
registerBehavior(MineBehavior.INSTANCE);
|
||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||
pathingBehavior = new PathingBehavior(this);
|
||||
lookBehavior = new LookBehavior(this);
|
||||
memoryBehavior = new MemoryBehavior(this);
|
||||
followBehavior = new FollowBehavior(this);
|
||||
mineBehavior = new MineBehavior(this);
|
||||
new ExampleBaritoneControl(this);
|
||||
}
|
||||
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
||||
registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||
@@ -127,6 +138,42 @@ public enum Baritone {
|
||||
this.registerEventListener(behavior);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FollowBehavior getFollowBehavior() {
|
||||
return followBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookBehavior getLookBehavior() {
|
||||
return lookBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryBehavior getMemoryBehavior() {
|
||||
return memoryBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MineBehavior getMineBehavior() {
|
||||
return mineBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingBehavior getPathingBehavior() {
|
||||
return pathingBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldProvider getWorldProvider() {
|
||||
return WorldProvider.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldScanner getWorldScanner() {
|
||||
return WorldScanner.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEventListener(IGameEventListener listener) {
|
||||
this.gameEventHandler.registerEventListener(listener);
|
||||
}
|
||||
|
||||
@@ -22,11 +22,12 @@ import baritone.api.behavior.*;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.cache.WorldScanner;
|
||||
|
||||
/**
|
||||
* todo fix this cancer
|
||||
*
|
||||
* @author Brady
|
||||
* @since 9/29/2018
|
||||
*/
|
||||
@@ -34,27 +35,27 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
||||
|
||||
@Override
|
||||
public IFollowBehavior getFollowBehavior() {
|
||||
return FollowBehavior.INSTANCE;
|
||||
return Baritone.INSTANCE.getFollowBehavior();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILookBehavior getLookBehavior() {
|
||||
return LookBehavior.INSTANCE;
|
||||
return Baritone.INSTANCE.getLookBehavior();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMemoryBehavior getMemoryBehavior() {
|
||||
return MemoryBehavior.INSTANCE;
|
||||
return Baritone.INSTANCE.getMemoryBehavior();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMineBehavior getMineBehavior() {
|
||||
return MineBehavior.INSTANCE;
|
||||
return Baritone.INSTANCE.getMineBehavior();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPathingBehavior getPathingBehavior() {
|
||||
return PathingBehavior.INSTANCE;
|
||||
return Baritone.INSTANCE.getPathingBehavior();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IBehavior;
|
||||
|
||||
/**
|
||||
@@ -27,11 +28,18 @@ import baritone.api.behavior.IBehavior;
|
||||
*/
|
||||
public class Behavior implements IBehavior {
|
||||
|
||||
public final Baritone baritone;
|
||||
|
||||
/**
|
||||
* Whether or not this behavior is enabled
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
protected Behavior(Baritone baritone) {
|
||||
this.baritone = baritone;
|
||||
baritone.registerBehavior(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the enabled state of this {@link Behavior}.
|
||||
*
|
||||
|
||||
@@ -33,11 +33,11 @@ import net.minecraft.util.math.BlockPos;
|
||||
*/
|
||||
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
|
||||
|
||||
public static final FollowBehavior INSTANCE = new FollowBehavior();
|
||||
|
||||
private Entity following;
|
||||
|
||||
private FollowBehavior() {}
|
||||
public FollowBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
@@ -56,9 +56,9 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
|
||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
||||
}
|
||||
PathingBehavior.INSTANCE.setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
|
||||
PathingBehavior.INSTANCE.revalidateGoal();
|
||||
PathingBehavior.INSTANCE.path();
|
||||
baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
|
||||
((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
|
||||
baritone.getPathingBehavior().path();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,7 +73,7 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
baritone.getPathingBehavior().cancel();
|
||||
follow(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.BlockBed;
|
||||
|
||||
/**
|
||||
* A collection of event methods that are used to interact with Baritone's
|
||||
* waypoint system. This class probably needs a better name.
|
||||
*
|
||||
* @see Waypoint
|
||||
*
|
||||
* @author Brady
|
||||
* @since 8/22/2018
|
||||
*/
|
||||
public final class LocationTrackingBehavior extends Behavior implements Helper {
|
||||
|
||||
public static final LocationTrackingBehavior INSTANCE = new LocationTrackingBehavior();
|
||||
|
||||
private LocationTrackingBehavior() {}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,6 @@ import baritone.api.utils.Rotation;
|
||||
import baritone.utils.Helper;
|
||||
|
||||
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
||||
|
||||
public static final LookBehavior INSTANCE = new LookBehavior();
|
||||
|
||||
/**
|
||||
* Target's values are as follows:
|
||||
* <p>
|
||||
@@ -49,7 +46,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
||||
*/
|
||||
private float lastYaw;
|
||||
|
||||
private LookBehavior() {}
|
||||
public LookBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTarget(Rotation target, boolean force) {
|
||||
|
||||
@@ -17,14 +17,19 @@
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IMemoryBehavior;
|
||||
import baritone.api.behavior.memory.IRememberedInventory;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||
@@ -43,11 +48,11 @@ import java.util.*;
|
||||
*/
|
||||
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
|
||||
|
||||
public static MemoryBehavior INSTANCE = new MemoryBehavior();
|
||||
|
||||
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
|
||||
|
||||
private MemoryBehavior() {}
|
||||
public MemoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||
@@ -114,6 +119,18 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
||||
}
|
||||
|
||||
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
||||
return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
|
||||
}
|
||||
|
||||
@@ -20,21 +20,23 @@ package baritone.behavior;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IMineBehavior;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.pathing.goals.GoalTwoBlocks;
|
||||
import baritone.api.pathing.goals.*;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.cache.CachedChunk;
|
||||
import baritone.cache.ChunkPacker;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
@@ -46,14 +48,15 @@ import java.util.stream.Collectors;
|
||||
* @author leijurv
|
||||
*/
|
||||
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
||||
|
||||
public static final MineBehavior INSTANCE = new MineBehavior();
|
||||
|
||||
public static final int ORE_LOCATIONS_COUNT = 64;
|
||||
private List<Block> mining;
|
||||
private List<BlockPos> locationsCache;
|
||||
private int quantity;
|
||||
private List<BlockPos> knownOreLocations;
|
||||
private BlockPos branchPoint;
|
||||
private int desiredQuantity;
|
||||
|
||||
private MineBehavior() {}
|
||||
public MineBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
@@ -64,53 +67,80 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
if (mining == null) {
|
||||
return;
|
||||
}
|
||||
if (quantity > 0) {
|
||||
if (desiredQuantity > 0) {
|
||||
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
|
||||
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
|
||||
System.out.println("Currently have " + curr + " " + item);
|
||||
if (curr >= quantity) {
|
||||
if (curr >= desiredQuantity) {
|
||||
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||
if (mineGoalUpdateInterval != 0) {
|
||||
if (event.getCount() % mineGoalUpdateInterval == 0) {
|
||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
||||
}
|
||||
if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
|
||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
||||
}
|
||||
if (Baritone.settings().legitMine.get()) {
|
||||
addNearby();
|
||||
}
|
||||
updateGoal();
|
||||
PathingBehavior.INSTANCE.revalidateGoal();
|
||||
baritone.getPathingBehavior().revalidateGoal();
|
||||
}
|
||||
|
||||
private void updateGoal() {
|
||||
if (mining == null) {
|
||||
if (mining == null || world() == null || player() == null) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = locationsCache;
|
||||
List<BlockPos> locs = knownOreLocations;
|
||||
if (!locs.isEmpty()) {
|
||||
locs = prune(new ArrayList<>(locs), mining, 64);
|
||||
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
|
||||
PathingBehavior.INSTANCE.path();
|
||||
locationsCache = locs;
|
||||
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, world());
|
||||
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
|
||||
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
|
||||
knownOreLocations = locs2;
|
||||
return;
|
||||
}
|
||||
// we don't know any ore locations at the moment
|
||||
if (!Baritone.settings().legitMine.get()) {
|
||||
return;
|
||||
}
|
||||
// only in non-Xray mode (aka legit mode) do we do this
|
||||
if (branchPoint == null) {
|
||||
int y = Baritone.settings().legitMineYLevel.get();
|
||||
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
||||
// cool, path is over and we are at desired y
|
||||
branchPoint = playerFeet();
|
||||
} else {
|
||||
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (playerFeet().equals(branchPoint)) {
|
||||
// TODO mine 1x1 shafts to either side
|
||||
branchPoint = branchPoint.north(10);
|
||||
}
|
||||
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
|
||||
}
|
||||
|
||||
private void rescan() {
|
||||
if (mining == null) {
|
||||
if (mining == null || world() == null || player() == null) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = scanFor(mining, 64);
|
||||
if (Baritone.settings().legitMine.get()) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
|
||||
locs.addAll(droppedItemsScan(mining, world()));
|
||||
if (locs.isEmpty()) {
|
||||
logDebug("No locations for " + mining + " known, cancelling");
|
||||
mine(0, (String[]) null);
|
||||
return;
|
||||
}
|
||||
locationsCache = locs;
|
||||
knownOreLocations = locs;
|
||||
}
|
||||
|
||||
public Goal coalesce(BlockPos loc, List<BlockPos> locs) {
|
||||
private static Goal coalesce(BlockPos loc, List<BlockPos> locs) {
|
||||
if (!Baritone.settings().forceInternalMining.get()) {
|
||||
return new GoalTwoBlocks(loc);
|
||||
}
|
||||
@@ -132,11 +162,30 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
}
|
||||
}
|
||||
|
||||
public GoalComposite coalesce(List<BlockPos> locs) {
|
||||
return new GoalComposite(locs.stream().map(loc -> coalesce(loc, locs)).toArray(Goal[]::new));
|
||||
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
|
||||
if (!Baritone.settings().mineScanDroppedItems.get()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Set<Item> searchingFor = new HashSet<>();
|
||||
for (Block block : mining) {
|
||||
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
|
||||
Item ore = Item.getItemFromBlock(block);
|
||||
searchingFor.add(drop);
|
||||
searchingFor.add(ore);
|
||||
}
|
||||
List<BlockPos> ret = new ArrayList<>();
|
||||
for (Entity entity : world.loadedEntityList) {
|
||||
if (entity instanceof EntityItem) {
|
||||
EntityItem ei = (EntityItem) entity;
|
||||
if (searchingFor.contains(ei.getItem().getItem())) {
|
||||
ret.add(entity.getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<BlockPos> scanFor(List<Block> mining, int max) {
|
||||
public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
|
||||
List<BlockPos> locs = new ArrayList<>();
|
||||
List<Block> uninteresting = new ArrayList<>();
|
||||
//long b = System.currentTimeMillis();
|
||||
@@ -156,29 +205,59 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
|
||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||
}
|
||||
return prune(locs, mining, max);
|
||||
return prune(locs, mining, max, world);
|
||||
}
|
||||
|
||||
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
|
||||
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
|
||||
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
||||
public void addNearby() {
|
||||
BlockPos playerFeet = playerFeet();
|
||||
int searchDist = 4;//why four? idk
|
||||
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
||||
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
|
||||
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
if (mining.contains(BlockStateInterface.getBlock(pos)) && RotationUtils.reachable(player(), pos).isPresent()) {//crucial to only add blocks we can see because otherwise this is an x-ray and it'll get caught
|
||||
knownOreLocations.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
|
||||
}
|
||||
|
||||
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max, World world) {
|
||||
List<BlockPos> dropped = droppedItemsScan(mining, world);
|
||||
List<BlockPos> locs = locs2
|
||||
.stream()
|
||||
|
||||
// remove any that are within loaded chunks that aren't actually what we want
|
||||
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
|
||||
|
||||
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
||||
.filter(MineBehavior::plausibleToBreak)
|
||||
|
||||
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 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(BlockStateInterface.get(pos).getBlock()))
|
||||
.collect(Collectors.toList()));
|
||||
if (locs.size() > max) {
|
||||
return locs.subList(0, max);
|
||||
}
|
||||
return locs;
|
||||
}
|
||||
|
||||
public static boolean plausibleToBreak(BlockPos pos) {
|
||||
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
|
||||
return false;
|
||||
}
|
||||
// bedrock above and below makes it implausible, otherwise we're good
|
||||
return !(BlockStateInterface.getBlock(pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(pos.down()) == Blocks.BEDROCK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mine(int quantity, String... blocks) {
|
||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
|
||||
this.quantity = quantity;
|
||||
this.locationsCache = new ArrayList<>();
|
||||
this.desiredQuantity = quantity;
|
||||
this.knownOreLocations = new ArrayList<>();
|
||||
this.branchPoint = null;
|
||||
rescan();
|
||||
updateGoal();
|
||||
}
|
||||
@@ -186,8 +265,9 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
@Override
|
||||
public void mine(int quantity, Block... blocks) {
|
||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
|
||||
this.quantity = quantity;
|
||||
this.locationsCache = new ArrayList<>();
|
||||
this.desiredQuantity = quantity;
|
||||
this.knownOreLocations = new ArrayList<>();
|
||||
this.branchPoint = null;
|
||||
rescan();
|
||||
updateGoal();
|
||||
}
|
||||
@@ -195,6 +275,6 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
@Override
|
||||
public void cancel() {
|
||||
mine(0, (String[]) null);
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
baritone.getPathingBehavior().cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,21 +32,23 @@ import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import baritone.pathing.calc.AStarPathFinder;
|
||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||
import baritone.pathing.calc.CutoffPath;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.utils.BlockBreakHelper;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.PathRenderer;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
|
||||
|
||||
public static final PathingBehavior INSTANCE = new PathingBehavior();
|
||||
|
||||
private PathExecutor current;
|
||||
private PathExecutor next;
|
||||
|
||||
@@ -59,29 +61,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
|
||||
private boolean lastAutoJump;
|
||||
|
||||
private PathingBehavior() {}
|
||||
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
|
||||
|
||||
private void dispatchPathEvent(PathEvent event) {
|
||||
Baritone.INSTANCE.getExecutor().execute(() -> Baritone.INSTANCE.getGameEventHandler().onPathEvent(event));
|
||||
public PathingBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
private void queuePathEvent(PathEvent event) {
|
||||
toDispatch.add(event);
|
||||
}
|
||||
|
||||
private void dispatchEvents() {
|
||||
ArrayList<PathEvent> curr = new ArrayList<>();
|
||||
toDispatch.drainTo(curr);
|
||||
for (PathEvent event : curr) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
dispatchEvents();
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
this.cancel();
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
mc.playerController.setPlayerCapabilities(mc.player);
|
||||
tickPath();
|
||||
dispatchEvents();
|
||||
}
|
||||
|
||||
private void tickPath() {
|
||||
if (current == null) {
|
||||
return;
|
||||
}
|
||||
boolean safe = current.onTick(event);
|
||||
boolean safe = current.onTick();
|
||||
synchronized (pathPlanLock) {
|
||||
if (current.failed() || current.finished()) {
|
||||
current = null;
|
||||
if (goal == null || goal.isInGoal(playerFeet())) {
|
||||
logDebug("All done. At " + goal);
|
||||
dispatchPathEvent(PathEvent.AT_GOAL);
|
||||
queuePathEvent(PathEvent.AT_GOAL);
|
||||
next = null;
|
||||
return;
|
||||
}
|
||||
@@ -93,43 +112,38 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
// but if we fail in the middle of current
|
||||
// we're nowhere close to our planned ahead path
|
||||
// so need to discard it sadly.
|
||||
dispatchPathEvent(PathEvent.DISCARD_NEXT);
|
||||
queuePathEvent(PathEvent.DISCARD_NEXT);
|
||||
next = null;
|
||||
}
|
||||
if (next != null) {
|
||||
logDebug("Continuing on to planned next path");
|
||||
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
||||
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick(event);
|
||||
current.onTick();
|
||||
return;
|
||||
}
|
||||
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
dispatchPathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
dispatchPathEvent(PathEvent.CALC_STARTED);
|
||||
queuePathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// at this point, we know current is in progress
|
||||
if (safe) {
|
||||
// a movement just ended
|
||||
if (next != null) {
|
||||
if (next.snipsnapifpossible()) {
|
||||
// jump directly onto the next path
|
||||
logDebug("Splicing into planned next path early...");
|
||||
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (safe && next != null && player().onGround && next.snipsnapifpossible()) {
|
||||
// a movement just ended; jump directly onto the next path
|
||||
logDebug("Splicing into planned next path early...");
|
||||
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick();
|
||||
return;
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
@@ -147,7 +161,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
|
||||
// and this path has 5 seconds or less left
|
||||
logDebug("Path almost over. Planning ahead...");
|
||||
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
|
||||
}
|
||||
}
|
||||
@@ -184,6 +198,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
this.goal = goal;
|
||||
}
|
||||
|
||||
public boolean setGoalAndPath(Goal goal) {
|
||||
setGoal(goal);
|
||||
return path();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
@@ -211,7 +230,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
dispatchPathEvent(PathEvent.CANCELED);
|
||||
queuePathEvent(PathEvent.CANCELED);
|
||||
current = null;
|
||||
next = null;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
@@ -244,7 +263,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
if (isPathCalcInProgress) {
|
||||
return false;
|
||||
}
|
||||
dispatchPathEvent(PathEvent.CALC_STARTED);
|
||||
queuePathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
||||
return true;
|
||||
}
|
||||
@@ -309,12 +328,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
isPathCalcInProgress = true;
|
||||
}
|
||||
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
||||
if (talkAboutIt) {
|
||||
logDebug("Starting to search for path from " + start + " to " + goal);
|
||||
}
|
||||
|
||||
Optional<IPath> path = findPath(start, previous);
|
||||
Optional<IPath> path = findPath(start, previous, context);
|
||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
||||
path = path.map(p -> {
|
||||
IPath result = p.cutoffAtLoadedChunks();
|
||||
@@ -343,18 +363,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
synchronized (pathPlanLock) {
|
||||
if (current == null) {
|
||||
if (executor.isPresent()) {
|
||||
dispatchPathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||
current = executor.get();
|
||||
} else {
|
||||
dispatchPathEvent(PathEvent.CALC_FAILED);
|
||||
queuePathEvent(PathEvent.CALC_FAILED);
|
||||
}
|
||||
} else {
|
||||
if (next == null) {
|
||||
if (executor.isPresent()) {
|
||||
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
||||
next = executor.get();
|
||||
} else {
|
||||
dispatchPathEvent(PathEvent.NEXT_CALC_FAILED);
|
||||
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("I have no idea what to do with this path");
|
||||
@@ -382,19 +402,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
* @param start
|
||||
* @return
|
||||
*/
|
||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) {
|
||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
|
||||
Goal goal = this.goal;
|
||||
if (goal == null) {
|
||||
logDebug("no goal");
|
||||
return Optional.empty();
|
||||
}
|
||||
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
|
||||
BlockPos pos = null;
|
||||
if (goal instanceof IGoalRenderPos) {
|
||||
pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||
}
|
||||
|
||||
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
|
||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||
if (world().getChunk(pos) instanceof EmptyChunk) {
|
||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||
goal = new GoalXZ(pos.getX(), pos.getZ());
|
||||
}
|
||||
@@ -405,14 +421,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
} else {
|
||||
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
||||
}
|
||||
Optional<HashSet<Long>> favoredPositions;
|
||||
if (Baritone.settings().backtrackCostFavoringCoefficient.get() == 1D) {
|
||||
favoredPositions = Optional.empty();
|
||||
} else {
|
||||
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
|
||||
Optional<LongOpenHashSet> favoredPositions = Optional.empty();
|
||||
if (Baritone.settings().backtrackCostFavoringCoefficient.get() != 1D && previous.isPresent()) {
|
||||
LongOpenHashSet tmp = new LongOpenHashSet();
|
||||
previous.get().positions().forEach(pos -> tmp.add(BetterBlockPos.longHash(pos)));
|
||||
favoredPositions = Optional.of(tmp);
|
||||
}
|
||||
try {
|
||||
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions);
|
||||
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions, context);
|
||||
return pf.calculate(timeout);
|
||||
} catch (Exception e) {
|
||||
logDebug("Pathing exception: " + e);
|
||||
|
||||
+55
-33
@@ -33,40 +33,62 @@ import java.util.*;
|
||||
*/
|
||||
public final class CachedChunk implements IBlockTypeAccess, Helper {
|
||||
|
||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(new HashSet<Block>() {{
|
||||
add(Blocks.DIAMOND_ORE);
|
||||
add(Blocks.DIAMOND_BLOCK);
|
||||
//add(Blocks.COAL_ORE);
|
||||
add(Blocks.COAL_BLOCK);
|
||||
//add(Blocks.IRON_ORE);
|
||||
add(Blocks.IRON_BLOCK);
|
||||
//add(Blocks.GOLD_ORE);
|
||||
add(Blocks.GOLD_BLOCK);
|
||||
add(Blocks.EMERALD_ORE);
|
||||
add(Blocks.EMERALD_BLOCK);
|
||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
||||
|
||||
add(Blocks.ENDER_CHEST);
|
||||
add(Blocks.FURNACE);
|
||||
add(Blocks.CHEST);
|
||||
add(Blocks.END_PORTAL);
|
||||
add(Blocks.END_PORTAL_FRAME);
|
||||
add(Blocks.MOB_SPAWNER);
|
||||
// TODO add all shulker colors
|
||||
add(Blocks.PORTAL);
|
||||
add(Blocks.HOPPER);
|
||||
add(Blocks.BEACON);
|
||||
add(Blocks.BREWING_STAND);
|
||||
add(Blocks.SKULL);
|
||||
add(Blocks.ENCHANTING_TABLE);
|
||||
add(Blocks.ANVIL);
|
||||
add(Blocks.LIT_FURNACE);
|
||||
add(Blocks.BED);
|
||||
add(Blocks.DRAGON_EGG);
|
||||
add(Blocks.JUKEBOX);
|
||||
add(Blocks.END_GATEWAY);
|
||||
add(Blocks.WEB);
|
||||
add(Blocks.NETHER_WART);
|
||||
}});
|
||||
static {
|
||||
HashSet<Block> temp = new HashSet<>();
|
||||
temp.add(Blocks.DIAMOND_ORE);
|
||||
temp.add(Blocks.DIAMOND_BLOCK);
|
||||
//temp.add(Blocks.COAL_ORE);
|
||||
temp.add(Blocks.COAL_BLOCK);
|
||||
//temp.add(Blocks.IRON_ORE);
|
||||
temp.add(Blocks.IRON_BLOCK);
|
||||
//temp.add(Blocks.GOLD_ORE);
|
||||
temp.add(Blocks.GOLD_BLOCK);
|
||||
temp.add(Blocks.EMERALD_ORE);
|
||||
temp.add(Blocks.EMERALD_BLOCK);
|
||||
|
||||
temp.add(Blocks.ENDER_CHEST);
|
||||
temp.add(Blocks.FURNACE);
|
||||
temp.add(Blocks.CHEST);
|
||||
temp.add(Blocks.TRAPPED_CHEST);
|
||||
temp.add(Blocks.END_PORTAL);
|
||||
temp.add(Blocks.END_PORTAL_FRAME);
|
||||
temp.add(Blocks.MOB_SPAWNER);
|
||||
temp.add(Blocks.BARRIER);
|
||||
temp.add(Blocks.OBSERVER);
|
||||
temp.add(Blocks.WHITE_SHULKER_BOX);
|
||||
temp.add(Blocks.ORANGE_SHULKER_BOX);
|
||||
temp.add(Blocks.MAGENTA_SHULKER_BOX);
|
||||
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.YELLOW_SHULKER_BOX);
|
||||
temp.add(Blocks.LIME_SHULKER_BOX);
|
||||
temp.add(Blocks.PINK_SHULKER_BOX);
|
||||
temp.add(Blocks.GRAY_SHULKER_BOX);
|
||||
temp.add(Blocks.SILVER_SHULKER_BOX);
|
||||
temp.add(Blocks.CYAN_SHULKER_BOX);
|
||||
temp.add(Blocks.PURPLE_SHULKER_BOX);
|
||||
temp.add(Blocks.BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.BROWN_SHULKER_BOX);
|
||||
temp.add(Blocks.GREEN_SHULKER_BOX);
|
||||
temp.add(Blocks.RED_SHULKER_BOX);
|
||||
temp.add(Blocks.BLACK_SHULKER_BOX);
|
||||
temp.add(Blocks.PORTAL);
|
||||
temp.add(Blocks.HOPPER);
|
||||
temp.add(Blocks.BEACON);
|
||||
temp.add(Blocks.BREWING_STAND);
|
||||
temp.add(Blocks.SKULL);
|
||||
temp.add(Blocks.ENCHANTING_TABLE);
|
||||
temp.add(Blocks.ANVIL);
|
||||
temp.add(Blocks.LIT_FURNACE);
|
||||
temp.add(Blocks.BED);
|
||||
temp.add(Blocks.DRAGON_EGG);
|
||||
temp.add(Blocks.JUKEBOX);
|
||||
temp.add(Blocks.END_GATEWAY);
|
||||
temp.add(Blocks.WEB);
|
||||
temp.add(Blocks.NETHER_WART);
|
||||
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the chunk data in bits. Equal to 16 KiB.
|
||||
|
||||
@@ -167,6 +167,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
private synchronized void prune() {
|
||||
BlockPos pruneCenter = guessPosition();
|
||||
for (CachedRegion region : allRegions()) {
|
||||
if (region == null) {
|
||||
continue;
|
||||
}
|
||||
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
|
||||
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
|
||||
double dist = Math.sqrt(distX * distX + distZ * distZ);
|
||||
@@ -187,6 +190,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
}
|
||||
CachedChunk mostRecentlyModified = null;
|
||||
for (CachedRegion region : allRegions()) {
|
||||
if (region == null) {
|
||||
continue;
|
||||
}
|
||||
CachedChunk ch = region.mostRecentlyModified();
|
||||
if (ch == null) {
|
||||
continue;
|
||||
|
||||
+6
-3
@@ -40,6 +40,8 @@ import java.util.*;
|
||||
*/
|
||||
public final class ChunkPacker implements Helper {
|
||||
|
||||
private static final Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
private ChunkPacker() {}
|
||||
|
||||
public static CachedChunk pack(Chunk chunk) {
|
||||
@@ -93,7 +95,8 @@ public final class ChunkPacker implements Helper {
|
||||
|
||||
for (int z = 0; z < 16; z++) {
|
||||
// @formatter:off
|
||||
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
||||
https:
|
||||
//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
||||
// @formatter:on
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 255; y >= 0; y--) {
|
||||
@@ -120,12 +123,12 @@ public final class ChunkPacker implements Helper {
|
||||
}
|
||||
|
||||
public static Block stringToBlock(String name) {
|
||||
return Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
|
||||
}
|
||||
|
||||
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block.equals(Blocks.WATER)) {
|
||||
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
|
||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.pathing.BetterWorldBorder;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@@ -40,11 +40,13 @@ import java.util.Optional;
|
||||
*/
|
||||
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
|
||||
private final Optional<HashSet<Long>> favoredPositions;
|
||||
private final Optional<LongOpenHashSet> favoredPositions;
|
||||
private final CalculationContext calcContext;
|
||||
|
||||
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions) {
|
||||
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<LongOpenHashSet> favoredPositions, CalculationContext context) {
|
||||
super(startX, startY, startZ, goal);
|
||||
this.favoredPositions = favoredPositions;
|
||||
this.calcContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,11 +63,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
||||
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
|
||||
bestSoFar[i] = startNode;
|
||||
}
|
||||
CalculationContext calcContext = new CalculationContext();
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
HashSet<Long> favored = favoredPositions.orElse(null);
|
||||
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
|
||||
BlockStateInterface.clearCachedChunk();
|
||||
LongOpenHashSet favored = favoredPositions.orElse(null);
|
||||
long startTime = System.nanoTime() / 1000000L;
|
||||
boolean slowPath = Baritone.settings().slowPath.get();
|
||||
if (slowPath) {
|
||||
@@ -99,14 +100,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
||||
for (Moves moves : Moves.values()) {
|
||||
int newX = currentNode.x + moves.xOffset;
|
||||
int newZ = currentNode.z + moves.zOffset;
|
||||
if (newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) {
|
||||
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !BlockStateInterface.isLoaded(newX, newZ)) {
|
||||
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
|
||||
if (!BlockStateInterface.isLoaded(newX, newZ)) {
|
||||
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
||||
numEmptyChunk++;
|
||||
}
|
||||
continue;
|
||||
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
||||
numEmptyChunk++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
|
||||
continue;
|
||||
@@ -132,7 +131,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||
}
|
||||
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
|
||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
||||
}
|
||||
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||
if (favoring && favored.contains(hashCode)) {
|
||||
|
||||
@@ -48,11 +48,7 @@ public class CalculationContext implements Helper {
|
||||
private final BetterWorldBorder worldBorder;
|
||||
|
||||
public CalculationContext() {
|
||||
this(new ToolSet());
|
||||
}
|
||||
|
||||
public CalculationContext(ToolSet toolSet) {
|
||||
this.toolSet = toolSet;
|
||||
this.toolSet = new ToolSet();
|
||||
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.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
|
||||
@@ -87,10 +83,7 @@ public class CalculationContext implements Helper {
|
||||
if (!allowBreak()) {
|
||||
return false;
|
||||
}
|
||||
if (isPossiblyProtected(x, y, z)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return !isPossiblyProtected(x, y, z);
|
||||
}
|
||||
|
||||
public boolean isPossiblyProtected(int x, int y, int z) {
|
||||
|
||||
@@ -20,16 +20,13 @@ package baritone.pathing.movement;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.pathing.movement.MovementStatus;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.VecUtils;
|
||||
import baritone.behavior.LookBehavior;
|
||||
import baritone.api.utils.*;
|
||||
import baritone.utils.BlockBreakHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
@@ -37,6 +34,7 @@ import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static baritone.utils.InputOverrideHandler.Input;
|
||||
@@ -115,9 +113,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
||||
*/
|
||||
@Override
|
||||
public MovementStatus update() {
|
||||
player().capabilities.allowFlying = false;
|
||||
player().capabilities.isFlying = false;
|
||||
MovementState latestState = updateState(currentState);
|
||||
if (BlockStateInterface.isLiquid(playerFeet())) {
|
||||
if (MovementHelper.isLiquid(playerFeet())) {
|
||||
latestState.setInput(Input.JUMP, true);
|
||||
}
|
||||
if (player().isEntityInsideOpaqueBlock()) {
|
||||
@@ -126,7 +124,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
||||
|
||||
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
|
||||
latestState.getTarget().getRotation().ifPresent(rotation ->
|
||||
LookBehavior.INSTANCE.updateTarget(
|
||||
Baritone.INSTANCE.getLookBehavior().updateTarget(
|
||||
rotation,
|
||||
latestState.getTarget().hasToForceRotations()));
|
||||
|
||||
@@ -178,7 +176,10 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
||||
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
|
||||
if (reachable.isPresent()) {
|
||||
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));
|
||||
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), blockPos) || BlockStateInterface.getBlock(blockPos) == Blocks.FIRE) {
|
||||
state.setInput(Input.CLICK_LEFT, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//get rekt minecraft
|
||||
@@ -187,7 +188,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
||||
//you dont own me!!!!
|
||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
|
||||
VecUtils.getBlockPosCenter(blockPos)), true)
|
||||
).setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||
);
|
||||
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
|
||||
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (block == Blocks.AIR) { // early return for most common case
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL) {
|
||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA) {
|
||||
return false;
|
||||
}
|
||||
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
|
||||
@@ -98,14 +98,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (snow) {
|
||||
// the check in BlockSnow.isPassable is layers < 5
|
||||
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
|
||||
return state.getValue(BlockSnow.LAYERS) < 3;
|
||||
if (state.getValue(BlockSnow.LAYERS) >= 3) {
|
||||
return false;
|
||||
}
|
||||
// ok, it's low enough we could walk through it, but is it supported?
|
||||
return canWalkOn(x, y - 1, z);
|
||||
}
|
||||
if (trapdoor) {
|
||||
return !state.getValue(BlockTrapDoor.OPEN); // see BlockTrapDoor.isPassable
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (BlockStateInterface.isFlowing(state)) {
|
||||
if (isFlowing(state)) {
|
||||
return false; // Don't walk through flowing liquids
|
||||
}
|
||||
if (block instanceof BlockLiquid) {
|
||||
@@ -145,6 +149,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|| block == Blocks.WEB
|
||||
|| block == Blocks.VINE
|
||||
|| block == Blocks.LADDER
|
||||
|| block == Blocks.COCOA
|
||||
|| block instanceof BlockDoor
|
||||
|| block instanceof BlockFenceGate
|
||||
|| block instanceof BlockSnow
|
||||
@@ -226,7 +231,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return true;
|
||||
}
|
||||
|
||||
return facing == playerFacing == open;
|
||||
return (facing == playerFacing) == open;
|
||||
}
|
||||
|
||||
static boolean avoidWalkingInto(Block block) {
|
||||
@@ -254,9 +259,6 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return false;
|
||||
}
|
||||
if (state.isBlockNormalCube()) {
|
||||
if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
|
||||
@@ -268,22 +270,22 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
||||
return true;
|
||||
}
|
||||
if (BlockStateInterface.isWater(block)) {
|
||||
if (isWater(block)) {
|
||||
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
||||
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
||||
Block up = BlockStateInterface.get(x, y + 1, z).getBlock();
|
||||
if (up == Blocks.WATERLILY) {
|
||||
return true;
|
||||
}
|
||||
if (BlockStateInterface.isFlowing(state) || block == Blocks.FLOWING_WATER) {
|
||||
if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
|
||||
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
||||
return BlockStateInterface.isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
|
||||
return 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();
|
||||
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
|
||||
}
|
||||
if (block instanceof BlockGlass || block instanceof BlockStainedGlass) {
|
||||
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockSlab) {
|
||||
@@ -295,10 +297,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockStairs) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return block instanceof BlockStairs;
|
||||
}
|
||||
|
||||
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
|
||||
@@ -400,7 +399,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @param ts previously calculated ToolSet
|
||||
*/
|
||||
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
|
||||
mc.player.inventory.currentItem = ts.getBestSlot(b);
|
||||
mc.player.inventory.currentItem = ts.getBestSlot(b.getBlock());
|
||||
}
|
||||
|
||||
static boolean throwaway(boolean select) {
|
||||
@@ -447,4 +446,46 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
false
|
||||
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the specified block is
|
||||
* water, regardless of whether or not it is flowing.
|
||||
*
|
||||
* @param b The block
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
static boolean isWater(Block b) {
|
||||
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the block at the specified pos is
|
||||
* water, regardless of whether or not it is flowing.
|
||||
*
|
||||
* @param bp The block pos
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
static boolean isWater(BlockPos bp) {
|
||||
return isWater(BlockStateInterface.getBlock(bp));
|
||||
}
|
||||
|
||||
static boolean isLava(Block b) {
|
||||
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the specified pos has a liquid
|
||||
*
|
||||
* @param p The pos
|
||||
* @return Whether or not the block is a liquid
|
||||
*/
|
||||
static boolean isLiquid(BlockPos p) {
|
||||
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
|
||||
}
|
||||
|
||||
static boolean isFlowing(IBlockState state) {
|
||||
// Will be IFluidState in 1.13
|
||||
return state.getBlock() instanceof BlockLiquid
|
||||
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class MovementAscend extends Movement {
|
||||
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
|
||||
if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
|
||||
return COST_INF;
|
||||
}
|
||||
// TODO: add ability to place against .down() as well as the cardinal directions
|
||||
@@ -97,21 +97,19 @@ public class MovementAscend extends Movement {
|
||||
}
|
||||
}
|
||||
IBlockState srcUp2 = null;
|
||||
if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling) {//it would fall on us and possibly suffocate us
|
||||
if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
|
||||
// HOWEVER, we assume that we're standing in the start position
|
||||
// that means that src and src.up(1) are both air
|
||||
// maybe they aren't now, but they will be by the time this starts
|
||||
if (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling)) {
|
||||
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src
|
||||
// (the presupposition of this Movement)
|
||||
// we have necessarily already cleared the entire BlockFalling stack
|
||||
// on top of our head
|
||||
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src
|
||||
// (the presupposition of this Movement)
|
||||
// we have necessarily already cleared the entire BlockFalling stack
|
||||
// on top of our head
|
||||
|
||||
// as in, if we have a block, then two BlockFallings on top of it
|
||||
// and that block is x, y+1, z, and we'd have to clear it to even start this movement
|
||||
// we don't need to worry about those BlockFallings because we've already cleared them
|
||||
return COST_INF;
|
||||
}
|
||||
// as in, if we have a block, then two BlockFallings on top of it
|
||||
// and that block is x, y+1, z, and we'd have to clear it to even start this movement
|
||||
// we don't need to worry about those BlockFallings because we've already cleared them
|
||||
return COST_INF;
|
||||
// you may think we only need to check srcUp2, not srcUp
|
||||
// however, in the scenario where glitchy world gen where unsupported sand / gravel generates
|
||||
// it's possible srcUp is AIR from the start, and srcUp2 is falling
|
||||
@@ -206,10 +204,8 @@ public class MovementAscend extends Movement {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
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 (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(src.down())) {
|
||||
return state; // don't jump while walking from a non double slab into a bottom slab
|
||||
}
|
||||
|
||||
if (Baritone.settings().assumeStep.get()) {
|
||||
|
||||
@@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
|
||||
}
|
||||
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
|
||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
|
||||
if (ontoBlock.getBlock() == Blocks.WATER && !BlockStateInterface.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
|
||||
if (ontoBlock.getBlock() == Blocks.WATER && !MovementHelper.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
|
||||
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
|
||||
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
|
||||
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||
@@ -183,11 +183,10 @@ public class MovementDescend extends Movement {
|
||||
}
|
||||
|
||||
BlockPos playerFeet = playerFeet();
|
||||
if (playerFeet.equals(dest)) {
|
||||
if (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094) { // lilypads
|
||||
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
}/* else {
|
||||
if (playerFeet.equals(dest) && (MovementHelper.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads
|
||||
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
/* else {
|
||||
// System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ public class MovementDiagonal extends Movement {
|
||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
|
||||
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) {
|
||||
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
|
||||
return COST_INF;
|
||||
}
|
||||
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
|
||||
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) {
|
||||
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
|
||||
@@ -101,25 +101,22 @@ public class MovementDiagonal extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z);
|
||||
if (optionA == 0) {
|
||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
|
||||
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
||||
if ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER)) {
|
||||
return COST_INF;
|
||||
}
|
||||
return COST_INF;
|
||||
}
|
||||
optionB += MovementHelper.getMiningDurationTicks(context, destX, y + 1, z, pb3, true);
|
||||
if (optionA != 0 && optionB != 0) {
|
||||
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
||||
return COST_INF;
|
||||
}
|
||||
if (optionB == 0) {
|
||||
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) {
|
||||
// and now that option B is fully calculated, see if we can edge around that way
|
||||
if ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER)) {
|
||||
return COST_INF;
|
||||
}
|
||||
return COST_INF;
|
||||
}
|
||||
boolean water = false;
|
||||
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.isWater(destInto.getBlock())) {
|
||||
Block startIn = BlockStateInterface.getBlock(x, y, z);
|
||||
if (MovementHelper.isWater(startIn) || MovementHelper.isWater(destInto.getBlock())) {
|
||||
// Ignore previous multiplier
|
||||
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
|
||||
// Not even touching the blocks below
|
||||
@@ -128,6 +125,10 @@ public class MovementDiagonal extends Movement {
|
||||
}
|
||||
if (optionA != 0 || optionB != 0) {
|
||||
multiplier *= SQRT_2 - 0.001; // TODO tune
|
||||
if (startIn == Blocks.LADDER || startIn == Blocks.VINE) {
|
||||
// edging around doesn't work if doing so would climb a ladder or vine instead of moving sideways
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
if (context.canSprint() && !water) {
|
||||
// If we aren't edging around anything, and we aren't in water
|
||||
@@ -149,7 +150,7 @@ public class MovementDiagonal extends Movement {
|
||||
state.setStatus(MovementStatus.SUCCESS);
|
||||
return state;
|
||||
}
|
||||
if (!BlockStateInterface.isLiquid(playerFeet())) {
|
||||
if (!MovementHelper.isLiquid(playerFeet())) {
|
||||
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||
}
|
||||
MovementHelper.moveTowards(state, dest);
|
||||
|
||||
@@ -25,7 +25,6 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
@@ -63,7 +62,7 @@ public class MovementFall extends Movement {
|
||||
|
||||
BlockPos playerFeet = playerFeet();
|
||||
Rotation targetRotation = null;
|
||||
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
||||
if (!MovementHelper.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
||||
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
@@ -84,8 +83,8 @@ public class MovementFall extends Movement {
|
||||
} else {
|
||||
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
||||
}
|
||||
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || BlockStateInterface.isWater(dest))) { // 0.094 because lilypads
|
||||
if (BlockStateInterface.isWater(dest)) {
|
||||
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
|
||||
if (MovementHelper.isWater(dest)) {
|
||||
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
||||
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
||||
if (player().motionY >= 0) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import baritone.utils.Helper;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
@@ -68,7 +69,7 @@ public class MovementParkour extends Movement {
|
||||
return;
|
||||
}
|
||||
IBlockState standingOn = BlockStateInterface.get(x, y - 1, z);
|
||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) {
|
||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) {
|
||||
return;
|
||||
}
|
||||
int xDiff = dir.getXOffset();
|
||||
@@ -124,7 +125,7 @@ public class MovementParkour extends Movement {
|
||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
||||
return;
|
||||
}
|
||||
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
|
||||
if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
@@ -202,7 +203,7 @@ public class MovementParkour extends Movement {
|
||||
} else if (!playerFeet().equals(src)) {
|
||||
if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) {
|
||||
|
||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
||||
if (!MovementHelper.canWalkOn(dest.down()) && !player().onGround) {
|
||||
BlockPos positionToPlace = dest.down();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
||||
|
||||
@@ -54,16 +54,12 @@ public class MovementPillar extends Movement {
|
||||
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
||||
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 (fromDownDown.getBlock() instanceof BlockSlab && !((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 (fromDown instanceof BlockVine) {
|
||||
if (!hasAgainst(x, y, z)) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (fromDown instanceof BlockVine && !hasAgainst(x, y, z)) {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState toBreak = BlockStateInterface.get(x, y + 2, z);
|
||||
Block toBreakBlock = toBreak.getBlock();
|
||||
@@ -71,9 +67,9 @@ public class MovementPillar extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
Block srcUp = null;
|
||||
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) {
|
||||
if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(fromDown)) {
|
||||
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
|
||||
if (BlockStateInterface.isWater(srcUp)) {
|
||||
if (MovementHelper.isWater(srcUp)) {
|
||||
return LADDER_UP_ONE_COST;
|
||||
}
|
||||
}
|
||||
@@ -148,7 +144,7 @@ public class MovementPillar extends Movement {
|
||||
}
|
||||
|
||||
IBlockState fromDown = BlockStateInterface.get(src);
|
||||
if (BlockStateInterface.isWater(fromDown.getBlock()) && BlockStateInterface.isWater(dest)) {
|
||||
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(dest)) {
|
||||
// stay centered while swimming up a water column
|
||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
||||
@@ -162,10 +158,11 @@ public class MovementPillar extends Movement {
|
||||
}
|
||||
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
|
||||
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
||||
VecUtils.getBlockPosCenter(positionToPlace),
|
||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch));
|
||||
if (!ladder) {
|
||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
||||
VecUtils.getBlockPosCenter(positionToPlace),
|
||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
|
||||
state.setTarget(new MovementState.MovementTarget(new Rotation(mc.player.rotationYaw, rotation.getPitch()), true));
|
||||
}
|
||||
|
||||
boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder;
|
||||
@@ -198,7 +195,8 @@ public class MovementPillar extends Movement {
|
||||
|
||||
// If our Y coordinate is above our goal, stop jumping
|
||||
state.setInput(InputOverrideHandler.Input.JUMP, player().posY < dest.getY());
|
||||
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||
state.setInput(InputOverrideHandler.Input.SNEAK, player().posY > dest.getY()); // delay placement by 1 tick for ncp compatibility
|
||||
// since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak
|
||||
|
||||
double diffX = player().posX - (dest.getX() + 0.5);
|
||||
double diffZ = player().posZ - (dest.getZ() + 0.5);
|
||||
@@ -209,6 +207,9 @@ public class MovementPillar extends Movement {
|
||||
|
||||
// If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck
|
||||
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||
|
||||
// revise our target to both yaw and pitch if we're going to be moving forward
|
||||
state.setTarget(new MovementState.MovementTarget(rotation, true));
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +218,7 @@ public class MovementPillar extends Movement {
|
||||
if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) {
|
||||
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||
blockIsThere = false;
|
||||
} else if (Minecraft.getMinecraft().player.isSneaking()) {
|
||||
} else if (Minecraft.getMinecraft().player.isSneaking()) { // 1 tick after we're able to place
|
||||
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
@@ -239,7 +240,7 @@ public class MovementPillar extends Movement {
|
||||
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||
}
|
||||
}
|
||||
if (BlockStateInterface.isWater(dest.up())) {
|
||||
if (MovementHelper.isWater(dest.up())) {
|
||||
return true;
|
||||
}
|
||||
return super.prepared(state);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class MovementTraverse extends Movement {
|
||||
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
||||
double WC = WALK_ONE_BLOCK_COST;
|
||||
boolean water = false;
|
||||
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
||||
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
||||
WC = context.waterWalkSpeed();
|
||||
water = true;
|
||||
} else {
|
||||
@@ -101,18 +101,18 @@ public class MovementTraverse extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
|
||||
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
|
||||
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
|
||||
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
||||
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
||||
return COST_INF;
|
||||
}
|
||||
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb0, false);
|
||||
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
|
||||
if (hardness1 >= COST_INF) {
|
||||
return COST_INF;
|
||||
}
|
||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb1, true);
|
||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true);
|
||||
|
||||
double WC = throughWater ? context.waterWalkSpeed() : WALK_ONE_BLOCK_COST;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -189,11 +189,9 @@ public class MovementTraverse extends Movement {
|
||||
} else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(dest, src)) {
|
||||
isDoorActuallyBlockingUs = true;
|
||||
}
|
||||
if (isDoorActuallyBlockingUs) {
|
||||
if (!(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
|
||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true))
|
||||
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||
}
|
||||
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
|
||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true))
|
||||
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +223,7 @@ public class MovementTraverse extends Movement {
|
||||
if (playerFeet().equals(dest)) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
}
|
||||
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
|
||||
if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
|
||||
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||
}
|
||||
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
|
||||
@@ -267,11 +265,8 @@ public class MovementTraverse extends Movement {
|
||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
|
||||
|
||||
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
||||
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get())) {
|
||||
if (RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
||||
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||
}
|
||||
// wrong side?
|
||||
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get()) && RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
||||
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||
}
|
||||
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
|
||||
return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package baritone.pathing.path;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.movement.ActionCosts;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
@@ -81,14 +80,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
/**
|
||||
* Tick this executor
|
||||
*
|
||||
* @param event
|
||||
* @return True if a movement just finished (and the player is therefore in a "stable" state, like,
|
||||
* not sneaking out over lava), false otherwise
|
||||
*/
|
||||
public boolean onTick(TickEvent event) {
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public boolean onTick() {
|
||||
if (pathPosition == path.length() - 1) {
|
||||
pathPosition++;
|
||||
}
|
||||
@@ -261,7 +256,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
//System.out.println("Movement done, next path");
|
||||
pathPosition++;
|
||||
onChangeInPathPosition();
|
||||
onTick(event);
|
||||
onTick();
|
||||
return true;
|
||||
} else {
|
||||
sprintIfRequested();
|
||||
@@ -276,7 +271,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // movement is in progress
|
||||
return canCancel; // movement is in progress, but if it reports cancellable, PathingBehavior is good to cut onto the next path
|
||||
}
|
||||
|
||||
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
|
||||
@@ -331,10 +326,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
|
||||
if (path.movements().get(pathPosition) instanceof MovementFall) {
|
||||
BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of
|
||||
if (VecUtils.entityFlatDistanceToCenter(player(), fallDest) < leniency) { // ignore Y by using flat distance
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return VecUtils.entityFlatDistanceToCenter(player(), fallDest) >= leniency; // ignore Y by using flat distance
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -432,20 +424,13 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
|
||||
private static boolean canSprintInto(IMovement current, IMovement next) {
|
||||
if (next instanceof MovementDescend) {
|
||||
if (next.getDirection().equals(current.getDirection())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (next instanceof MovementTraverse) {
|
||||
if (next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
|
||||
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
|
||||
return true;
|
||||
}
|
||||
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get();
|
||||
}
|
||||
|
||||
private void onChangeInPathPosition() {
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
package baritone.utils;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
@@ -105,8 +105,8 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
}
|
||||
|
||||
// Setup Baritone's pathing goal and (if needed) begin pathing
|
||||
PathingBehavior.INSTANCE.setGoal(GOAL);
|
||||
PathingBehavior.INSTANCE.path();
|
||||
Baritone.INSTANCE.getPathingBehavior().setGoal(GOAL);
|
||||
Baritone.INSTANCE.getPathingBehavior().path();
|
||||
|
||||
// If we have reached our goal, print a message and safely close the game
|
||||
if (GOAL.isInGoal(playerFeet())) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import baritone.cache.CachedRegion;
|
||||
import baritone.cache.WorldData;
|
||||
import baritone.cache.WorldProvider;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -128,47 +127,4 @@ public class BlockStateInterface implements Helper {
|
||||
public static Block getBlock(int x, int y, int z) {
|
||||
return get(x, y, z).getBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the specified block is
|
||||
* water, regardless of whether or not it is flowing.
|
||||
*
|
||||
* @param b The block
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
public static boolean isWater(Block b) {
|
||||
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the block at the specified pos is
|
||||
* water, regardless of whether or not it is flowing.
|
||||
*
|
||||
* @param bp The block pos
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
public static boolean isWater(BlockPos bp) {
|
||||
return isWater(BlockStateInterface.getBlock(bp));
|
||||
}
|
||||
|
||||
public static boolean isLava(Block b) {
|
||||
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the specified pos has a liquid
|
||||
*
|
||||
* @param p The pos
|
||||
* @return Whether or not the block is a liquid
|
||||
*/
|
||||
public static boolean isLiquid(BlockPos p) {
|
||||
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
|
||||
}
|
||||
|
||||
public static boolean isFlowing(IBlockState state) {
|
||||
// Will be IFluidState in 1.13
|
||||
return state.getBlock() instanceof BlockLiquid
|
||||
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
|
||||
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ import baritone.api.pathing.movement.ActionCosts;
|
||||
import baritone.api.utils.RayTraceUtils;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.behavior.Behavior;
|
||||
import baritone.behavior.FollowBehavior;
|
||||
import baritone.behavior.MineBehavior;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.cache.ChunkPacker;
|
||||
import baritone.cache.Waypoint;
|
||||
@@ -48,47 +46,83 @@ import java.util.stream.Stream;
|
||||
|
||||
public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
|
||||
public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl();
|
||||
public static ExampleBaritoneControl INSTANCE; // compatibility with impact 4.4
|
||||
|
||||
private ExampleBaritoneControl() {
|
||||
private static final String HELP_MSG =
|
||||
"baritone - Output settings into chat\n" +
|
||||
"settings - Same as baritone\n" +
|
||||
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
|
||||
"path - Go towards goal\n" +
|
||||
"repack - (debug) Repacks chunk cache\n" +
|
||||
"rescan - (debug) Same as repack\n" +
|
||||
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
|
||||
"cancel - Cancels current path\n" +
|
||||
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
|
||||
"gc - Calls System.gc();\n" +
|
||||
"invert - Runs away from the goal instead of towards it\n" +
|
||||
"follow - Follows a player 'follow username'\n" +
|
||||
"reloadall - (debug) Reloads chunk cache\n" +
|
||||
"saveall - (debug) Saves chunk cache\n" +
|
||||
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
|
||||
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
|
||||
"thisway - Creates a goal X blocks where you're facing\n" +
|
||||
"list - Lists waypoints under a category\n" +
|
||||
"get - Same as list\n" +
|
||||
"show - Same as list\n" +
|
||||
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
|
||||
"goto - Paths towards specified block or waypoint\n" +
|
||||
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
|
||||
"sethome - Sets \"home\"\n" +
|
||||
"home - Paths towards \"home\" \n" +
|
||||
"costs - (debug) all movement costs from current location\n" +
|
||||
"pause - Toggle pause\n" +
|
||||
"damn - Daniel ";
|
||||
|
||||
}
|
||||
|
||||
public void initAndRegister() {
|
||||
Baritone.INSTANCE.registerBehavior(this);
|
||||
public ExampleBaritoneControl(Baritone baritone) {
|
||||
super(baritone);
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendChatMessage(ChatEvent event) {
|
||||
if (!Baritone.settings().chatControl.get()) {
|
||||
if (!Baritone.settings().removePrefix.get()) {
|
||||
return;
|
||||
}
|
||||
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
|
||||
return;
|
||||
}
|
||||
String msg = event.getMessage().toLowerCase(Locale.US);
|
||||
String msg = event.getMessage();
|
||||
if (Baritone.settings().prefix.get()) {
|
||||
if (!msg.startsWith("#")) {
|
||||
return;
|
||||
}
|
||||
msg = msg.substring(1);
|
||||
}
|
||||
if (runCommand(msg)) {
|
||||
event.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean runCommand(String msg0) {
|
||||
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
||||
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
|
||||
for (Settings.Setting<Boolean> setting : toggleable) {
|
||||
if (msg.equalsIgnoreCase(setting.getName())) {
|
||||
setting.value ^= true;
|
||||
event.cancel();
|
||||
logDirect("Toggled " + setting.getName() + " to " + setting.value);
|
||||
SettingsUtil.save(Baritone.settings());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (msg.equals("baritone") || msg.equals("settings")) {
|
||||
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
|
||||
logDirect(setting.toString());
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
|
||||
for (String line : HELP_MSG.split("\n")) {
|
||||
logDirect(line);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (msg.contains(" ")) {
|
||||
String[] data = msg.split(" ");
|
||||
@@ -110,25 +144,21 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
logDirect("Unable to parse " + data[1]);
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
SettingsUtil.save(Baritone.settings());
|
||||
logDirect(setting.toString());
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Baritone.settings().byLowerName.containsKey(msg)) {
|
||||
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg);
|
||||
logDirect(setting.toString());
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.startsWith("goal")) {
|
||||
event.cancel();
|
||||
String[] params = msg.substring(4).trim().split(" ");
|
||||
if (params[0].equals("")) {
|
||||
params = new String[]{};
|
||||
@@ -154,30 +184,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
break;
|
||||
default:
|
||||
logDirect("unable to understand lol");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
logDirect("unable to parse integer " + ex);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
pathingBehavior.setGoal(goal);
|
||||
logDirect("Goal: " + goal);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("path")) {
|
||||
if (!PathingBehavior.INSTANCE.path()) {
|
||||
if (PathingBehavior.INSTANCE.getGoal() == null) {
|
||||
if (!pathingBehavior.path()) {
|
||||
if (pathingBehavior.getGoal() == null) {
|
||||
logDirect("No goal.");
|
||||
} else {
|
||||
if (PathingBehavior.INSTANCE.getGoal().isInGoal(playerFeet())) {
|
||||
if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
|
||||
logDirect("Already in goal");
|
||||
} else {
|
||||
logDirect("Currently executing a path. Please cancel it first.");
|
||||
}
|
||||
}
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("repack") || msg.equals("rescan")) {
|
||||
ChunkProviderClient cli = world().getChunkProvider();
|
||||
@@ -194,41 +223,36 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
}
|
||||
logDirect("Queued " + count + " chunks for repacking");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("axis")) {
|
||||
PathingBehavior.INSTANCE.setGoal(new GoalAxis());
|
||||
PathingBehavior.INSTANCE.path();
|
||||
event.cancel();
|
||||
return;
|
||||
pathingBehavior.setGoal(new GoalAxis());
|
||||
pathingBehavior.path();
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("cancel") || msg.equals("stop")) {
|
||||
MineBehavior.INSTANCE.cancel();
|
||||
FollowBehavior.INSTANCE.cancel();
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
event.cancel();
|
||||
baritone.getMineBehavior().cancel();
|
||||
baritone.getFollowBehavior().cancel();
|
||||
pathingBehavior.cancel();
|
||||
logDirect("ok canceled");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("forcecancel")) {
|
||||
MineBehavior.INSTANCE.cancel();
|
||||
FollowBehavior.INSTANCE.cancel();
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
baritone.getMineBehavior().cancel();
|
||||
baritone.getFollowBehavior().cancel();
|
||||
pathingBehavior.cancel();
|
||||
AbstractNodeCostSearch.forceCancel();
|
||||
PathingBehavior.INSTANCE.forceCancel();
|
||||
event.cancel();
|
||||
pathingBehavior.forceCancel();
|
||||
logDirect("ok force canceled");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("gc")) {
|
||||
System.gc();
|
||||
event.cancel();
|
||||
logDirect("Called System.gc();");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("invert")) {
|
||||
Goal goal = PathingBehavior.INSTANCE.getGoal();
|
||||
Goal goal = pathingBehavior.getGoal();
|
||||
BlockPos runAwayFrom;
|
||||
if (goal instanceof GoalXZ) {
|
||||
runAwayFrom = new BlockPos(((GoalXZ) goal).getX(), 0, ((GoalXZ) goal).getZ());
|
||||
@@ -239,17 +263,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect("Inverting goal of player feet");
|
||||
runAwayFrom = playerFeet();
|
||||
}
|
||||
PathingBehavior.INSTANCE.setGoal(new GoalRunAway(1, runAwayFrom) {
|
||||
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
|
||||
@Override
|
||||
public boolean isInGoal(BlockPos pos) {
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (!PathingBehavior.INSTANCE.path()) {
|
||||
if (!pathingBehavior.path()) {
|
||||
logDirect("Currently executing a path. Please cancel it first.");
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("follow")) {
|
||||
String name = msg.substring(6).trim();
|
||||
@@ -259,34 +282,28 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
} else {
|
||||
for (EntityPlayer pl : world().playerEntities) {
|
||||
String theirName = pl.getName().trim().toLowerCase();
|
||||
if (!theirName.equals(player().getName().trim().toLowerCase())) { // don't follow ourselves lol
|
||||
if (theirName.contains(name) || name.contains(theirName)) {
|
||||
toFollow = Optional.of(pl);
|
||||
}
|
||||
if (!theirName.equals(player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
|
||||
toFollow = Optional.of(pl);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!toFollow.isPresent()) {
|
||||
logDirect("Not found");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
FollowBehavior.INSTANCE.follow(toFollow.get());
|
||||
baritone.getFollowBehavior().follow(toFollow.get());
|
||||
logDirect("Following " + toFollow.get());
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("reloadall")) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
||||
logDirect("ok");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("saveall")) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save();
|
||||
logDirect("ok");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("find")) {
|
||||
String blockType = msg.substring(4).trim();
|
||||
@@ -298,8 +315,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually));
|
||||
}
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("mine")) {
|
||||
String[] blockTypes = msg.substring(4).trim().split(" ");
|
||||
@@ -307,34 +323,30 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
int quantity = Integer.parseInt(blockTypes[1]);
|
||||
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
|
||||
Objects.requireNonNull(block);
|
||||
MineBehavior.INSTANCE.mine(quantity, block);
|
||||
baritone.getMineBehavior().mine(quantity, block);
|
||||
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
|
||||
for (String s : blockTypes) {
|
||||
if (ChunkPacker.stringToBlock(s) == null) {
|
||||
logDirect(s + " isn't a valid block name");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
MineBehavior.INSTANCE.mine(0, blockTypes);
|
||||
baritone.getMineBehavior().mine(0, blockTypes);
|
||||
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("thisway")) {
|
||||
try {
|
||||
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
pathingBehavior.setGoal(goal);
|
||||
logDirect("Goal: " + goal);
|
||||
} catch (NumberFormatException ex) {
|
||||
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("list") || msg.startsWith("get ") || msg.startsWith("show")) {
|
||||
String waypointType = msg.substring(4).trim();
|
||||
@@ -345,8 +357,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||
if (tag == null) {
|
||||
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
Set<IWaypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getByTag(tag);
|
||||
// might as well show them from oldest to newest
|
||||
@@ -356,11 +367,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
for (IWaypoint waypoint : sorted) {
|
||||
logDirect(waypoint.toString());
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("save")) {
|
||||
event.cancel();
|
||||
String name = msg.substring(4).trim();
|
||||
BlockPos pos = playerFeet();
|
||||
if (name.contains(" ")) {
|
||||
@@ -368,19 +377,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
String[] parts = name.split(" ");
|
||||
if (parts.length != 4) {
|
||||
logDirect("Unable to parse, expected four things");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
pos = new BlockPos(Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]));
|
||||
} catch (NumberFormatException ex) {
|
||||
logDirect("Unable to parse coordinate integers");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
name = parts[0];
|
||||
}
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
|
||||
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto user' to set goal, say 'list user' to list.");
|
||||
return;
|
||||
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("goto")) {
|
||||
String waypointType = msg.substring(4).trim();
|
||||
@@ -394,40 +403,35 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
String mining = waypointType;
|
||||
Block block = ChunkPacker.stringToBlock(mining);
|
||||
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||
event.cancel();
|
||||
if (block == null) {
|
||||
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
||||
if (waypoint == null) {
|
||||
logDirect("No locations for " + mining + " known, cancelling");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
List<BlockPos> locs = MineBehavior.INSTANCE.scanFor(Collections.singletonList(block), 64);
|
||||
List<BlockPos> locs = baritone.getMineBehavior().searchWorld(Collections.singletonList(block), 64, world());
|
||||
if (locs.isEmpty()) {
|
||||
logDirect("No locations for " + mining + " known, cancelling");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
||||
PathingBehavior.INSTANCE.path();
|
||||
return;
|
||||
pathingBehavior.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
||||
pathingBehavior.path();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
|
||||
if (waypoint == null) {
|
||||
logDirect("None saved for tag " + tag);
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
if (!PathingBehavior.INSTANCE.path()) {
|
||||
if (!goal.isInGoal(playerFeet())) {
|
||||
logDirect("Currently executing a path. Please cancel it first.");
|
||||
}
|
||||
pathingBehavior.setGoal(goal);
|
||||
if (!pathingBehavior.path() && !goal.isInGoal(playerFeet())) {
|
||||
logDirect("Currently executing a path. Please cancel it first.");
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("spawn") || msg.equals("bed")) {
|
||||
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
|
||||
@@ -436,20 +440,18 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
// for some reason the default spawnpoint is underground sometimes
|
||||
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
|
||||
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
pathingBehavior.setGoal(goal);
|
||||
} else {
|
||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
pathingBehavior.setGoal(goal);
|
||||
logDirect("Set goal to most recent bed " + goal);
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("sethome")) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet()));
|
||||
logDirect("Saved. Say home to set goal.");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("home")) {
|
||||
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
|
||||
@@ -457,12 +459,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
logDirect("home not saved");
|
||||
} else {
|
||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||
PathingBehavior.INSTANCE.setGoal(goal);
|
||||
PathingBehavior.INSTANCE.path();
|
||||
pathingBehavior.setGoal(goal);
|
||||
pathingBehavior.path();
|
||||
logDirect("Going to saved home " + goal);
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("costs")) {
|
||||
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
||||
@@ -479,18 +480,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||
}
|
||||
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
|
||||
}
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("pause")) {
|
||||
boolean enabled = PathingBehavior.INSTANCE.toggle();
|
||||
boolean enabled = pathingBehavior.toggle();
|
||||
logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + ".");
|
||||
event.cancel();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("damn")) {
|
||||
logDirect("daniel");
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,41 +23,41 @@ import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.init.Enchantments;
|
||||
import net.minecraft.init.MobEffects;
|
||||
import net.minecraft.item.Item.ToolMaterial;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemTool;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A cached list of the best tools on the hotbar for any block
|
||||
*
|
||||
* @author avecowa, Brady, leijurv
|
||||
* @author Avery, Brady, leijurv
|
||||
*/
|
||||
public class ToolSet implements Helper {
|
||||
|
||||
/**
|
||||
* A cache mapping a {@link Block} to how long it will take to break
|
||||
* with this toolset, given the optimum tool is used.
|
||||
*/
|
||||
private Map<Block, Double> breakStrengthCache = new HashMap<>();
|
||||
private final Map<Block, Double> breakStrengthCache;
|
||||
|
||||
/**
|
||||
* Calculate which tool on the hotbar is best for mining
|
||||
*
|
||||
* @param b the blockstate to be mined
|
||||
* @return a byte indicating the index in the tools array that worked best
|
||||
* My buddy leijurv owned me so we have this to not create a new lambda instance.
|
||||
*/
|
||||
public byte getBestSlot(IBlockState b) {
|
||||
byte best = 0;
|
||||
double value = -1;
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
double v = calculateStrVsBlock(i, b);
|
||||
if (v > value || value == -1) {
|
||||
value = v;
|
||||
best = i;
|
||||
}
|
||||
private final Function<Block, Double> backendCalculation;
|
||||
|
||||
public ToolSet() {
|
||||
breakStrengthCache = new HashMap<>();
|
||||
|
||||
if (Baritone.settings().considerPotionEffects.get()) {
|
||||
double amplifier = potionAmplifier();
|
||||
Function<Double, Double> amplify = x -> amplifier * x;
|
||||
backendCalculation = amplify.compose(this::getBestDestructionTime);
|
||||
} else {
|
||||
backendCalculation = this::getBestDestructionTime;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,14 +67,64 @@ public class ToolSet implements Helper {
|
||||
* @return how long it would take in ticks
|
||||
*/
|
||||
public double getStrVsBlock(IBlockState state) {
|
||||
Double strength = this.breakStrengthCache.get(state.getBlock());
|
||||
if (strength != null) {
|
||||
// the function will take this path >99% of the time
|
||||
return strength;
|
||||
return breakStrengthCache.computeIfAbsent(state.getBlock(), backendCalculation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the material cost of a possible tool. The priority matches the
|
||||
* listed order in the Item.ToolMaterial enum.
|
||||
*
|
||||
* @param itemStack a possibly empty ItemStack
|
||||
* @return values range from -1 to 4
|
||||
*/
|
||||
private int getMaterialCost(ItemStack itemStack) {
|
||||
if (itemStack.getItem() instanceof ItemTool) {
|
||||
ItemTool tool = (ItemTool) itemStack.getItem();
|
||||
return ToolMaterial.valueOf(tool.getToolMaterialName()).ordinal();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
double str = calculateStrVsBlock(getBestSlot(state), state);
|
||||
this.breakStrengthCache.put(state.getBlock(), str);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate which tool on the hotbar is best for mining
|
||||
*
|
||||
* @param b the blockstate to be mined
|
||||
* @return A byte containing the index in the tools array that worked best
|
||||
*/
|
||||
public byte getBestSlot(Block b) {
|
||||
byte best = 0;
|
||||
double value = Double.NEGATIVE_INFINITY;
|
||||
int materialCost = Integer.MIN_VALUE;
|
||||
IBlockState blockState = b.getDefaultState();
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
ItemStack itemStack = player().inventory.getStackInSlot(i);
|
||||
double v = calculateStrVsBlock(itemStack, blockState);
|
||||
if (v > value) {
|
||||
value = v;
|
||||
best = i;
|
||||
materialCost = getMaterialCost(itemStack);
|
||||
} else if (v == value) {
|
||||
int c = getMaterialCost(itemStack);
|
||||
if (c < materialCost) {
|
||||
value = v;
|
||||
best = i;
|
||||
materialCost = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate how effectively a block can be destroyed
|
||||
*
|
||||
* @param b the blockstate to be mined
|
||||
* @return A double containing the destruction ticks with the best tool
|
||||
*/
|
||||
private double getBestDestructionTime(Block b) {
|
||||
ItemStack stack = player().inventory.getStackInSlot(getBestSlot(b));
|
||||
return calculateStrVsBlock(stack, b.getDefaultState());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,49 +134,55 @@ public class ToolSet implements Helper {
|
||||
* @param state the blockstate to be mined
|
||||
* @return how long it would take in ticks
|
||||
*/
|
||||
private double calculateStrVsBlock(byte slot, IBlockState state) {
|
||||
// Calculate the slot with the best item
|
||||
ItemStack contents = player().inventory.getStackInSlot(slot);
|
||||
|
||||
float blockHard = state.getBlockHardness(null, null);
|
||||
if (blockHard < 0) {
|
||||
private double calculateStrVsBlock(ItemStack item, IBlockState state) {
|
||||
float hardness = state.getBlockHardness(null, null);
|
||||
if (hardness < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float speed = contents.getDestroySpeed(state);
|
||||
float speed = item.getDestroySpeed(state);
|
||||
if (speed > 1) {
|
||||
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, contents);
|
||||
if (effLevel > 0 && !contents.isEmpty()) {
|
||||
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, item);
|
||||
if (effLevel > 0 && !item.isEmpty()) {
|
||||
speed += effLevel * effLevel + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Baritone.settings().considerPotionEffects.get()) {
|
||||
if (player().isPotionActive(MobEffects.HASTE)) {
|
||||
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
||||
}
|
||||
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
|
||||
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
||||
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;
|
||||
speed /= hardness;
|
||||
if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
|
||||
speed /= 30;
|
||||
} else {
|
||||
return speed / 100;
|
||||
speed /= 100;
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates any modifier to breaking time based on status effects.
|
||||
*
|
||||
* @return a double to scale block breaking speed.
|
||||
*/
|
||||
private double potionAmplifier() {
|
||||
double speed = 1;
|
||||
if (player().isPotionActive(MobEffects.HASTE)) {
|
||||
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
||||
}
|
||||
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
|
||||
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
||||
case 0:
|
||||
speed *= 0.3;
|
||||
break;
|
||||
case 1:
|
||||
speed *= 0.09;
|
||||
break;
|
||||
case 2:
|
||||
speed *= 0.0027;
|
||||
break;
|
||||
default:
|
||||
speed *= 0.00081;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user