Merge branch 'master' into tenor
This commit is contained in:
@@ -5,12 +5,15 @@
|
|||||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||||
[](http://hits.dwyl.com/cabaletta/baritone)
|
[](http://hits.dwyl.com/cabaletta/baritone)
|
||||||
[](https://github.com/cabaletta/baritone/issues)
|
[](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/),
|
A Minecraft pathfinder bot.
|
||||||
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
|
||||||
|
|
||||||
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
||||||
|
|
||||||
|
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||||
|
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||||
|
|
||||||
Here are some links to help to get started:
|
Here are some links to help to get started:
|
||||||
|
|
||||||
- [Features](FEATURES.md)
|
- [Features](FEATURES.md)
|
||||||
@@ -21,29 +24,29 @@ There's also some useful information down below
|
|||||||
|
|
||||||
# Setup
|
# 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
|
## Command Line
|
||||||
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||||
|
|
||||||
Running Baritone:
|
Running Baritone:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ gradlew run
|
$ gradlew runClient
|
||||||
```
|
```
|
||||||
|
|
||||||
Setting up for IntelliJ:
|
Building Baritone:
|
||||||
```
|
```
|
||||||
$ gradlew setupDecompWorkspace
|
$ gradlew build
|
||||||
$ gradlew --refresh-dependencies
|
|
||||||
$ gradlew genIntellijRuns
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For example, to replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
|
||||||
|
|
||||||
|
## IntelliJ's Gradle UI
|
||||||
|
- Open the project in IntelliJ as a Gradle project
|
||||||
|
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
|
||||||
|
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||||
|
- Select the "Minecraft Client" launch config
|
||||||
|
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
|
||||||
|
|
||||||
# Chat control
|
# Chat control
|
||||||
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
|
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ sourceSets {
|
|||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = '1.12.2'
|
version = '1.12.2'
|
||||||
mappings = 'snapshot_20180731'
|
mappings = 'stable_39'
|
||||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||||
runDir = 'run'
|
runDir = 'run'
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,16 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
import baritone.api.behavior.*;
|
import baritone.api.behavior.ILookBehavior;
|
||||||
|
import baritone.api.behavior.IMemoryBehavior;
|
||||||
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.cache.IWorldProvider;
|
import baritone.api.cache.IWorldProvider;
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
|
import baritone.api.process.ICustomGoalProcess;
|
||||||
|
import baritone.api.process.IFollowProcess;
|
||||||
|
import baritone.api.process.IGetToBlockProcess;
|
||||||
|
import baritone.api.process.IMineProcess;
|
||||||
import baritone.api.utils.SettingsUtil;
|
import baritone.api.utils.SettingsUtil;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -36,20 +42,20 @@ import java.util.ServiceLoader;
|
|||||||
*/
|
*/
|
||||||
public final class BaritoneAPI {
|
public final class BaritoneAPI {
|
||||||
|
|
||||||
private static final IBaritoneProvider baritone;
|
private static final IBaritone baritone;
|
||||||
private static final Settings settings;
|
private static final Settings settings;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
|
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
|
||||||
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
|
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
|
||||||
baritone = instances.next();
|
baritone = instances.next().getBaritoneForPlayer(null); // PWNAGE
|
||||||
|
|
||||||
settings = new Settings();
|
settings = new Settings();
|
||||||
SettingsUtil.readAndApply(settings);
|
SettingsUtil.readAndApply(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IFollowBehavior getFollowBehavior() {
|
public static IFollowProcess getFollowProcess() {
|
||||||
return baritone.getFollowBehavior();
|
return baritone.getFollowProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ILookBehavior getLookBehavior() {
|
public static ILookBehavior getLookBehavior() {
|
||||||
@@ -60,8 +66,8 @@ public final class BaritoneAPI {
|
|||||||
return baritone.getMemoryBehavior();
|
return baritone.getMemoryBehavior();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMineBehavior getMineBehavior() {
|
public static IMineProcess getMineProcess() {
|
||||||
return baritone.getMineBehavior();
|
return baritone.getMineProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IPathingBehavior getPathingBehavior() {
|
public static IPathingBehavior getPathingBehavior() {
|
||||||
@@ -80,6 +86,14 @@ public final class BaritoneAPI {
|
|||||||
return baritone.getWorldScanner();
|
return baritone.getWorldScanner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ICustomGoalProcess getCustomGoalProcess() {
|
||||||
|
return baritone.getCustomGoalProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IGetToBlockProcess getGetToBlockProcess() {
|
||||||
|
return baritone.getGetToBlockProcess();
|
||||||
|
}
|
||||||
|
|
||||||
public static void registerEventListener(IGameEventListener listener) {
|
public static void registerEventListener(IGameEventListener listener) {
|
||||||
baritone.registerEventListener(listener);
|
baritone.registerEventListener(listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api;
|
||||||
|
|
||||||
|
import baritone.api.behavior.ILookBehavior;
|
||||||
|
import baritone.api.behavior.IMemoryBehavior;
|
||||||
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
|
import baritone.api.cache.IWorldProvider;
|
||||||
|
import baritone.api.cache.IWorldScanner;
|
||||||
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
|
import baritone.api.process.ICustomGoalProcess;
|
||||||
|
import baritone.api.process.IFollowProcess;
|
||||||
|
import baritone.api.process.IGetToBlockProcess;
|
||||||
|
import baritone.api.process.IMineProcess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/29/2018
|
||||||
|
*/
|
||||||
|
public interface IBaritone {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IFollowProcess} instance
|
||||||
|
* @see IFollowProcess
|
||||||
|
*/
|
||||||
|
IFollowProcess getFollowProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link ILookBehavior} instance
|
||||||
|
* @see ILookBehavior
|
||||||
|
*/
|
||||||
|
ILookBehavior getLookBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IMemoryBehavior} instance
|
||||||
|
* @see IMemoryBehavior
|
||||||
|
*/
|
||||||
|
IMemoryBehavior getMemoryBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IMineProcess} instance
|
||||||
|
* @see IMineProcess
|
||||||
|
*/
|
||||||
|
IMineProcess getMineProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IPathingBehavior} instance
|
||||||
|
* @see IPathingBehavior
|
||||||
|
*/
|
||||||
|
IPathingBehavior getPathingBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IWorldProvider} instance
|
||||||
|
* @see IWorldProvider
|
||||||
|
*/
|
||||||
|
IWorldProvider getWorldProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IWorldScanner} instance
|
||||||
|
* @see IWorldScanner
|
||||||
|
*/
|
||||||
|
IWorldScanner getWorldScanner();
|
||||||
|
|
||||||
|
ICustomGoalProcess getCustomGoalProcess();
|
||||||
|
|
||||||
|
IGetToBlockProcess getGetToBlockProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a {@link IGameEventListener} with Baritone's "event bus".
|
||||||
|
*
|
||||||
|
* @param listener The listener
|
||||||
|
*/
|
||||||
|
void registerEventListener(IGameEventListener listener);
|
||||||
|
}
|
||||||
@@ -17,70 +17,19 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
import baritone.api.behavior.*;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import baritone.api.cache.IWorldProvider;
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Leijurv
|
||||||
* @since 9/29/2018
|
|
||||||
*/
|
*/
|
||||||
public interface IBaritoneProvider {
|
public interface IBaritoneProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IFollowBehavior
|
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
||||||
|
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
|
||||||
*
|
*
|
||||||
* @return The {@link IFollowBehavior} instance
|
* @param player The player
|
||||||
|
* @return The {@link IBaritone} instance.
|
||||||
*/
|
*/
|
||||||
IFollowBehavior getFollowBehavior();
|
IBaritone getBaritoneForPlayer(EntityPlayerSP player);
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ILookBehavior
|
|
||||||
*
|
|
||||||
* @return The {@link ILookBehavior} instance
|
|
||||||
*/
|
|
||||||
ILookBehavior getLookBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IMemoryBehavior
|
|
||||||
*
|
|
||||||
* @return The {@link IMemoryBehavior} instance
|
|
||||||
*/
|
|
||||||
IMemoryBehavior getMemoryBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IMineBehavior
|
|
||||||
*
|
|
||||||
* @return The {@link IMineBehavior} instance
|
|
||||||
*/
|
|
||||||
IMineBehavior getMineBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IPathingBehavior
|
|
||||||
*
|
|
||||||
* @return The {@link IPathingBehavior} instance
|
|
||||||
*/
|
|
||||||
IPathingBehavior getPathingBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IWorldProvider
|
|
||||||
*
|
|
||||||
* @return The {@link IWorldProvider} instance
|
|
||||||
*/
|
|
||||||
IWorldProvider getWorldProvider();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IWorldScanner
|
|
||||||
*
|
|
||||||
* @return The {@link IWorldScanner} instance
|
|
||||||
*/
|
|
||||||
IWorldScanner getWorldScanner();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a {@link IGameEventListener} with Baritone's "event bus".
|
|
||||||
*
|
|
||||||
* @param listener The listener
|
|
||||||
*/
|
|
||||||
void registerEventListener(IGameEventListener listener);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import net.minecraft.util.text.ITextComponent;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,6 +276,13 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> chunkCaching = new Setting<>(true);
|
public Setting<Boolean> chunkCaching = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
|
||||||
|
* <p>
|
||||||
|
* Temporarily disabled, see issue #248
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print all the debug messages to chat
|
* Print all the debug messages to chat
|
||||||
*/
|
*/
|
||||||
@@ -305,17 +312,17 @@ public class Settings {
|
|||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the goal
|
* Ignore depth when rendering the goal
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the path
|
* Ignore depth when rendering the path
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line width of the path when rendered, in pixels
|
* Line width of the path when rendered, in pixels
|
||||||
@@ -370,12 +377,27 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||||
|
*/
|
||||||
|
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current path is too long, cut off this many movements from the beginning.
|
||||||
|
*/
|
||||||
|
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescan for the goal once every 5 ticks.
|
* Rescan for the goal once every 5 ticks.
|
||||||
* Set to 0 to disable.
|
* Set to 0 to disable.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -389,7 +411,7 @@ public class Settings {
|
|||||||
* <p>
|
* <p>
|
||||||
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(false);
|
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
||||||
|
|||||||
@@ -18,10 +18,9 @@
|
|||||||
package baritone.api.behavior;
|
package baritone.api.behavior;
|
||||||
|
|
||||||
import baritone.api.event.listener.AbstractGameEventListener;
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
import baritone.api.utils.interfaces.Toggleable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IBehavior extends AbstractGameEventListener, Toggleable {}
|
public interface IBehavior extends AbstractGameEventListener {}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface ILookBehavior extends IBehavior {
|
|||||||
* otherwise, it should be {@code false};
|
* otherwise, it should be {@code false};
|
||||||
*
|
*
|
||||||
* @param rotation The target rotations
|
* @param rotation The target rotations
|
||||||
* @param force Whether or not to "force" the rotations
|
* @param force Whether or not to "force" the rotations
|
||||||
*/
|
*/
|
||||||
void updateTarget(Rotation rotation, boolean force);
|
void updateTarget(Rotation rotation, boolean force);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,35 +39,25 @@ public interface IPathingBehavior extends IBehavior {
|
|||||||
*/
|
*/
|
||||||
Optional<Double> ticksRemainingInSegment();
|
Optional<Double> ticksRemainingInSegment();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the pathing goal.
|
|
||||||
*
|
|
||||||
* @param goal The pathing goal
|
|
||||||
*/
|
|
||||||
void setGoal(Goal goal);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current pathing goal
|
* @return The current pathing goal
|
||||||
*/
|
*/
|
||||||
Goal getGoal();
|
Goal getGoal();
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins pathing. Calculation will start in a new thread, and once completed,
|
|
||||||
* movement will commence. Returns whether or not the operation was successful.
|
|
||||||
*
|
|
||||||
* @return Whether or not the operation was successful
|
|
||||||
*/
|
|
||||||
boolean path();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether or not a path is currently being executed.
|
* @return Whether or not a path is currently being executed.
|
||||||
*/
|
*/
|
||||||
boolean isPathing();
|
boolean isPathing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the pathing behavior or the current path calculation.
|
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
|
||||||
|
* <p>
|
||||||
|
* Basically, "MAKE IT STOP".
|
||||||
|
*
|
||||||
|
* @return Whether or not the pathing behavior was canceled. All processes are guaranteed to be canceled, but the
|
||||||
|
* PathingBehavior might be in the middle of an uncancelable action like a parkour jump
|
||||||
*/
|
*/
|
||||||
void cancel();
|
boolean cancelEverything();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current path, from the current path executor, if there is one.
|
* Returns the current path, from the current path executor, if there is one.
|
||||||
|
|||||||
+1
-2
@@ -29,11 +29,10 @@ public interface ICachedRegion extends IBlockTypeAccess {
|
|||||||
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
||||||
* because region sizes are 512x512 blocks.
|
* because region sizes are 512x512 blocks.
|
||||||
*
|
*
|
||||||
* @see ICachedWorld#isCached(int, int)
|
|
||||||
*
|
|
||||||
* @param blockX The block X coordinate
|
* @param blockX The block X coordinate
|
||||||
* @param blockZ The block Z coordinate
|
* @param blockZ The block Z coordinate
|
||||||
* @return Whether or not the specified XZ location is cached
|
* @return Whether or not the specified XZ location is cached
|
||||||
|
* @see ICachedWorld#isCached(int, int)
|
||||||
*/
|
*/
|
||||||
boolean isCached(int blockX, int blockZ);
|
boolean isCached(int blockX, int blockZ);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -61,8 +61,8 @@ public interface ICachedWorld {
|
|||||||
* information that is returned by this method may not be up to date, because
|
* information that is returned by this method may not be up to date, because
|
||||||
* older cached chunks can contain data that is much more likely to have changed.
|
* older cached chunks can contain data that is much more likely to have changed.
|
||||||
*
|
*
|
||||||
* @param block The special block to search for
|
* @param block The special block to search for
|
||||||
* @param maximum The maximum number of position results to receive
|
* @param maximum The maximum number of position results to receive
|
||||||
* @param maxRegionDistanceSq The maximum region distance, squared
|
* @param maxRegionDistanceSq The maximum region distance, squared
|
||||||
* @return The locations found that match the special block
|
* @return The locations found that match the special block
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -50,19 +50,17 @@ public interface IWaypointCollection {
|
|||||||
/**
|
/**
|
||||||
* Gets all of the waypoints that have the specified tag
|
* Gets all of the waypoints that have the specified tag
|
||||||
*
|
*
|
||||||
* @see IWaypointCollection#getAllWaypoints()
|
|
||||||
*
|
|
||||||
* @param tag The tag
|
* @param tag The tag
|
||||||
* @return All of the waypoints with the specified tag
|
* @return All of the waypoints with the specified tag
|
||||||
|
* @see IWaypointCollection#getAllWaypoints()
|
||||||
*/
|
*/
|
||||||
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all of the waypoints in this collection, regardless of the tag.
|
* Gets all of the waypoints in this collection, regardless of the tag.
|
||||||
*
|
*
|
||||||
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
|
||||||
*
|
|
||||||
* @return All of the waypoints in this collection
|
* @return All of the waypoints in this collection
|
||||||
|
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
||||||
*/
|
*/
|
||||||
Set<IWaypoint> getAllWaypoints();
|
Set<IWaypoint> getAllWaypoints();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
import baritone.api.event.events.type.ManagedPlayerEvent;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
|
|||||||
private final Type type;
|
private final Type type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The state of the event
|
* The yaw rotation
|
||||||
*/
|
*/
|
||||||
private final EventState state;
|
private float yaw;
|
||||||
|
|
||||||
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) {
|
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
|
||||||
super(player);
|
super(player);
|
||||||
this.state = state;
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The state of the event
|
* Set the yaw movement rotation
|
||||||
|
*
|
||||||
|
* @param yaw Yaw rotation
|
||||||
*/
|
*/
|
||||||
public final EventState getState() {
|
public final void setYaw(float yaw) {
|
||||||
return this.state;
|
this.yaw = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The yaw rotation
|
||||||
|
*/
|
||||||
|
public final float getYaw() {
|
||||||
|
return this.yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,14 +24,12 @@ package baritone.api.event.events.type;
|
|||||||
public enum EventState {
|
public enum EventState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that whatever movement the event is being
|
* Before the dispatching of what the event is targetting
|
||||||
* dispatched as a result of is about to occur.
|
|
||||||
*/
|
*/
|
||||||
PRE,
|
PRE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that whatever movement the event is being
|
* After the dispatching of what the event is targetting
|
||||||
* dispatched as a result of has already occurred.
|
|
||||||
*/
|
*/
|
||||||
POST
|
POST
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import baritone.api.Settings;
|
|||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -51,7 +53,9 @@ public interface IPath {
|
|||||||
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
||||||
* (as opposed to Path objects that are just constructed every frame for rendering)
|
* (as opposed to Path objects that are just constructed every frame for rendering)
|
||||||
*/
|
*/
|
||||||
default void postProcess() {}
|
default IPath postProcess() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
||||||
@@ -117,20 +121,48 @@ public interface IPath {
|
|||||||
*
|
*
|
||||||
* @return The result of this cut-off operation
|
* @return The result of this cut-off operation
|
||||||
*/
|
*/
|
||||||
default IPath cutoffAtLoadedChunks() {
|
default IPath cutoffAtLoadedChunks(World world) {
|
||||||
return this;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
|
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
|
||||||
* Default implementation just returns this path, without the intended functionality.
|
* Default implementation just returns this path, without the intended functionality.
|
||||||
*
|
*
|
||||||
|
* @return The result of this cut-off operation
|
||||||
* @see Settings#pathCutoffMinimumLength
|
* @see Settings#pathCutoffMinimumLength
|
||||||
* @see Settings#pathCutoffFactor
|
* @see Settings#pathCutoffFactor
|
||||||
*
|
|
||||||
* @return The result of this cut-off operation
|
|
||||||
*/
|
*/
|
||||||
default IPath staticCutoff(Goal destination) {
|
default IPath staticCutoff(Goal destination) {
|
||||||
return this;
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
||||||
|
*/
|
||||||
|
default void sanityCheck() {
|
||||||
|
List<BetterBlockPos> path = positions();
|
||||||
|
List<IMovement> movements = movements();
|
||||||
|
if (!getSrc().equals(path.get(0))) {
|
||||||
|
throw new IllegalStateException("Start node does not equal first path element");
|
||||||
|
}
|
||||||
|
if (!getDest().equals(path.get(path.size() - 1))) {
|
||||||
|
throw new IllegalStateException("End node does not equal last path element");
|
||||||
|
}
|
||||||
|
if (path.size() != movements.size() + 1) {
|
||||||
|
throw new IllegalStateException("Size of path array is unexpected");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < path.size() - 1; i++) {
|
||||||
|
BlockPos src = path.get(i);
|
||||||
|
BlockPos dest = path.get(i + 1);
|
||||||
|
IMovement movement = movements.get(i);
|
||||||
|
if (!src.equals(movement.getSrc())) {
|
||||||
|
throw new IllegalStateException("Path source is not equal to the movement source");
|
||||||
|
}
|
||||||
|
if (!dest.equals(movement.getDest())) {
|
||||||
|
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package baritone.api.pathing.calc;
|
package baritone.api.pathing.calc;
|
||||||
|
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ public interface IPathFinder {
|
|||||||
*
|
*
|
||||||
* @return The final path
|
* @return The final path
|
||||||
*/
|
*/
|
||||||
Optional<IPath> calculate(long timeout);
|
PathCalculationResult calculate(long timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package baritone.api.pathing.goals;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful for automated combat (retreating specifically)
|
* Useful for automated combat (retreating specifically)
|
||||||
@@ -32,16 +33,26 @@ public class GoalRunAway implements Goal {
|
|||||||
|
|
||||||
private final double distanceSq;
|
private final double distanceSq;
|
||||||
|
|
||||||
|
private final Optional<Integer> maintainY;
|
||||||
|
|
||||||
public GoalRunAway(double distance, BlockPos... from) {
|
public GoalRunAway(double distance, BlockPos... from) {
|
||||||
|
this(distance, Optional.empty(), from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoalRunAway(double distance, Optional<Integer> maintainY, BlockPos... from) {
|
||||||
if (from.length == 0) {
|
if (from.length == 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.distanceSq = distance * distance;
|
this.distanceSq = distance * distance;
|
||||||
|
this.maintainY = maintainY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(int x, int y, int z) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
if (maintainY.isPresent() && maintainY.get() != y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (BlockPos p : from) {
|
for (BlockPos p : from) {
|
||||||
int diffX = x - p.getX();
|
int diffX = x - p.getX();
|
||||||
int diffZ = z - p.getZ();
|
int diffZ = z - p.getZ();
|
||||||
@@ -62,11 +73,19 @@ public class GoalRunAway implements Goal {
|
|||||||
min = h;
|
min = h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -min;
|
min = -min;
|
||||||
|
if (maintainY.isPresent()) {
|
||||||
|
min = min * 0.5 + GoalYLevel.calculate(maintainY.get(), y);
|
||||||
|
}
|
||||||
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GoalRunAwayFrom" + Arrays.asList(from);
|
if (maintainY.isPresent()) {
|
||||||
|
return "GoalRunAwayFromMaintainY y=" + maintainY.get() + ", " + Arrays.asList(from);
|
||||||
|
} else {
|
||||||
|
return "GoalRunAwayFrom" + Arrays.asList(from);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
|
import baritone.api.event.events.PathEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A process that can control the PathingBehavior.
|
||||||
|
* <p>
|
||||||
|
* Differences between a baritone process and a behavior:
|
||||||
|
* Only one baritone process can be active at a time
|
||||||
|
* PathingBehavior can only be controlled by a process
|
||||||
|
* <p>
|
||||||
|
* That's it actually
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public interface IBaritoneProcess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Would this process like to be in control?
|
||||||
|
*
|
||||||
|
* @return Whether or not this process would like to be in contorl.
|
||||||
|
*/
|
||||||
|
boolean isActive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when this process is in control of pathing; Returns what Baritone should do.
|
||||||
|
*
|
||||||
|
* @param calcFailed {@code true} if this specific process was in control last tick,
|
||||||
|
* and there was a {@link PathEvent#CALC_FAILED} event last tick
|
||||||
|
* @param isSafeToCancel {@code true} if a {@link PathingCommandType#REQUEST_PAUSE} would happen this tick, and
|
||||||
|
* {@link IPathingBehavior} wouldn't actually tick. {@code false} if the PathExecutor reported
|
||||||
|
* pausing would be unsafe at the end of the last tick. Effectively "could request cancel or
|
||||||
|
* pause and have it happen right away"
|
||||||
|
* @return What the {@link IPathingBehavior} should do
|
||||||
|
*/
|
||||||
|
PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this process should be treated as "temporary".
|
||||||
|
* <p>
|
||||||
|
* If a process is temporary, it doesn't call {@link #onLostControl} on the processes that aren't execute because of it.
|
||||||
|
* <p>
|
||||||
|
* For example, {@code CombatPauserProcess} and {@code PauseForAutoEatProcess} should return {@code true} always,
|
||||||
|
* and should return {@link #isActive} {@code true} only if there's something in range this tick, or if the player would like
|
||||||
|
* to start eating this tick. {@code PauseForAutoEatProcess} should only actually right click once onTick is called with
|
||||||
|
* {@code isSafeToCancel} true though.
|
||||||
|
*
|
||||||
|
* @return Whethor or not if this control is temporary
|
||||||
|
*/
|
||||||
|
boolean isTemporary();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if {@link #isActive} returned {@code true}, but another non-temporary
|
||||||
|
* process has control. Effectively the same as cancel. You want control but you
|
||||||
|
* don't get it.
|
||||||
|
*/
|
||||||
|
void onLostControl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine which Process gains control if multiple are reporting {@link #isActive()}. The one
|
||||||
|
* that returns the highest value will be given control.
|
||||||
|
*
|
||||||
|
* @return A double representing the priority
|
||||||
|
*/
|
||||||
|
double priority();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns which bot this process is associated with. (5000000iq forward thinking)
|
||||||
|
*
|
||||||
|
* @return The Bot associated with this process
|
||||||
|
*/
|
||||||
|
IBaritone associatedWith();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a user-friendly name for this process. Suitable for a HUD.
|
||||||
|
*
|
||||||
|
* @return A display name that's suitable for a HUD
|
||||||
|
*/
|
||||||
|
String displayName();
|
||||||
|
}
|
||||||
+23
-27
@@ -15,40 +15,36 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.utils.interfaces;
|
package baritone.api.process;
|
||||||
|
|
||||||
/**
|
import baritone.api.pathing.goals.Goal;
|
||||||
* @author Brady
|
|
||||||
* @since 8/20/2018
|
public interface ICustomGoalProcess extends IBaritoneProcess {
|
||||||
*/
|
|
||||||
public interface Toggleable {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the enabled state of this {@link Toggleable}.
|
* Sets the pathing goal
|
||||||
*
|
*
|
||||||
* @return The new state.
|
* @param goal The new goal
|
||||||
*/
|
*/
|
||||||
boolean toggle();
|
void setGoal(Goal goal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the enabled state of this {@link Toggleable}.
|
* Starts path calculation and execution.
|
||||||
|
*/
|
||||||
|
void path();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current goal
|
||||||
|
*/
|
||||||
|
Goal getGoal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the goal and begins the path execution.
|
||||||
*
|
*
|
||||||
* @return The new state.
|
* @param goal The new goal
|
||||||
*/
|
*/
|
||||||
boolean setEnabled(boolean enabled);
|
default void setGoalAndPath(Goal goal) {
|
||||||
|
this.setGoal(goal);
|
||||||
/**
|
this.path();
|
||||||
* @return Whether or not this {@link Toggleable} object is enabled
|
}
|
||||||
*/
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the state changes from disabled to enabled
|
|
||||||
*/
|
|
||||||
default void onEnable() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the state changes from enabled to disabled
|
|
||||||
*/
|
|
||||||
default void onDisable() {}
|
|
||||||
}
|
}
|
||||||
+15
-8
@@ -15,30 +15,37 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.behavior;
|
package baritone.api.process;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IFollowBehavior extends IBehavior {
|
public interface IFollowProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the follow target to the specified entity;
|
* Set the follow target to any entities matching this predicate
|
||||||
*
|
*
|
||||||
* @param entity The entity to follow
|
* @param filter the predicate
|
||||||
*/
|
*/
|
||||||
void follow(Entity entity);
|
void follow(Predicate<Entity> filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The entity that is currently being followed
|
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
|
||||||
*/
|
*/
|
||||||
Entity following();
|
List<Entity> following();
|
||||||
|
|
||||||
|
Predicate<Entity> currentFilter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the follow behavior, this will clear the current follow target.
|
* Cancels the follow behavior, this will clear the current follow target.
|
||||||
*/
|
*/
|
||||||
void cancel();
|
default void cancel() {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* but it rescans the world every once in a while so it doesn't get fooled by its cache
|
||||||
|
*/
|
||||||
|
public interface IGetToBlockProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
|
void getToBlock(Block block);
|
||||||
|
}
|
||||||
+11
-9
@@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.behavior;
|
package baritone.api.process;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import net.minecraft.block.Block;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IMineBehavior extends IBehavior {
|
public interface IMineProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin to search for and mine the specified blocks until
|
* Begin to search for and mine the specified blocks until
|
||||||
@@ -31,9 +31,9 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* are mined. This is based on the first target block to mine.
|
* are mined. This is based on the first target block to mine.
|
||||||
*
|
*
|
||||||
* @param quantity The number of items to get from blocks mined
|
* @param quantity The number of items to get from blocks mined
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
void mine(int quantity, String... blocks);
|
void mineByName(int quantity, String... blocks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin to search for and mine the specified blocks until
|
* Begin to search for and mine the specified blocks until
|
||||||
@@ -41,7 +41,7 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* are mined. This is based on the first target block to mine.
|
* are mined. This is based on the first target block to mine.
|
||||||
*
|
*
|
||||||
* @param quantity The number of items to get from blocks mined
|
* @param quantity The number of items to get from blocks mined
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
void mine(int quantity, Block... blocks);
|
void mine(int quantity, Block... blocks);
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
*
|
*
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
default void mine(String... blocks) {
|
default void mineByName(String... blocks) {
|
||||||
this.mine(0, blocks);
|
mineByName(0, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,11 +60,13 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
default void mine(Block... blocks) {
|
default void mine(Block... blocks) {
|
||||||
this.mine(0, blocks);
|
mine(0, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the current mining task
|
* Cancels the current mining task
|
||||||
*/
|
*/
|
||||||
void cancel();
|
default void cancel() {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class PathingCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target goal, may be {@code null}.
|
||||||
|
*/
|
||||||
|
public final Goal goal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The command type.
|
||||||
|
*
|
||||||
|
* @see PathingCommandType
|
||||||
|
*/
|
||||||
|
public final PathingCommandType commandType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link PathingCommand}.
|
||||||
|
*
|
||||||
|
* @param goal The target goal, may be {@code null}.
|
||||||
|
* @param commandType The command type, cannot be {@code null}.
|
||||||
|
* @throws NullPointerException if {@code commandType} is {@code null}.
|
||||||
|
* @see Goal
|
||||||
|
* @see PathingCommandType
|
||||||
|
*/
|
||||||
|
public PathingCommand(Goal goal, PathingCommandType commandType) {
|
||||||
|
Objects.requireNonNull(commandType);
|
||||||
|
|
||||||
|
this.goal = goal;
|
||||||
|
this.commandType = commandType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.Settings;
|
||||||
|
|
||||||
|
public enum PathingCommandType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* If you use this alongside a {@code null} goal, it will continue along its current path and current goal.
|
||||||
|
*/
|
||||||
|
SET_GOAL_AND_PATH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has no effect on the current goal or path, just requests a pause
|
||||||
|
*/
|
||||||
|
REQUEST_PAUSE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal (regardless of {@code null}), and request a cancel of the current path (when safe)
|
||||||
|
*/
|
||||||
|
CANCEL_AND_SET_GOAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* If {@link Settings#cancelOnGoalInvalidation} is {@code true}, revalidate the
|
||||||
|
* current goal, and cancel if it's no longer valid, or if the new goal is {@code null}.
|
||||||
|
*/
|
||||||
|
REVALIDATE_GOAL_AND_PATH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* Cancel the current path if the goals are not equal
|
||||||
|
*/
|
||||||
|
FORCE_REVALIDATE_GOAL_AND_PATH
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class PathCalculationResult {
|
||||||
|
|
||||||
|
public final Optional<IPath> path;
|
||||||
|
public final Type type;
|
||||||
|
|
||||||
|
public PathCalculationResult(Type type, Optional<IPath> path) {
|
||||||
|
this.path = path;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
SUCCESS_TO_GOAL,
|
||||||
|
SUCCESS_SEGMENT,
|
||||||
|
FAILURE,
|
||||||
|
CANCELLATION,
|
||||||
|
EXCEPTION,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,43 +30,11 @@ import java.util.Optional;
|
|||||||
* @since 8/25/2018
|
* @since 8/25/2018
|
||||||
*/
|
*/
|
||||||
public final class RayTraceUtils {
|
public final class RayTraceUtils {
|
||||||
/**
|
|
||||||
* The {@link Minecraft} instance
|
|
||||||
*/
|
|
||||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
private RayTraceUtils() {}
|
private RayTraceUtils() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
|
|
||||||
* will be that of the next render pass given that the local player's yaw and
|
|
||||||
* pitch match the specified yaw and pitch values. This is particularly useful
|
|
||||||
* when you would like to simulate a "legit" raytrace with certainty that the only
|
|
||||||
* thing to achieve the desired outcome (whether it is hitting and entity or placing
|
|
||||||
* a block) can be done just by modifying user input.
|
|
||||||
*
|
|
||||||
* @param yaw The yaw to raytrace with
|
|
||||||
* @param pitch The pitch to raytrace with
|
|
||||||
* @return The calculated raytrace result
|
|
||||||
*/
|
|
||||||
public static RayTraceResult simulateRayTrace(float yaw, float pitch) {
|
|
||||||
RayTraceResult oldTrace = mc.objectMouseOver;
|
|
||||||
float oldYaw = mc.player.rotationYaw;
|
|
||||||
float oldPitch = mc.player.rotationPitch;
|
|
||||||
|
|
||||||
mc.player.rotationYaw = yaw;
|
|
||||||
mc.player.rotationPitch = pitch;
|
|
||||||
|
|
||||||
mc.entityRenderer.getMouseOver(1.0F);
|
|
||||||
RayTraceResult result = mc.objectMouseOver;
|
|
||||||
mc.objectMouseOver = oldTrace;
|
|
||||||
|
|
||||||
mc.player.rotationYaw = oldYaw;
|
|
||||||
mc.player.rotationPitch = oldPitch;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a block raytrace with the specified rotations. This should only be used when
|
* Performs a block raytrace with the specified rotations. This should only be used when
|
||||||
* any entity collisions can be ignored, because this method will not recognize if an
|
* any entity collisions can be ignored, because this method will not recognize if an
|
||||||
@@ -75,9 +43,8 @@ public final class RayTraceUtils {
|
|||||||
* @param rotation The rotation to raytrace towards
|
* @param rotation The rotation to raytrace towards
|
||||||
* @return The calculated raytrace result
|
* @return The calculated raytrace result
|
||||||
*/
|
*/
|
||||||
public static RayTraceResult rayTraceTowards(Rotation rotation) {
|
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
||||||
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
Vec3d start = entity.getPositionEyes(1.0F);
|
||||||
Vec3d start = mc.player.getPositionEyes(1.0F);
|
|
||||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||||
Vec3d end = start.add(
|
Vec3d end = start.add(
|
||||||
direction.x * blockReachDistance,
|
direction.x * blockReachDistance,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class Rotation {
|
|||||||
public Rotation clamp() {
|
public Rotation clamp() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
this.yaw,
|
this.yaw,
|
||||||
RotationUtils.clampPitch(this.pitch)
|
clampPitch(this.pitch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public class Rotation {
|
|||||||
*/
|
*/
|
||||||
public Rotation normalize() {
|
public Rotation normalize() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
RotationUtils.normalizeYaw(this.yaw),
|
normalizeYaw(this.yaw),
|
||||||
this.pitch
|
this.pitch
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -105,8 +105,35 @@ public class Rotation {
|
|||||||
*/
|
*/
|
||||||
public Rotation normalizeAndClamp() {
|
public Rotation normalizeAndClamp() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
RotationUtils.normalizeYaw(this.yaw),
|
normalizeYaw(this.yaw),
|
||||||
RotationUtils.clampPitch(this.pitch)
|
clampPitch(this.pitch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps the specified pitch value between -90 and 90.
|
||||||
|
*
|
||||||
|
* @param pitch The input pitch
|
||||||
|
* @return The clamped pitch
|
||||||
|
*/
|
||||||
|
public static float clampPitch(float pitch) {
|
||||||
|
return Math.max(-90, Math.min(90, pitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the specified yaw value between -180 and 180.
|
||||||
|
*
|
||||||
|
* @param yaw The input yaw
|
||||||
|
* @return The normalized yaw
|
||||||
|
*/
|
||||||
|
public static float normalizeYaw(float yaw) {
|
||||||
|
float newYaw = yaw % 360F;
|
||||||
|
if (newYaw < -180F) {
|
||||||
|
newYaw += 360F;
|
||||||
|
}
|
||||||
|
if (newYaw >= 180F) {
|
||||||
|
newYaw -= 360F;
|
||||||
|
}
|
||||||
|
return newYaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package baritone.api.utils;
|
|||||||
|
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
|
|
||||||
@@ -31,11 +30,6 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public final class RotationUtils {
|
public final class RotationUtils {
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Minecraft} instance
|
|
||||||
*/
|
|
||||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant that a degree value is multiplied by to get the equivalent radian value
|
* Constant that a degree value is multiplied by to get the equivalent radian value
|
||||||
*/
|
*/
|
||||||
@@ -60,33 +54,6 @@ public final class RotationUtils {
|
|||||||
|
|
||||||
private RotationUtils() {}
|
private RotationUtils() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamps the specified pitch value between -90 and 90.
|
|
||||||
*
|
|
||||||
* @param pitch The input pitch
|
|
||||||
* @return The clamped pitch
|
|
||||||
*/
|
|
||||||
public static float clampPitch(float pitch) {
|
|
||||||
return Math.max(-90, Math.min(90, pitch));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalizes the specified yaw value between -180 and 180.
|
|
||||||
*
|
|
||||||
* @param yaw The input yaw
|
|
||||||
* @return The normalized yaw
|
|
||||||
*/
|
|
||||||
public static float normalizeYaw(float yaw) {
|
|
||||||
float newYaw = yaw % 360F;
|
|
||||||
if (newYaw < -180F) {
|
|
||||||
newYaw += 360F;
|
|
||||||
}
|
|
||||||
if (newYaw >= 180F) {
|
|
||||||
newYaw -= 360F;
|
|
||||||
}
|
|
||||||
return newYaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
|
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
|
||||||
*
|
*
|
||||||
@@ -168,7 +135,7 @@ public final class RotationUtils {
|
|||||||
* @param pos The target block position
|
* @param pos The target block position
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachable(Entity entity, BlockPos pos) {
|
public static Optional<Rotation> reachable(Entity entity, BlockPos pos, double blockReachDistance) {
|
||||||
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
|
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
|
||||||
/*
|
/*
|
||||||
* why add 0.0001?
|
* why add 0.0001?
|
||||||
@@ -182,19 +149,19 @@ public final class RotationUtils {
|
|||||||
*/
|
*/
|
||||||
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
||||||
}
|
}
|
||||||
Optional<Rotation> possibleRotation = reachableCenter(entity, pos);
|
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance);
|
||||||
//System.out.println("center: " + possibleRotation);
|
//System.out.println("center: " + possibleRotation);
|
||||||
if (possibleRotation.isPresent()) {
|
if (possibleRotation.isPresent()) {
|
||||||
return possibleRotation;
|
return possibleRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
IBlockState state = mc.world.getBlockState(pos);
|
IBlockState state = entity.world.getBlockState(pos);
|
||||||
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
|
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
||||||
if (possibleRotation.isPresent()) {
|
if (possibleRotation.isPresent()) {
|
||||||
return possibleRotation;
|
return possibleRotation;
|
||||||
}
|
}
|
||||||
@@ -212,9 +179,9 @@ public final class RotationUtils {
|
|||||||
* @param offsetPos The position of the block with the offset applied.
|
* @param offsetPos The position of the block with the offset applied.
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos) {
|
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||||
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||||
//System.out.println(result);
|
//System.out.println(result);
|
||||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
if (result.getBlockPos().equals(pos)) {
|
if (result.getBlockPos().equals(pos)) {
|
||||||
@@ -235,7 +202,7 @@ public final class RotationUtils {
|
|||||||
* @param pos The target block position
|
* @param pos The target block position
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos) {
|
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance) {
|
||||||
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos));
|
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos), blockReachDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ import java.io.File;
|
|||||||
@Mixin(AnvilChunkLoader.class)
|
@Mixin(AnvilChunkLoader.class)
|
||||||
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
||||||
|
|
||||||
@Shadow @Final private File chunkSaveLocation;
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private File chunkSaveLocation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getChunkSaveLocation() {
|
public File getChunkSaveLocation() {
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ public class MixinBlockPos extends Vec3i {
|
|||||||
super(xIn, yIn, zIn);
|
super(xIn, yIn, zIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this was to ensure a friendly name for when we print raw
|
||||||
|
* block positions to chat in the context of an obfuscated environment.
|
||||||
|
*
|
||||||
|
* @return a string representation of the object.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||||||
@Mixin(ChunkProviderServer.class)
|
@Mixin(ChunkProviderServer.class)
|
||||||
public class MixinChunkProviderServer implements IChunkProviderServer {
|
public class MixinChunkProviderServer implements IChunkProviderServer {
|
||||||
|
|
||||||
@Shadow @Final private IChunkLoader chunkLoader;
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private IChunkLoader chunkLoader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkLoader getChunkLoader() {
|
public IChunkLoader getChunkLoader() {
|
||||||
|
|||||||
@@ -19,14 +19,17 @@ package baritone.launch.mixins;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/21/2018
|
* @since 8/21/2018
|
||||||
@@ -34,23 +37,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public class MixinEntity {
|
public class MixinEntity {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public float rotationYaw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called to override the movement direction when walking
|
||||||
|
*/
|
||||||
|
private RotationMoveEvent motionUpdateRotationEvent;
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "moveRelative",
|
method = "moveRelative",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
||||||
Entity _this = (Entity) (Object) this;
|
// noinspection ConstantConditions
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
if (EntityPlayerSP.class.isInstance(this)) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
|
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
||||||
|
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Redirect(
|
||||||
method = "moveRelative",
|
method = "moveRelative",
|
||||||
at = @At("RETURN")
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
opcode = GETFIELD,
|
||||||
|
target = "net/minecraft/entity/Entity.rotationYaw:F"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
private float overrideYaw(Entity self) {
|
||||||
Entity _this = (Entity) (Object) this;
|
if (self instanceof EntityPlayerSP) {
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
return this.motionUpdateRotationEvent.getYaw();
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
|
}
|
||||||
|
return self.rotationYaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,41 +19,59 @@ package baritone.launch.mixins;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/10/2018
|
* @since 9/10/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(EntityLivingBase.class)
|
@Mixin(EntityLivingBase.class)
|
||||||
public class MixinEntityLivingBase {
|
public abstract class MixinEntityLivingBase extends Entity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called to override the movement direction when jumping
|
||||||
|
*/
|
||||||
|
private RotationMoveEvent jumpRotationEvent;
|
||||||
|
|
||||||
|
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||||
|
super(worldIn);
|
||||||
|
this.jumpRotationEvent = jumpRotationEvent;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "jump",
|
method = "jump",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preJump(CallbackInfo ci) {
|
private void preMoveRelative(CallbackInfo ci) {
|
||||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
// noinspection ConstantConditions
|
||||||
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
|
if (EntityPlayerSP.class.isInstance(this)) {
|
||||||
// but proguard isn't smart enough to optimize out this Class.isInstance =)
|
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Redirect(
|
||||||
method = "jump",
|
method = "jump",
|
||||||
at = @At("RETURN")
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
opcode = GETFIELD,
|
||||||
|
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
private void postJump(CallbackInfo ci) {
|
private float overrideYaw(EntityLivingBase self) {
|
||||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
if (self instanceof EntityPlayerSP) {
|
||||||
// See above
|
return this.jumpRotationEvent.getYaw();
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
}
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
|
return self.rotationYaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,6 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||||
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
|
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
|
||||||
return (!pathingBehavior.isEnabled() || !pathingBehavior.isPathing()) && capabilities.allowFlying;
|
return !pathingBehavior.isPathing() && capabilities.allowFlying;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class MixinEntityRenderer {
|
|||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE_STRING",
|
value = "INVOKE_STRING",
|
||||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||||
args = { "ldc=hand" }
|
args = {"ldc=hand"}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||||
|
|||||||
@@ -83,10 +83,9 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void runTick(CallbackInfo ci) {
|
private void runTick(CallbackInfo ci) {
|
||||||
Minecraft mc = (Minecraft) (Object) this;
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onTick(new TickEvent(
|
Baritone.INSTANCE.getGameEventHandler().onTick(new TickEvent(
|
||||||
EventState.PRE,
|
EventState.PRE,
|
||||||
(mc.player != null && mc.world != null)
|
(player != null && world != null)
|
||||||
? TickEvent.Type.IN
|
? TickEvent.Type.IN
|
||||||
: TickEvent.Type.OUT
|
: TickEvent.Type.OUT
|
||||||
));
|
));
|
||||||
@@ -142,7 +141,7 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean isAllowUserInput(GuiScreen screen) {
|
private boolean isAllowUserInput(GuiScreen screen) {
|
||||||
return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && Baritone.INSTANCE.getPathingBehavior().isEnabled() && player != null) || screen.allowUserInput;
|
return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && player != null) || screen.allowUserInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ public class MixinNetworkManager {
|
|||||||
)
|
)
|
||||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));}
|
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
|
|||||||
@@ -18,16 +18,24 @@
|
|||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.IBaritoneProvider;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.Settings;
|
import baritone.api.Settings;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
import baritone.behavior.*;
|
import baritone.behavior.Behavior;
|
||||||
|
import baritone.behavior.LookBehavior;
|
||||||
|
import baritone.behavior.MemoryBehavior;
|
||||||
|
import baritone.behavior.PathingBehavior;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.cache.WorldScanner;
|
import baritone.cache.WorldScanner;
|
||||||
import baritone.event.GameEventHandler;
|
import baritone.event.GameEventHandler;
|
||||||
|
import baritone.process.CustomGoalProcess;
|
||||||
|
import baritone.process.FollowProcess;
|
||||||
|
import baritone.process.GetToBlockProcess;
|
||||||
|
import baritone.process.MineProcess;
|
||||||
import baritone.utils.BaritoneAutoTest;
|
import baritone.utils.BaritoneAutoTest;
|
||||||
import baritone.utils.ExampleBaritoneControl;
|
import baritone.utils.ExampleBaritoneControl;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
|
import baritone.utils.PathingControlManager;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -44,50 +52,57 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 10:50 PM
|
* @since 7/31/2018 10:50 PM
|
||||||
*/
|
*/
|
||||||
public enum Baritone implements IBaritoneProvider {
|
public enum Baritone implements IBaritone {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton instance of this class
|
* Singleton instance of this class
|
||||||
*/
|
*/
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
|
private static ThreadPoolExecutor threadPool;
|
||||||
|
private static File dir;
|
||||||
|
|
||||||
|
static {
|
||||||
|
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||||
|
|
||||||
|
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||||
|
if (!Files.exists(dir.toPath())) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(dir.toPath());
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not {@link Baritone#init()} has been called yet
|
* Whether or not {@link Baritone#init()} has been called yet
|
||||||
*/
|
*/
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
|
|
||||||
private GameEventHandler gameEventHandler;
|
private GameEventHandler gameEventHandler;
|
||||||
private InputOverrideHandler inputOverrideHandler;
|
|
||||||
private Settings settings;
|
|
||||||
private File dir;
|
|
||||||
private ThreadPoolExecutor threadPool;
|
|
||||||
|
|
||||||
private List<Behavior> behaviors;
|
private List<Behavior> behaviors;
|
||||||
private PathingBehavior pathingBehavior;
|
private PathingBehavior pathingBehavior;
|
||||||
private LookBehavior lookBehavior;
|
private LookBehavior lookBehavior;
|
||||||
private MemoryBehavior memoryBehavior;
|
private MemoryBehavior memoryBehavior;
|
||||||
private FollowBehavior followBehavior;
|
private InputOverrideHandler inputOverrideHandler;
|
||||||
private MineBehavior mineBehavior;
|
|
||||||
|
|
||||||
/**
|
private FollowProcess followProcess;
|
||||||
* Whether or not Baritone is active
|
private MineProcess mineProcess;
|
||||||
*/
|
private GetToBlockProcess getToBlockProcess;
|
||||||
private boolean active;
|
private CustomGoalProcess customGoalProcess;
|
||||||
|
|
||||||
|
private PathingControlManager pathingControlManager;
|
||||||
|
|
||||||
|
private WorldProvider worldProvider;
|
||||||
|
|
||||||
Baritone() {
|
Baritone() {
|
||||||
this.gameEventHandler = new GameEventHandler();
|
this.gameEventHandler = new GameEventHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void init() {
|
public synchronized void init() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
|
||||||
this.inputOverrideHandler = new InputOverrideHandler();
|
|
||||||
|
|
||||||
// Acquire the "singleton" instance of the settings directly from the API
|
|
||||||
// We might want to change this...
|
|
||||||
this.settings = BaritoneAPI.getSettings();
|
|
||||||
|
|
||||||
this.behaviors = new ArrayList<>();
|
this.behaviors = new ArrayList<>();
|
||||||
{
|
{
|
||||||
@@ -95,26 +110,29 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
pathingBehavior = new PathingBehavior(this);
|
pathingBehavior = new PathingBehavior(this);
|
||||||
lookBehavior = new LookBehavior(this);
|
lookBehavior = new LookBehavior(this);
|
||||||
memoryBehavior = new MemoryBehavior(this);
|
memoryBehavior = new MemoryBehavior(this);
|
||||||
followBehavior = new FollowBehavior(this);
|
inputOverrideHandler = new InputOverrideHandler(this);
|
||||||
mineBehavior = new MineBehavior(this);
|
|
||||||
new ExampleBaritoneControl(this);
|
new ExampleBaritoneControl(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.pathingControlManager = new PathingControlManager(this);
|
||||||
|
{
|
||||||
|
followProcess = new FollowProcess(this);
|
||||||
|
mineProcess = new MineProcess(this);
|
||||||
|
customGoalProcess = new CustomGoalProcess(this); // very high iq
|
||||||
|
getToBlockProcess = new GetToBlockProcess(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.worldProvider = new WorldProvider();
|
||||||
|
|
||||||
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
||||||
registerEventListener(BaritoneAutoTest.INSTANCE);
|
registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||||
}
|
}
|
||||||
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
|
||||||
if (!Files.exists(dir.toPath())) {
|
|
||||||
try {
|
|
||||||
Files.createDirectories(dir.toPath());
|
|
||||||
} catch (IOException ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.active = true;
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
public PathingControlManager getPathingControlManager() {
|
||||||
return this.initialized;
|
return pathingControlManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IGameEventListener getGameEventHandler() {
|
public IGameEventListener getGameEventHandler() {
|
||||||
@@ -129,18 +147,24 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
return this.behaviors;
|
return this.behaviors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Executor getExecutor() {
|
|
||||||
return threadPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerBehavior(Behavior behavior) {
|
public void registerBehavior(Behavior behavior) {
|
||||||
this.behaviors.add(behavior);
|
this.behaviors.add(behavior);
|
||||||
this.registerEventListener(behavior);
|
this.registerEventListener(behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FollowBehavior getFollowBehavior() {
|
public CustomGoalProcess getCustomGoalProcess() { // Iffy
|
||||||
return followBehavior;
|
return customGoalProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GetToBlockProcess getGetToBlockProcess() { // Iffy
|
||||||
|
return getToBlockProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FollowProcess getFollowProcess() {
|
||||||
|
return followProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -154,8 +178,8 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MineBehavior getMineBehavior() {
|
public MineProcess getMineProcess() {
|
||||||
return mineBehavior;
|
return mineProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -165,7 +189,7 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldProvider getWorldProvider() {
|
public WorldProvider getWorldProvider() {
|
||||||
return WorldProvider.INSTANCE;
|
return worldProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -178,19 +202,15 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
this.gameEventHandler.registerEventListener(listener);
|
this.gameEventHandler.registerEventListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive() {
|
|
||||||
return this.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Settings getSettings() {
|
|
||||||
return this.settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Settings settings() {
|
public static Settings settings() {
|
||||||
return Baritone.INSTANCE.settings; // yolo
|
return BaritoneAPI.getSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getDir() {
|
public static File getDir() {
|
||||||
return this.dir;
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Executor getExecutor() {
|
||||||
|
return threadPool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,59 +17,17 @@
|
|||||||
|
|
||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.IBaritoneProvider;
|
import baritone.api.IBaritoneProvider;
|
||||||
import baritone.api.behavior.*;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import baritone.api.cache.IWorldProvider;
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.cache.WorldScanner;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo fix this cancer
|
|
||||||
*
|
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/29/2018
|
* @since 9/29/2018
|
||||||
*/
|
*/
|
||||||
public final class BaritoneProvider implements IBaritoneProvider {
|
public final class BaritoneProvider implements IBaritoneProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IFollowBehavior getFollowBehavior() {
|
public IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
|
||||||
return Baritone.INSTANCE.getFollowBehavior();
|
return Baritone.INSTANCE; // pwnage
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ILookBehavior getLookBehavior() {
|
|
||||||
return Baritone.INSTANCE.getLookBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMemoryBehavior getMemoryBehavior() {
|
|
||||||
return Baritone.INSTANCE.getMemoryBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMineBehavior getMineBehavior() {
|
|
||||||
return Baritone.INSTANCE.getMineBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPathingBehavior getPathingBehavior() {
|
|
||||||
return Baritone.INSTANCE.getPathingBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldProvider getWorldProvider() {
|
|
||||||
return WorldProvider.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldScanner getWorldScanner() {
|
|
||||||
return WorldScanner.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerEventListener(IGameEventListener listener) {
|
|
||||||
Baritone.INSTANCE.registerEventListener(listener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import baritone.Baritone;
|
|||||||
import baritone.api.behavior.IBehavior;
|
import baritone.api.behavior.IBehavior;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type of game event listener that can be toggled.
|
* A type of game event listener that is given {@link Baritone} instance context.
|
||||||
*
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 6:29 PM
|
* @since 8/1/2018 6:29 PM
|
||||||
@@ -30,49 +30,8 @@ public class Behavior implements IBehavior {
|
|||||||
|
|
||||||
public final Baritone baritone;
|
public final Baritone baritone;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not this behavior is enabled
|
|
||||||
*/
|
|
||||||
private boolean enabled = true;
|
|
||||||
|
|
||||||
protected Behavior(Baritone baritone) {
|
protected Behavior(Baritone baritone) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
baritone.registerBehavior(this);
|
baritone.registerBehavior(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles the enabled state of this {@link Behavior}.
|
|
||||||
*
|
|
||||||
* @return The new state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean toggle() {
|
|
||||||
return this.setEnabled(!this.isEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the enabled state of this {@link Behavior}.
|
|
||||||
*
|
|
||||||
* @return The new state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean setEnabled(boolean enabled) {
|
|
||||||
if (enabled == this.enabled) {
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
if (this.enabled = enabled) {
|
|
||||||
this.onEnable();
|
|
||||||
} else {
|
|
||||||
this.onDisable();
|
|
||||||
}
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Whether or not this {@link Behavior} is active.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isEnabled() {
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Baritone.
|
|
||||||
*
|
|
||||||
* Baritone is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Baritone is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package baritone.behavior;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.behavior.IFollowBehavior;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.pathing.goals.GoalNear;
|
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Follow an entity
|
|
||||||
*
|
|
||||||
* @author leijurv
|
|
||||||
*/
|
|
||||||
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
|
|
||||||
|
|
||||||
private Entity following;
|
|
||||||
|
|
||||||
public FollowBehavior(Baritone baritone) {
|
|
||||||
super(baritone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTick(TickEvent event) {
|
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
|
||||||
following = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (following == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// lol this is trashy but it works
|
|
||||||
BlockPos pos;
|
|
||||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
|
||||||
pos = following.getPosition();
|
|
||||||
} else {
|
|
||||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
|
||||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
|
||||||
}
|
|
||||||
baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
|
|
||||||
((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
|
|
||||||
baritone.getPathingBehavior().path();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void follow(Entity entity) {
|
|
||||||
this.following = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Entity following() {
|
|
||||||
return this.following;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() {
|
|
||||||
baritone.getPathingBehavior().cancel();
|
|
||||||
follow(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,7 @@ import baritone.api.utils.Rotation;
|
|||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
|
|
||||||
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target's values are as follows:
|
* Target's values are as follows:
|
||||||
* <p>
|
* <p>
|
||||||
@@ -63,7 +64,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Whether or not we're going to silently set our angles
|
// Whether or not we're going to silently set our angles
|
||||||
boolean silent = Baritone.settings().antiCheatCompatibility.get();
|
boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
|
||||||
|
|
||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE: {
|
case PRE: {
|
||||||
@@ -76,14 +77,15 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
|||||||
nudgeToLevel();
|
nudgeToLevel();
|
||||||
}
|
}
|
||||||
this.target = null;
|
this.target = null;
|
||||||
} else if (silent) {
|
}
|
||||||
|
if (silent) {
|
||||||
this.lastYaw = player().rotationYaw;
|
this.lastYaw = player().rotationYaw;
|
||||||
player().rotationYaw = this.target.getYaw();
|
player().rotationYaw = this.target.getYaw();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case POST: {
|
case POST: {
|
||||||
if (!this.force && silent) {
|
if (silent) {
|
||||||
player().rotationYaw = this.lastYaw;
|
player().rotationYaw = this.lastYaw;
|
||||||
this.target = null;
|
this.target = null;
|
||||||
}
|
}
|
||||||
@@ -97,26 +99,20 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
|||||||
@Override
|
@Override
|
||||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||||
if (this.target != null && !this.force) {
|
if (this.target != null && !this.force) {
|
||||||
switch (event.getState()) {
|
|
||||||
case PRE:
|
|
||||||
this.lastYaw = player().rotationYaw;
|
|
||||||
player().rotationYaw = this.target.getYaw();
|
|
||||||
break;
|
|
||||||
case POST:
|
|
||||||
player().rotationYaw = this.lastYaw;
|
|
||||||
|
|
||||||
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
event.setYaw(this.target.getYaw());
|
||||||
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
|
||||||
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
||||||
this.target = null;
|
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
||||||
}
|
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
||||||
break;
|
this.target = null;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
|
||||||
|
*/
|
||||||
private void nudgeToLevel() {
|
private void nudgeToLevel() {
|
||||||
if (player().rotationPitch < -20) {
|
if (player().rotationPitch < -20) {
|
||||||
player().rotationPitch++;
|
player().rotationPitch++;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import baritone.api.event.events.PacketEvent;
|
|||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.block.BlockBed;
|
import net.minecraft.block.BlockBed;
|
||||||
@@ -122,13 +121,13 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
|||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerDeath() {
|
public void onPlayerDeath() {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
||||||
@@ -143,7 +142,7 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
|||||||
}
|
}
|
||||||
|
|
||||||
private WorldDataContainer getCurrentContainer() {
|
private WorldDataContainer getCurrentContainer() {
|
||||||
return this.worldDataContainers.computeIfAbsent(WorldProvider.INSTANCE.getCurrentWorld(), data -> new WorldDataContainer());
|
return this.worldDataContainers.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), data -> new WorldDataContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,12 +28,13 @@ import baritone.api.pathing.calc.IPathFinder;
|
|||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
import baritone.pathing.calc.AStarPathFinder;
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.calc.CutoffPath;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
|
import baritone.pathing.path.CutoffPath;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.BlockBreakHelper;
|
import baritone.utils.BlockBreakHelper;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
@@ -52,6 +53,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
|
|
||||||
private Goal goal;
|
private Goal goal;
|
||||||
|
|
||||||
|
private boolean safeToCancel;
|
||||||
|
private boolean pauseRequestedLastTick;
|
||||||
|
private boolean cancelRequested;
|
||||||
|
private boolean calcFailedLastTick;
|
||||||
|
|
||||||
private volatile boolean isPathCalcInProgress;
|
private volatile boolean isPathCalcInProgress;
|
||||||
private final Object pathCalcLock = new Object();
|
private final Object pathCalcLock = new Object();
|
||||||
|
|
||||||
@@ -72,8 +78,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
private void dispatchEvents() {
|
private void dispatchEvents() {
|
||||||
ArrayList<PathEvent> curr = new ArrayList<>();
|
ArrayList<PathEvent> curr = new ArrayList<>();
|
||||||
toDispatch.drainTo(curr);
|
toDispatch.drainTo(curr);
|
||||||
|
calcFailedLastTick = curr.contains(PathEvent.CALC_FAILED);
|
||||||
for (PathEvent event : curr) {
|
for (PathEvent event : curr) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
|
baritone.getGameEventHandler().onPathEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,18 +88,30 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
cancel();
|
secretInternalSegmentCancel();
|
||||||
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
baritone.getPathingControlManager().preTick();
|
||||||
tickPath();
|
tickPath();
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickPath() {
|
private void tickPath() {
|
||||||
|
if (pauseRequestedLastTick && safeToCancel) {
|
||||||
|
pauseRequestedLastTick = false;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
BlockBreakHelper.stopBreakingBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cancelRequested) {
|
||||||
|
cancelRequested = false;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean safe = current.onTick();
|
safeToCancel = current.onTick();
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
if (current.failed() || current.finished()) {
|
if (current.failed() || current.finished()) {
|
||||||
current = null;
|
current = null;
|
||||||
@@ -134,7 +153,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// at this point, we know current is in progress
|
// at this point, we know current is in progress
|
||||||
if (safe && next != null && next.snipsnapifpossible()) {
|
if (safeToCancel && next != null && next.snipsnapifpossible()) {
|
||||||
// a movement just ended; jump directly onto the next path
|
// a movement just ended; jump directly onto the next path
|
||||||
logDebug("Splicing into planned next path early...");
|
logDebug("Splicing into planned next path early...");
|
||||||
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||||
@@ -143,6 +162,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
current.onTick();
|
current.onTick();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
current = current.trySplice(next);
|
||||||
|
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (isPathCalcInProgress) {
|
||||||
// if we aren't calculating right now
|
// if we aren't calculating right now
|
||||||
@@ -191,14 +214,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void secretInternalSetGoal(Goal goal) {
|
||||||
public void setGoal(Goal goal) {
|
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setGoalAndPath(Goal goal) {
|
public boolean secretInternalSetGoalAndPath(Goal goal) {
|
||||||
setGoal(goal);
|
secretInternalSetGoal(goal);
|
||||||
return path();
|
return secretInternalPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -226,17 +248,60 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return this.current != null;
|
return this.current != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSafeToCancel() {
|
||||||
|
return current == null || safeToCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestPause() {
|
||||||
|
pauseRequestedLastTick = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean cancelSegmentIfSafe() {
|
||||||
|
if (isSafeToCancel()) {
|
||||||
|
secretInternalSegmentCancel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public boolean cancelEverything() {
|
||||||
|
boolean doIt = isSafeToCancel();
|
||||||
|
if (doIt) {
|
||||||
|
secretInternalSegmentCancel();
|
||||||
|
}
|
||||||
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
|
return doIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean calcFailedLastTick() { // NOT exposed on public api
|
||||||
|
return calcFailedLastTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void softCancelIfSafe() {
|
||||||
|
if (!isSafeToCancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
current = null;
|
||||||
|
next = null;
|
||||||
|
cancelRequested = true;
|
||||||
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
|
// do everything BUT clear keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// just cancel the current path
|
||||||
|
public void secretInternalSegmentCancel() {
|
||||||
queuePathEvent(PathEvent.CANCELED);
|
queuePathEvent(PathEvent.CANCELED);
|
||||||
current = null;
|
current = null;
|
||||||
next = null;
|
next = null;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
BlockBreakHelper.stopBreakingBlock();
|
BlockBreakHelper.stopBreakingBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forceCancel() { // NOT exposed on public api
|
public void forceCancel() { // NOT exposed on public api
|
||||||
|
cancelEverything();
|
||||||
|
secretInternalSegmentCancel();
|
||||||
isPathCalcInProgress = false;
|
isPathCalcInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,8 +310,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
*
|
*
|
||||||
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
||||||
*/
|
*/
|
||||||
@Override
|
public boolean secretInternalPath() {
|
||||||
public boolean path() {
|
|
||||||
if (goal == null) {
|
if (goal == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -327,15 +391,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
isPathCalcInProgress = true;
|
isPathCalcInProgress = true;
|
||||||
}
|
}
|
||||||
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
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(() -> {
|
Baritone.getExecutor().execute(() -> {
|
||||||
if (talkAboutIt) {
|
if (talkAboutIt) {
|
||||||
logDebug("Starting to search for path from " + start + " to " + goal);
|
logDebug("Starting to search for path from " + start + " to " + goal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<IPath> path = findPath(start, previous, context);
|
PathCalculationResult calcResult = findPath(start, previous, context);
|
||||||
|
Optional<IPath> path = calcResult.path;
|
||||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
||||||
path = path.map(p -> {
|
path = path.map(p -> {
|
||||||
IPath result = p.cutoffAtLoadedChunks();
|
IPath result = p.cutoffAtLoadedChunks(context.world());
|
||||||
|
|
||||||
if (result instanceof CutoffPath) {
|
if (result instanceof CutoffPath) {
|
||||||
logDebug("Cutting off path at edge of loaded chunks");
|
logDebug("Cutting off path at edge of loaded chunks");
|
||||||
@@ -364,7 +429,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||||
current = executor.get();
|
current = executor.get();
|
||||||
} else {
|
} else {
|
||||||
queuePathEvent(PathEvent.CALC_FAILED);
|
if (calcResult.type != PathCalculationResult.Type.CANCELLATION && calcResult.type != PathCalculationResult.Type.EXCEPTION) {
|
||||||
|
// don't dispatch CALC_FAILED on cancellation
|
||||||
|
queuePathEvent(PathEvent.CALC_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
@@ -378,18 +446,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
throw new IllegalStateException("I have no idea what to do with this path");
|
throw new IllegalStateException("I have no idea what to do with this path");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||||
|
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
} else {
|
||||||
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||||
} else {
|
}
|
||||||
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
}
|
||||||
|
synchronized (pathCalcLock) {
|
||||||
|
isPathCalcInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
synchronized (pathCalcLock) {
|
|
||||||
isPathCalcInProgress = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -400,19 +466,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
* @param start
|
* @param start
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
|
private PathCalculationResult findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
|
||||||
Goal goal = this.goal;
|
Goal goal = this.goal;
|
||||||
if (goal == null) {
|
if (goal == null) {
|
||||||
logDebug("no goal");
|
logDebug("no goal");
|
||||||
return Optional.empty();
|
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, Optional.empty());
|
||||||
}
|
}
|
||||||
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
|
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
||||||
BlockPos pos = null;
|
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||||
if (goal instanceof IGoalRenderPos) {
|
if (context.world().getChunk(pos) instanceof EmptyChunk) {
|
||||||
pos = ((IGoalRenderPos) goal).getGoalPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
|
|
||||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||||
goal = new GoalXZ(pos.getX(), pos.getZ());
|
goal = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
}
|
}
|
||||||
@@ -435,25 +497,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logDebug("Pathing exception: " + e);
|
logDebug("Pathing exception: " + e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return Optional.empty();
|
return new PathCalculationResult(PathCalculationResult.Type.EXCEPTION, Optional.empty());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void revalidateGoal() {
|
|
||||||
if (!Baritone.settings().cancelOnGoalInvalidation.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (pathPlanLock) {
|
|
||||||
if (current == null || goal == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Goal intended = current.getPath().getGoal();
|
|
||||||
BlockPos end = current.getPath().getDest();
|
|
||||||
if (intended.isInGoal(end) && !goal.isInGoal(end)) {
|
|
||||||
// this path used to end in the goal
|
|
||||||
// but the goal has changed, so there's no reason to continue...
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,9 +505,4 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
public void onRenderPass(RenderEvent event) {
|
public void onRenderPass(RenderEvent event) {
|
||||||
PathRenderer.render(event, this);
|
PathRenderer.render(event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-6
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.api.cache.IBlockTypeAccess;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -31,7 +30,7 @@ import java.util.*;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 1:04 AM
|
* @since 8/3/2018 1:04 AM
|
||||||
*/
|
*/
|
||||||
public final class CachedChunk implements IBlockTypeAccess, Helper {
|
public final class CachedChunk implements Helper {
|
||||||
|
|
||||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
||||||
|
|
||||||
@@ -143,8 +142,7 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
|||||||
calculateHeightMap();
|
calculateHeightMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
||||||
public final IBlockState getBlock(int x, int y, int z) {
|
|
||||||
int internalPos = z << 4 | x;
|
int internalPos = z << 4 | x;
|
||||||
if (heightMap[internalPos] == y) {
|
if (heightMap[internalPos] == y) {
|
||||||
// we have this exact block, it's a surface block
|
// we have this exact block, it's a surface block
|
||||||
@@ -155,10 +153,10 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
|||||||
return overview[internalPos];
|
return overview[internalPos];
|
||||||
}
|
}
|
||||||
PathingBlockType type = getType(x, y, z);
|
PathingBlockType type = getType(x, y, z);
|
||||||
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
|
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
||||||
return Blocks.BEDROCK.getDefaultState();
|
return Blocks.BEDROCK.getDefaultState();
|
||||||
}
|
}
|
||||||
return ChunkPacker.pathingTypeToBlock(type);
|
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathingBlockType getType(int x, int y, int z) {
|
private PathingBlockType getType(int x, int y, int z) {
|
||||||
|
|||||||
+5
-2
@@ -59,22 +59,25 @@ public final class CachedRegion implements ICachedRegion {
|
|||||||
*/
|
*/
|
||||||
private final int z;
|
private final int z;
|
||||||
|
|
||||||
|
private final int dimension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has this region been modified since its most recent load or save
|
* Has this region been modified since its most recent load or save
|
||||||
*/
|
*/
|
||||||
private boolean hasUnsavedChanges;
|
private boolean hasUnsavedChanges;
|
||||||
|
|
||||||
CachedRegion(int x, int z) {
|
CachedRegion(int x, int z, int dimension) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.hasUnsavedChanges = false;
|
this.hasUnsavedChanges = false;
|
||||||
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final IBlockState getBlock(int x, int y, int z) {
|
public final IBlockState getBlock(int x, int y, int z) {
|
||||||
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
return chunk.getBlock(x & 15, y, z & 15);
|
return chunk.getBlock(x & 15, y, z & 15, dimension);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -56,7 +56,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
|
|
||||||
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
CachedWorld(Path directory) {
|
private final int dimension;
|
||||||
|
|
||||||
|
CachedWorld(Path directory, int dimension) {
|
||||||
if (!Files.exists(directory)) {
|
if (!Files.exists(directory)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(directory);
|
Files.createDirectories(directory);
|
||||||
@@ -64,11 +66,12 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.directory = directory.toString();
|
this.directory = directory.toString();
|
||||||
|
this.dimension = dimension;
|
||||||
System.out.println("Cached world directory: " + directory);
|
System.out.println("Cached world directory: " + directory);
|
||||||
// Insert an invalid region element
|
// Insert an invalid region element
|
||||||
cachedRegions.put(0, null);
|
cachedRegions.put(0, null);
|
||||||
Baritone.INSTANCE.getExecutor().execute(new PackerThread());
|
Baritone.getExecutor().execute(new PackerThread());
|
||||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
Baritone.getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(30000);
|
Thread.sleep(30000);
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -165,6 +168,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
* Delete regions that are too far from the player
|
* Delete regions that are too far from the player
|
||||||
*/
|
*/
|
||||||
private synchronized void prune() {
|
private synchronized void prune() {
|
||||||
|
if (!Baritone.settings().pruneRegionsFromRAM.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
BlockPos pruneCenter = guessPosition();
|
BlockPos pruneCenter = guessPosition();
|
||||||
for (CachedRegion region : allRegions()) {
|
for (CachedRegion region : allRegions()) {
|
||||||
if (region == null) {
|
if (region == null) {
|
||||||
@@ -184,7 +190,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
|
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
|
||||||
*/
|
*/
|
||||||
private BlockPos guessPosition() {
|
private BlockPos guessPosition() {
|
||||||
WorldData data = WorldProvider.INSTANCE.getCurrentWorld();
|
WorldData data = Baritone.INSTANCE.getWorldProvider().getCurrentWorld();
|
||||||
if (data != null && data.getCachedWorld() == this) {
|
if (data != null && data.getCachedWorld() == this) {
|
||||||
return playerFeet();
|
return playerFeet();
|
||||||
}
|
}
|
||||||
@@ -238,7 +244,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
*/
|
*/
|
||||||
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
|
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
|
||||||
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
|
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
|
||||||
CachedRegion newRegion = new CachedRegion(regionX, regionZ);
|
CachedRegion newRegion = new CachedRegion(regionX, regionZ, dimension);
|
||||||
newRegion.load(this.directory);
|
newRegion.load(this.directory);
|
||||||
return newRegion;
|
return newRegion;
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-2
@@ -144,7 +144,7 @@ public final class ChunkPacker implements Helper {
|
|||||||
return PathingBlockType.SOLID;
|
return PathingBlockType.SOLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBlockState pathingTypeToBlock(PathingBlockType type) {
|
public static IBlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AIR:
|
case AIR:
|
||||||
return Blocks.AIR.getDefaultState();
|
return Blocks.AIR.getDefaultState();
|
||||||
@@ -154,7 +154,7 @@ public final class ChunkPacker implements Helper {
|
|||||||
return Blocks.LAVA.getDefaultState();
|
return Blocks.LAVA.getDefaultState();
|
||||||
case SOLID:
|
case SOLID:
|
||||||
// Dimension solid types
|
// Dimension solid types
|
||||||
switch (mc.player.dimension) {
|
switch (dimension) {
|
||||||
case -1:
|
case -1:
|
||||||
return Blocks.NETHERRACK.getDefaultState();
|
return Blocks.NETHERRACK.getDefaultState();
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
+3
-3
@@ -42,9 +42,9 @@ public class Waypoint implements IWaypoint {
|
|||||||
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
|
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
|
||||||
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
|
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
|
||||||
*
|
*
|
||||||
* @param name The waypoint name
|
* @param name The waypoint name
|
||||||
* @param tag The waypoint tag
|
* @param tag The waypoint tag
|
||||||
* @param location The waypoint location
|
* @param location The waypoint location
|
||||||
* @param creationTimestamp When the waypoint was created
|
* @param creationTimestamp When the waypoint was created
|
||||||
*/
|
*/
|
||||||
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
||||||
|
|||||||
+5
-3
@@ -35,15 +35,17 @@ public class WorldData implements IWorldData {
|
|||||||
private final Waypoints waypoints;
|
private final Waypoints waypoints;
|
||||||
//public final MapData map;
|
//public final MapData map;
|
||||||
public final Path directory;
|
public final Path directory;
|
||||||
|
public final int dimension;
|
||||||
|
|
||||||
WorldData(Path directory) {
|
WorldData(Path directory, int dimension) {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.cache = new CachedWorld(directory.resolve("cache"));
|
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
|
||||||
this.waypoints = new Waypoints(directory.resolve("waypoints"));
|
this.waypoints = new Waypoints(directory.resolve("waypoints"));
|
||||||
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClose() {
|
public void onClose() {
|
||||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
Baritone.getExecutor().execute(() -> {
|
||||||
System.out.println("Started saving the world in a new thread");
|
System.out.println("Started saving the world in a new thread");
|
||||||
cache.save();
|
cache.save();
|
||||||
});
|
});
|
||||||
|
|||||||
+22
-18
@@ -22,7 +22,6 @@ import baritone.api.cache.IWorldProvider;
|
|||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||||
import baritone.utils.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
|
|
||||||
@@ -39,11 +38,9 @@ import java.util.function.Consumer;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:06 AM
|
* @since 8/4/2018 11:06 AM
|
||||||
*/
|
*/
|
||||||
public enum WorldProvider implements IWorldProvider, Helper {
|
public class WorldProvider implements IWorldProvider, Helper {
|
||||||
|
|
||||||
INSTANCE;
|
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
|
||||||
|
|
||||||
private final Map<Path, WorldData> worldCache = new HashMap<>();
|
|
||||||
|
|
||||||
private WorldData currentWorld;
|
private WorldData currentWorld;
|
||||||
|
|
||||||
@@ -52,13 +49,20 @@ public enum WorldProvider implements IWorldProvider, Helper {
|
|||||||
return this.currentWorld;
|
return this.currentWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void initWorld(WorldClient world) {
|
/**
|
||||||
int dimensionID = world.provider.getDimensionType().getId();
|
* Called when a new world is initialized to discover the
|
||||||
File directory;
|
*
|
||||||
File readme;
|
* @param dimension The ID of the world's dimension
|
||||||
|
*/
|
||||||
|
public final void initWorld(int dimension) {
|
||||||
|
// Fight me @leijurv
|
||||||
|
File directory, readme;
|
||||||
|
|
||||||
IntegratedServer integratedServer = mc.getIntegratedServer();
|
IntegratedServer integratedServer = mc.getIntegratedServer();
|
||||||
|
|
||||||
|
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
|
||||||
if (integratedServer != null) {
|
if (integratedServer != null) {
|
||||||
WorldServer localServerWorld = integratedServer.getWorld(dimensionID);
|
WorldServer localServerWorld = integratedServer.getWorld(dimension);
|
||||||
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
||||||
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
||||||
directory = loader.getChunkSaveLocation();
|
directory = loader.getChunkSaveLocation();
|
||||||
@@ -71,27 +75,27 @@ public enum WorldProvider implements IWorldProvider, Helper {
|
|||||||
|
|
||||||
directory = new File(directory, "baritone");
|
directory = new File(directory, "baritone");
|
||||||
readme = directory;
|
readme = directory;
|
||||||
|
} else { // Otherwise, the server must be remote...
|
||||||
} else {
|
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
|
||||||
//remote
|
readme = Baritone.getDir();
|
||||||
directory = new File(Baritone.INSTANCE.getDir(), mc.getCurrentServerData().serverIP);
|
|
||||||
readme = Baritone.INSTANCE.getDir();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lol wtf is this baritone folder in my minecraft save?
|
// lol wtf is this baritone folder in my minecraft save?
|
||||||
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
|
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
|
||||||
// good thing we have a readme
|
// good thing we have a readme
|
||||||
out.write("https://github.com/cabaletta/baritone\n".getBytes());
|
out.write("https://github.com/cabaletta/baritone\n".getBytes());
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
|
||||||
directory = new File(directory, "DIM" + dimensionID);
|
// We will actually store the world data in a subfolder: "DIM<id>"
|
||||||
Path dir = directory.toPath();
|
Path dir = new File(directory, "DIM" + dimension).toPath();
|
||||||
if (!Files.exists(dir)) {
|
if (!Files.exists(dir)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(dir);
|
Files.createDirectories(dir);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Baritone world data dir: " + dir);
|
System.out.println("Baritone world data dir: " + dir);
|
||||||
this.currentWorld = this.worldCache.computeIfAbsent(dir, WorldData::new);
|
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void closeWorld() {
|
public final void closeWorld() {
|
||||||
|
|||||||
@@ -21,16 +21,12 @@ import baritone.Baritone;
|
|||||||
import baritone.api.event.events.*;
|
import baritone.api.event.events.*;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
import baritone.api.utils.interfaces.Toggleable;
|
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.InputOverrideHandler;
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import org.lwjgl.input.Keyboard;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -38,57 +34,32 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public final class GameEventHandler implements IGameEventListener, Helper {
|
public final class GameEventHandler implements IGameEventListener, Helper {
|
||||||
|
|
||||||
private final ArrayList<IGameEventListener> listeners = new ArrayList<>();
|
private final Baritone baritone;
|
||||||
|
|
||||||
|
private final List<IGameEventListener> listeners = new ArrayList<>();
|
||||||
|
|
||||||
|
public GameEventHandler(Baritone baritone) {
|
||||||
|
this.baritone = baritone;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onTick(TickEvent event) {
|
public final void onTick(TickEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onTick(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onTick(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onPlayerUpdate(PlayerUpdateEvent event) {
|
public final void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPlayerUpdate(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerUpdate(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onProcessKeyBinds() {
|
public final void onProcessKeyBinds() {
|
||||||
InputOverrideHandler inputHandler = Baritone.INSTANCE.getInputOverrideHandler();
|
listeners.forEach(IGameEventListener::onProcessKeyBinds);
|
||||||
|
|
||||||
// Simulate the key being held down this tick
|
|
||||||
for (InputOverrideHandler.Input input : InputOverrideHandler.Input.values()) {
|
|
||||||
KeyBinding keyBinding = input.getKeyBinding();
|
|
||||||
|
|
||||||
if (inputHandler.isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
|
|
||||||
int keyCode = keyBinding.getKeyCode();
|
|
||||||
|
|
||||||
if (keyCode < Keyboard.KEYBOARD_SIZE) {
|
|
||||||
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onProcessKeyBinds();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendChatMessage(ChatEvent event) {
|
public final void onSendChatMessage(ChatEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onSendChatMessage(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onSendChatMessage(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -107,108 +78,67 @@ public final class GameEventHandler implements IGameEventListener, Helper {
|
|||||||
&& mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
&& mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
||||||
|
|
||||||
if (isPostPopulate || isPreUnload) {
|
if (isPostPopulate || isPreUnload) {
|
||||||
WorldProvider.INSTANCE.ifWorldLoaded(world -> {
|
baritone.getWorldProvider().ifWorldLoaded(world -> {
|
||||||
Chunk chunk = mc.world.getChunk(event.getX(), event.getZ());
|
Chunk chunk = mc.world.getChunk(event.getX(), event.getZ());
|
||||||
world.getCachedWorld().queueForPacking(chunk);
|
world.getCachedWorld().queueForPacking(chunk);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onChunkEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onChunkEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onRenderPass(RenderEvent event) {
|
public final void onRenderPass(RenderEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onRenderPass(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onRenderPass(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onWorldEvent(WorldEvent event) {
|
public final void onWorldEvent(WorldEvent event) {
|
||||||
WorldProvider cache = WorldProvider.INSTANCE;
|
WorldProvider cache = baritone.getWorldProvider();
|
||||||
|
|
||||||
BlockStateInterface.clearCachedChunk();
|
|
||||||
|
|
||||||
if (event.getState() == EventState.POST) {
|
if (event.getState() == EventState.POST) {
|
||||||
cache.closeWorld();
|
cache.closeWorld();
|
||||||
if (event.getWorld() != null) {
|
if (event.getWorld() != null) {
|
||||||
cache.initWorld(event.getWorld());
|
cache.initWorld(event.getWorld().provider.getDimensionType().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onWorldEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onWorldEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendPacket(PacketEvent event) {
|
public final void onSendPacket(PacketEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onSendPacket(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onSendPacket(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onReceivePacket(PacketEvent event) {
|
public final void onReceivePacket(PacketEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onReceivePacket(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onReceivePacket(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPlayerRotationMove(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerRotationMove(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onBlockInteract(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onBlockInteract(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerDeath() {
|
public void onPlayerDeath() {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(IGameEventListener::onPlayerDeath);
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerDeath();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPathEvent(PathEvent event) {
|
public void onPathEvent(PathEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPathEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPathEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void registerEventListener(IGameEventListener listener) {
|
public final void registerEventListener(IGameEventListener listener) {
|
||||||
this.listeners.add(listener);
|
this.listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canDispatch(IGameEventListener listener) {
|
|
||||||
return !(listener instanceof Toggleable) || ((Toggleable) listener).isEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import baritone.api.utils.BetterBlockPos;
|
|||||||
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
@@ -44,7 +43,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
private final CalculationContext calcContext;
|
private final CalculationContext calcContext;
|
||||||
|
|
||||||
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions, CalculationContext context) {
|
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions, CalculationContext context) {
|
||||||
super(startX, startY, startZ, goal);
|
super(startX, startY, startZ, goal, context);
|
||||||
this.favoredPositions = favoredPositions;
|
this.favoredPositions = favoredPositions;
|
||||||
this.calcContext = context;
|
this.calcContext = context;
|
||||||
}
|
}
|
||||||
@@ -65,8 +64,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
HashSet<Long> favored = favoredPositions.orElse(null);
|
HashSet<Long> favored = favoredPositions.orElse(null);
|
||||||
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
|
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
|
||||||
BlockStateInterface.clearCachedChunk();
|
|
||||||
long startTime = System.nanoTime() / 1000000L;
|
long startTime = System.nanoTime() / 1000000L;
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
@@ -95,12 +93,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
numNodes++;
|
numNodes++;
|
||||||
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
||||||
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal));
|
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
for (Moves moves : Moves.values()) {
|
for (Moves moves : Moves.values()) {
|
||||||
int newX = currentNode.x + moves.xOffset;
|
int newX = currentNode.x + moves.xOffset;
|
||||||
int newZ = currentNode.z + moves.zOffset;
|
int newZ = currentNode.z + moves.zOffset;
|
||||||
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !BlockStateInterface.isLoaded(newX, newZ)) {
|
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !calcContext.isLoaded(newX, newZ)) {
|
||||||
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
|
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
|
||||||
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
||||||
numEmptyChunk++;
|
numEmptyChunk++;
|
||||||
@@ -131,7 +129,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||||
}
|
}
|
||||||
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
|
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);
|
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||||
if (favoring && favored.contains(hashCode)) {
|
if (favoring && favored.contains(hashCode)) {
|
||||||
@@ -198,7 +196,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
System.out.println("But I'm going to do it anyway, because yolo");
|
System.out.println("But I'm going to do it anyway, because yolo");
|
||||||
}
|
}
|
||||||
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal));
|
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import baritone.Baritone;
|
|||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.calc.IPathFinder;
|
import baritone.api.pathing.calc.IPathFinder;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -43,6 +45,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
|
|
||||||
protected final Goal goal;
|
protected final Goal goal;
|
||||||
|
|
||||||
|
private final CalculationContext context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
||||||
*/
|
*/
|
||||||
@@ -70,11 +74,12 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
*/
|
*/
|
||||||
protected final static double MIN_DIST_PATH = 5;
|
protected final static double MIN_DIST_PATH = 5;
|
||||||
|
|
||||||
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal) {
|
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
|
||||||
this.startX = startX;
|
this.startX = startX;
|
||||||
this.startY = startY;
|
this.startY = startY;
|
||||||
this.startZ = startZ;
|
this.startZ = startZ;
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
|
this.context = context;
|
||||||
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.get());
|
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,16 +87,26 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
cancelRequested = true;
|
cancelRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Optional<IPath> calculate(long timeout) {
|
public synchronized PathCalculationResult calculate(long timeout) {
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!");
|
throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!");
|
||||||
}
|
}
|
||||||
this.cancelRequested = false;
|
this.cancelRequested = false;
|
||||||
try {
|
try {
|
||||||
Optional<IPath> path = calculate0(timeout);
|
Optional<IPath> path = calculate0(timeout);
|
||||||
path.ifPresent(IPath::postProcess);
|
path = path.map(IPath::postProcess);
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
return path;
|
if (cancelRequested) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
|
||||||
|
}
|
||||||
|
if (!path.isPresent()) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.FAILURE, path);
|
||||||
|
}
|
||||||
|
if (goal.isInGoal(path.get().getDest())) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
|
||||||
|
} else {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_SEGMENT, path);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// this is run regardless of what exception may or may not be raised by calculate0
|
// this is run regardless of what exception may or may not be raised by calculate0
|
||||||
currentlyRunning = null;
|
currentlyRunning = null;
|
||||||
@@ -160,7 +175,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
@Override
|
@Override
|
||||||
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
||||||
try {
|
try {
|
||||||
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal));
|
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
System.out.println("Unable to construct path to render");
|
System.out.println("Unable to construct path to render");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -182,7 +197,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
}
|
}
|
||||||
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
try {
|
try {
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal));
|
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context));
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
System.out.println("Unable to construct path to render");
|
System.out.println("Unable to construct path to render");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import net.minecraft.client.Minecraft;
|
import baritone.pathing.path.CutoffPath;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import baritone.utils.pathing.PathBase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -38,7 +38,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
class Path implements IPath {
|
class Path extends PathBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The start position of this path
|
* The start position of this path
|
||||||
@@ -58,20 +58,26 @@ class Path implements IPath {
|
|||||||
|
|
||||||
private final List<Movement> movements;
|
private final List<Movement> movements;
|
||||||
|
|
||||||
|
private final List<PathNode> nodes;
|
||||||
|
|
||||||
private final Goal goal;
|
private final Goal goal;
|
||||||
|
|
||||||
private final int numNodes;
|
private final int numNodes;
|
||||||
|
|
||||||
|
private final CalculationContext context;
|
||||||
|
|
||||||
private volatile boolean verified;
|
private volatile boolean verified;
|
||||||
|
|
||||||
Path(PathNode start, PathNode end, int numNodes, Goal goal) {
|
Path(PathNode start, PathNode end, int numNodes, Goal goal, CalculationContext context) {
|
||||||
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
||||||
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
||||||
this.numNodes = numNodes;
|
this.numNodes = numNodes;
|
||||||
this.path = new ArrayList<>();
|
this.path = new ArrayList<>();
|
||||||
this.movements = new ArrayList<>();
|
this.movements = new ArrayList<>();
|
||||||
|
this.nodes = new ArrayList<>();
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
assemblePath(start, end);
|
this.context = context;
|
||||||
|
assemblePath(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,88 +86,80 @@ class Path implements IPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assembles this path given the start and end nodes.
|
* Assembles this path given the end node.
|
||||||
*
|
*
|
||||||
* @param start The start node
|
* @param end The end node
|
||||||
* @param end The end node
|
|
||||||
*/
|
*/
|
||||||
private void assemblePath(PathNode start, PathNode end) {
|
private void assemblePath(PathNode end) {
|
||||||
if (!path.isEmpty() || !movements.isEmpty()) {
|
if (!path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
PathNode current = end;
|
PathNode current = end;
|
||||||
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
||||||
|
LinkedList<PathNode> tempNodes = new LinkedList();
|
||||||
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
||||||
// Instead, do it into a linked list, then convert at the end
|
// Instead, do it into a linked list, then convert at the end
|
||||||
while (!current.equals(start)) {
|
while (current != null) {
|
||||||
|
tempNodes.addFirst(current);
|
||||||
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
||||||
current = current.previous;
|
current = current.previous;
|
||||||
}
|
}
|
||||||
tempPath.addFirst(this.start);
|
|
||||||
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
||||||
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
||||||
// to performantly do that conversion since it knows the length.
|
// to performantly do that conversion since it knows the length.
|
||||||
path.addAll(tempPath);
|
path.addAll(tempPath);
|
||||||
|
nodes.addAll(tempNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean assembleMovements() {
|
||||||
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
|
||||||
*/
|
|
||||||
private void sanityCheck() {
|
|
||||||
if (!start.equals(path.get(0))) {
|
|
||||||
throw new IllegalStateException("Start node does not equal first path element");
|
|
||||||
}
|
|
||||||
if (!end.equals(path.get(path.size() - 1))) {
|
|
||||||
throw new IllegalStateException("End node does not equal last path element");
|
|
||||||
}
|
|
||||||
if (path.size() != movements.size() + 1) {
|
|
||||||
throw new IllegalStateException("Size of path array is unexpected");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
|
||||||
BlockPos src = path.get(i);
|
|
||||||
BlockPos dest = path.get(i + 1);
|
|
||||||
Movement movement = movements.get(i);
|
|
||||||
if (!src.equals(movement.getSrc())) {
|
|
||||||
throw new IllegalStateException("Path source is not equal to the movement source");
|
|
||||||
}
|
|
||||||
if (!dest.equals(movement.getDest())) {
|
|
||||||
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assembleMovements() {
|
|
||||||
if (path.isEmpty() || !movements.isEmpty()) {
|
if (path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
for (int i = 0; i < path.size() - 1; i++) {
|
||||||
movements.add(runBackwards(path.get(i), path.get(i + 1)));
|
double cost = nodes.get(i + 1).cost - nodes.get(i).cost;
|
||||||
|
Movement move = runBackwards(path.get(i), path.get(i + 1), cost);
|
||||||
|
if (move == null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
movements.add(move);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Movement runBackwards(BetterBlockPos src, BetterBlockPos dest) { // TODO this is horrifying
|
private Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) {
|
||||||
for (Moves moves : Moves.values()) {
|
for (Moves moves : Moves.values()) {
|
||||||
Movement move = moves.apply0(src);
|
Movement move = moves.apply0(context, src);
|
||||||
if (move.getDest().equals(dest)) {
|
if (move.getDest().equals(dest)) {
|
||||||
// TODO instead of recalculating here, could we take pathNode.cost - pathNode.prevNode.cost to get the cost as-calculated?
|
// have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
|
||||||
move.recalculateCost(); // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
|
move.override(cost);
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this is no longer called from bestPathSoFar, now it's in postprocessing
|
// this is no longer called from bestPathSoFar, now it's in postprocessing
|
||||||
throw new IllegalStateException("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
|
Helper.HELPER.logDebug("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcess() {
|
public IPath postProcess() {
|
||||||
if (verified) {
|
if (verified) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
verified = true;
|
verified = true;
|
||||||
assembleMovements();
|
boolean failed = assembleMovements();
|
||||||
|
movements.forEach(m -> m.checkLoadedChunk(context));
|
||||||
|
|
||||||
|
if (failed) { // at least one movement became impossible during calculation
|
||||||
|
CutoffPath res = new CutoffPath(this, movements().size());
|
||||||
|
if (res.movements().size() != movements.size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
// more post processing here
|
// more post processing here
|
||||||
movements.forEach(Movement::checkLoadedChunk);
|
|
||||||
sanityCheck();
|
sanityCheck();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,28 +189,4 @@ class Path implements IPath {
|
|||||||
public BetterBlockPos getDest() {
|
public BetterBlockPos getDest() {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPath cutoffAtLoadedChunks() {
|
|
||||||
for (int i = 0; i < positions().size(); i++) {
|
|
||||||
BlockPos pos = positions().get(i);
|
|
||||||
if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
|
|
||||||
return new CutoffPath(this, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPath staticCutoff(Goal destination) {
|
|
||||||
if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
if (destination == null || destination.isInGoal(getDest())) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
|
|
||||||
int newLength = (int) (length() * factor);
|
|
||||||
return new CutoffPath(this, newLength);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,22 +19,33 @@ package baritone.pathing.movement;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.pathing.movement.ActionCosts;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
import baritone.cache.WorldData;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.ToolSet;
|
import baritone.utils.ToolSet;
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/7/2018 4:30 PM
|
* @since 8/7/2018 4:30 PM
|
||||||
*/
|
*/
|
||||||
public class CalculationContext implements Helper {
|
public class CalculationContext {
|
||||||
|
|
||||||
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
||||||
|
|
||||||
|
private final EntityPlayerSP player;
|
||||||
|
private final World world;
|
||||||
|
private final WorldData worldData;
|
||||||
|
private final BlockStateInterface bsi;
|
||||||
private final ToolSet toolSet;
|
private final ToolSet toolSet;
|
||||||
private final boolean hasWaterBucket;
|
private final boolean hasWaterBucket;
|
||||||
private final boolean hasThrowaway;
|
private final boolean hasThrowaway;
|
||||||
@@ -48,19 +59,20 @@ public class CalculationContext implements Helper {
|
|||||||
private final BetterWorldBorder worldBorder;
|
private final BetterWorldBorder worldBorder;
|
||||||
|
|
||||||
public CalculationContext() {
|
public CalculationContext() {
|
||||||
this(new ToolSet());
|
this.player = Helper.HELPER.player();
|
||||||
}
|
this.world = Helper.HELPER.world();
|
||||||
|
this.worldData = Baritone.INSTANCE.getWorldProvider().getCurrentWorld();
|
||||||
public CalculationContext(ToolSet toolSet) {
|
this.bsi = new BlockStateInterface(world, worldData); // TODO TODO TODO
|
||||||
this.toolSet = toolSet;
|
// new CalculationContext() needs to happen, can't add an argument (i'll beat you), can we get the world provider from currentlyTicking?
|
||||||
|
this.toolSet = new ToolSet(player);
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
|
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||||
this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
|
this.canSprint = Baritone.settings().allowSprint.get() && player.getFoodStats().getFoodLevel() > 6;
|
||||||
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get();
|
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get();
|
||||||
this.allowBreak = Baritone.settings().allowBreak.get();
|
this.allowBreak = Baritone.settings().allowBreak.get();
|
||||||
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
|
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
|
||||||
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
|
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
|
||||||
int depth = EnchantmentHelper.getDepthStriderModifier(player());
|
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
||||||
if (depth > 3) {
|
if (depth > 3) {
|
||||||
depth = 3;
|
depth = 3;
|
||||||
}
|
}
|
||||||
@@ -70,7 +82,23 @@ public class CalculationContext implements Helper {
|
|||||||
// why cache these things here, why not let the movements just get directly from settings?
|
// why cache these things here, why not let the movements just get directly from settings?
|
||||||
// because if some movements are calculated one way and others are calculated another way,
|
// because if some movements are calculated one way and others are calculated another way,
|
||||||
// then you get a wildly inconsistent path that isn't optimal for either scenario.
|
// then you get a wildly inconsistent path that isn't optimal for either scenario.
|
||||||
this.worldBorder = new BetterWorldBorder(world().getWorldBorder());
|
this.worldBorder = new BetterWorldBorder(world.getWorldBorder());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState get(int x, int y, int z) {
|
||||||
|
return bsi.get0(x, y, z); // laughs maniacally
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoaded(int x, int z) {
|
||||||
|
return bsi.isLoaded(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState get(BlockPos pos) {
|
||||||
|
return get(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(int x, int y, int z) {
|
||||||
|
return get(x, y, z).getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
||||||
@@ -95,6 +123,22 @@ public class CalculationContext implements Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public World world() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayerSP player() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockStateInterface bsi() {
|
||||||
|
return bsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldData worldData() {
|
||||||
|
return worldData;
|
||||||
|
}
|
||||||
|
|
||||||
public ToolSet getToolSet() {
|
public ToolSet getToolSet() {
|
||||||
return toolSet;
|
return toolSet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,22 +20,18 @@ package baritone.pathing.movement;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.*;
|
||||||
import baritone.api.utils.Rotation;
|
|
||||||
import baritone.api.utils.RotationUtils;
|
|
||||||
import baritone.api.utils.VecUtils;
|
|
||||||
import baritone.utils.BlockBreakHelper;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.block.BlockLiquid;
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static baritone.utils.InputOverrideHandler.Input;
|
import static baritone.utils.InputOverrideHandler.Input;
|
||||||
@@ -60,8 +56,6 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
*/
|
*/
|
||||||
protected final BetterBlockPos positionToPlace;
|
protected final BetterBlockPos positionToPlace;
|
||||||
|
|
||||||
private boolean didBreakLastTick;
|
|
||||||
|
|
||||||
private Double cost;
|
private Double cost;
|
||||||
|
|
||||||
public List<BlockPos> toBreakCached = null;
|
public List<BlockPos> toBreakCached = null;
|
||||||
@@ -97,7 +91,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return getCost();
|
return getCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void override(double cost) {
|
public void override(double cost) {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,52 +109,31 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
@Override
|
@Override
|
||||||
public MovementStatus update() {
|
public MovementStatus update() {
|
||||||
player().capabilities.isFlying = false;
|
player().capabilities.isFlying = false;
|
||||||
MovementState latestState = updateState(currentState);
|
currentState = updateState(currentState);
|
||||||
if (BlockStateInterface.isLiquid(playerFeet())) {
|
if (MovementHelper.isLiquid(playerFeet())) {
|
||||||
latestState.setInput(Input.JUMP, true);
|
currentState.setInput(Input.JUMP, true);
|
||||||
}
|
}
|
||||||
if (player().isEntityInsideOpaqueBlock()) {
|
if (player().isEntityInsideOpaqueBlock()) {
|
||||||
latestState.setInput(Input.CLICK_LEFT, true);
|
currentState.setInput(Input.CLICK_LEFT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
|
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
|
||||||
latestState.getTarget().getRotation().ifPresent(rotation ->
|
currentState.getTarget().getRotation().ifPresent(rotation ->
|
||||||
Baritone.INSTANCE.getLookBehavior().updateTarget(
|
Baritone.INSTANCE.getLookBehavior().updateTarget(
|
||||||
rotation,
|
rotation,
|
||||||
latestState.getTarget().hasToForceRotations()));
|
currentState.getTarget().hasToForceRotations()));
|
||||||
|
|
||||||
// TODO: calculate movement inputs from latestState.getGoal().position
|
// TODO: calculate movement inputs from latestState.getGoal().position
|
||||||
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
|
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
|
||||||
|
|
||||||
this.didBreakLastTick = false;
|
currentState.getInputStates().forEach((input, forced) -> {
|
||||||
|
|
||||||
latestState.getInputStates().forEach((input, forced) -> {
|
|
||||||
if (Baritone.settings().leftClickWorkaround.get()) {
|
|
||||||
RayTraceResult trace = mc.objectMouseOver;
|
|
||||||
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
|
||||||
boolean isLeftClick = forced && input == Input.CLICK_LEFT;
|
|
||||||
|
|
||||||
// If we're forcing left click, we're in a gui screen, and we're looking
|
|
||||||
// at a block, break the block without a direct game input manipulation.
|
|
||||||
if (mc.currentScreen != null && isLeftClick && isBlockTrace) {
|
|
||||||
BlockBreakHelper.tryBreakBlock(trace.getBlockPos(), trace.sideHit);
|
|
||||||
this.didBreakLastTick = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
|
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
|
||||||
});
|
});
|
||||||
latestState.getInputStates().replaceAll((input, forced) -> false);
|
currentState.getInputStates().replaceAll((input, forced) -> false);
|
||||||
|
|
||||||
if (!this.didBreakLastTick) {
|
|
||||||
BlockBreakHelper.stopBreakingBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentState = latestState;
|
|
||||||
|
|
||||||
// If the current status indicates a completed movement
|
// If the current status indicates a completed movement
|
||||||
if (currentState.getStatus().isComplete()) {
|
if (currentState.getStatus().isComplete()) {
|
||||||
onFinish(latestState);
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentState.getStatus();
|
return currentState.getStatus();
|
||||||
@@ -174,10 +147,13 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
for (BetterBlockPos blockPos : positionsToBreak) {
|
for (BetterBlockPos blockPos : positionsToBreak) {
|
||||||
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
||||||
somethingInTheWay = true;
|
somethingInTheWay = true;
|
||||||
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
|
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos, playerController().getBlockReachDistance());
|
||||||
if (reachable.isPresent()) {
|
if (reachable.isPresent()) {
|
||||||
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
|
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
|
||||||
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
|
state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
|
||||||
|
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), blockPos)) {
|
||||||
|
state.setInput(Input.CLICK_LEFT, true);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//get rekt minecraft
|
//get rekt minecraft
|
||||||
@@ -186,7 +162,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
//you dont own me!!!!
|
//you dont own me!!!!
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(blockPos)), true)
|
VecUtils.getBlockPosCenter(blockPos)), true)
|
||||||
).setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
);
|
||||||
|
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
|
||||||
|
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,20 +196,6 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run cleanup on state finish and declare success.
|
|
||||||
*/
|
|
||||||
public void onFinish(MovementState state) {
|
|
||||||
state.getInputStates().replaceAll((input, forced) -> false);
|
|
||||||
state.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel() {
|
|
||||||
currentState.getInputStates().replaceAll((input, forced) -> false);
|
|
||||||
currentState.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
|
|
||||||
currentState.setStatus(MovementStatus.CANCELED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
||||||
@@ -262,8 +226,8 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return getDest().subtract(getSrc());
|
return getDest().subtract(getSrc());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkLoadedChunk() {
|
public void checkLoadedChunk(CalculationContext context) {
|
||||||
calculatedWhileLoaded = !(world().getChunk(getDest()) instanceof EmptyChunk);
|
calculatedWhileLoaded = !(context.world().getChunk(getDest()) instanceof EmptyChunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import baritone.utils.ToolSet;
|
|||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.ItemPickaxe;
|
import net.minecraft.item.ItemPickaxe;
|
||||||
@@ -45,16 +44,16 @@ import net.minecraft.world.chunk.EmptyChunk;
|
|||||||
*/
|
*/
|
||||||
public interface MovementHelper extends ActionCosts, Helper {
|
public interface MovementHelper extends ActionCosts, Helper {
|
||||||
|
|
||||||
static boolean avoidBreaking(int x, int y, int z, IBlockState state) {
|
static boolean avoidBreaking(CalculationContext context, int x, int y, int z, IBlockState state) {
|
||||||
Block b = state.getBlock();
|
Block b = state.getBlock();
|
||||||
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|
||||||
|| b instanceof BlockSilverfish // obvious reasons
|
|| b instanceof BlockSilverfish // obvious reasons
|
||||||
// call BlockStateInterface.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|
// call context.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|
||||||
|| BlockStateInterface.get(x, y + 1, z).getBlock() instanceof BlockLiquid//don't break anything touching liquid on any side
|
|| context.get(x, y + 1, z).getBlock() instanceof BlockLiquid//don't break anything touching liquid on any side
|
||||||
|| BlockStateInterface.get(x + 1, y, z).getBlock() instanceof BlockLiquid
|
|| context.get(x + 1, y, z).getBlock() instanceof BlockLiquid
|
||||||
|| BlockStateInterface.get(x - 1, y, z).getBlock() instanceof BlockLiquid
|
|| context.get(x - 1, y, z).getBlock() instanceof BlockLiquid
|
||||||
|| BlockStateInterface.get(x, y, z + 1).getBlock() instanceof BlockLiquid
|
|| context.get(x, y, z + 1).getBlock() instanceof BlockLiquid
|
||||||
|| BlockStateInterface.get(x, y, z - 1).getBlock() instanceof BlockLiquid;
|
|| context.get(x, y, z - 1).getBlock() instanceof BlockLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,14 +63,14 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean canWalkThrough(BetterBlockPos pos) {
|
static boolean canWalkThrough(BetterBlockPos pos) {
|
||||||
return canWalkThrough(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
return canWalkThrough(new CalculationContext(), pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkThrough(int x, int y, int z) {
|
static boolean canWalkThrough(CalculationContext context, int x, int y, int z) {
|
||||||
return canWalkThrough(x, y, z, BlockStateInterface.get(x, y, z));
|
return canWalkThrough(context, x, y, z, context.get(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkThrough(int x, int y, int z, IBlockState state) {
|
static boolean canWalkThrough(CalculationContext context, int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.AIR) { // early return for most common case
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
@@ -105,14 +104,14 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.isFlowing(state)) {
|
if (isFlowing(state)) {
|
||||||
return false; // Don't walk through flowing liquids
|
return false; // Don't walk through flowing liquids
|
||||||
}
|
}
|
||||||
if (block instanceof BlockLiquid) {
|
if (block instanceof BlockLiquid) {
|
||||||
if (Baritone.settings().assumeWalkOnWater.get()) {
|
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IBlockState up = BlockStateInterface.get(x, y + 1, z);
|
IBlockState up = context.get(x, y + 1, z);
|
||||||
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -130,8 +129,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean fullyPassable(int x, int y, int z) {
|
static boolean fullyPassable(CalculationContext context, int x, int y, int z) {
|
||||||
return fullyPassable(BlockStateInterface.get(x, y, z));
|
return fullyPassable(context.get(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean fullyPassable(IBlockState state) {
|
static boolean fullyPassable(IBlockState state) {
|
||||||
@@ -246,7 +245,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean canWalkOn(int x, int y, int z, IBlockState state) {
|
static boolean canWalkOn(CalculationContext context, int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
||||||
// early return for most common case (air)
|
// early return for most common case (air)
|
||||||
@@ -254,9 +253,6 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (state.isBlockNormalCube()) {
|
if (state.isBlockNormalCube()) {
|
||||||
if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
|
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
|
||||||
@@ -268,20 +264,20 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
||||||
return true;
|
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()"
|
// 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
|
// 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();
|
Block up = context.get(x, y + 1, z).getBlock();
|
||||||
if (up == Blocks.WATERLILY) {
|
if (up == Blocks.WATERLILY) {
|
||||||
return true;
|
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
|
// 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 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
|
// 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 instanceof BlockGlass || block instanceof BlockStainedGlass) {
|
||||||
return true;
|
return true;
|
||||||
@@ -299,19 +295,19 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
|
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
|
||||||
return canWalkOn(pos.x, pos.y, pos.z, state);
|
return canWalkOn(new CalculationContext(), pos.x, pos.y, pos.z, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkOn(BetterBlockPos pos) {
|
static boolean canWalkOn(BetterBlockPos pos) {
|
||||||
return canWalkOn(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
return canWalkOn(new CalculationContext(), pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkOn(int x, int y, int z) {
|
static boolean canWalkOn(CalculationContext context, int x, int y, int z) {
|
||||||
return canWalkOn(x, y, z, BlockStateInterface.get(x, y, z));
|
return canWalkOn(context, x, y, z, context.get(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(int x, int y, int z) {
|
static boolean canPlaceAgainst(CalculationContext context, int x, int y, int z) {
|
||||||
return canPlaceAgainst(BlockStateInterface.get(x, y, z));
|
return canPlaceAgainst(context.get(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(BlockPos pos) {
|
static boolean canPlaceAgainst(BlockPos pos) {
|
||||||
@@ -324,16 +320,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
||||||
return getMiningDurationTicks(context, x, y, z, BlockStateInterface.get(x, y, z), includeFalling);
|
return getMiningDurationTicks(context, x, y, z, context.get(x, y, z), includeFalling);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (!canWalkThrough(x, y, z, state)) {
|
if (!canWalkThrough(context, x, y, z, state)) {
|
||||||
if (!context.canBreakAt(x, y, z)) {
|
if (!context.canBreakAt(x, y, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (avoidBreaking(x, y, z, state)) {
|
if (avoidBreaking(context, x, y, z, state)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockLiquid) {
|
if (block instanceof BlockLiquid) {
|
||||||
@@ -348,7 +344,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
double result = m / strVsBlock;
|
double result = m / strVsBlock;
|
||||||
result += context.breakBlockAdditionalCost();
|
result += context.breakBlockAdditionalCost();
|
||||||
if (includeFalling) {
|
if (includeFalling) {
|
||||||
IBlockState above = BlockStateInterface.get(x, y + 1, z);
|
IBlockState above = context.get(x, y + 1, z);
|
||||||
if (above.getBlock() instanceof BlockFalling) {
|
if (above.getBlock() instanceof BlockFalling) {
|
||||||
result += getMiningDurationTicks(context, x, y + 1, z, above, true);
|
result += getMiningDurationTicks(context, x, y + 1, z, above, true);
|
||||||
}
|
}
|
||||||
@@ -364,10 +360,6 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
|
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isBottomSlab(BlockPos pos) {
|
|
||||||
return isBottomSlab(BlockStateInterface.get(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AutoTool
|
* AutoTool
|
||||||
*/
|
*/
|
||||||
@@ -387,7 +379,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @param b the blockstate to mine
|
* @param b the blockstate to mine
|
||||||
*/
|
*/
|
||||||
static void switchToBestToolFor(IBlockState b) {
|
static void switchToBestToolFor(IBlockState b) {
|
||||||
switchToBestToolFor(b, new ToolSet());
|
switchToBestToolFor(b, new ToolSet(Helper.HELPER.player()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -397,11 +389,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @param ts previously calculated ToolSet
|
* @param ts previously calculated ToolSet
|
||||||
*/
|
*/
|
||||||
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
|
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
|
||||||
mc.player.inventory.currentItem = ts.getBestSlot(b.getBlock());
|
Helper.HELPER.player().inventory.currentItem = ts.getBestSlot(b.getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean throwaway(boolean select) {
|
static boolean throwaway(boolean select) {
|
||||||
EntityPlayerSP p = Minecraft.getMinecraft().player;
|
EntityPlayerSP p = Helper.HELPER.player();
|
||||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||||
for (byte i = 0; i < 9; i++) {
|
for (byte i = 0; i < 9; i++) {
|
||||||
ItemStack item = inv.get(i);
|
ItemStack item = inv.get(i);
|
||||||
@@ -437,11 +429,55 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void moveTowards(MovementState state, BlockPos pos) {
|
static void moveTowards(MovementState state, BlockPos pos) {
|
||||||
|
EntityPlayerSP player = Helper.HELPER.player();
|
||||||
state.setTarget(new MovementTarget(
|
state.setTarget(new MovementTarget(
|
||||||
new Rotation(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(pos),
|
VecUtils.getBlockPosCenter(pos),
|
||||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getYaw(), mc.player.rotationPitch),
|
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
|
||||||
false
|
false
|
||||||
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
)).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.getPropertyKeys().contains(BlockLiquid.LEVEL)
|
||||||
|
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import net.minecraft.util.EnumFacing;
|
|||||||
public enum Moves {
|
public enum Moves {
|
||||||
DOWNWARD(0, -1, 0) {
|
DOWNWARD(0, -1, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementDownward(src, src.down());
|
return new MovementDownward(src, src.down());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ public enum Moves {
|
|||||||
|
|
||||||
PILLAR(0, +1, 0) {
|
PILLAR(0, +1, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementPillar(src, src.up());
|
return new MovementPillar(src, src.up());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public enum Moves {
|
|||||||
|
|
||||||
TRAVERSE_NORTH(0, 0, -1) {
|
TRAVERSE_NORTH(0, 0, -1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementTraverse(src, src.north());
|
return new MovementTraverse(src, src.north());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public enum Moves {
|
|||||||
|
|
||||||
TRAVERSE_SOUTH(0, 0, +1) {
|
TRAVERSE_SOUTH(0, 0, +1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementTraverse(src, src.south());
|
return new MovementTraverse(src, src.south());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public enum Moves {
|
|||||||
|
|
||||||
TRAVERSE_EAST(+1, 0, 0) {
|
TRAVERSE_EAST(+1, 0, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementTraverse(src, src.east());
|
return new MovementTraverse(src, src.east());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ public enum Moves {
|
|||||||
|
|
||||||
TRAVERSE_WEST(-1, 0, 0) {
|
TRAVERSE_WEST(-1, 0, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementTraverse(src, src.west());
|
return new MovementTraverse(src, src.west());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ public enum Moves {
|
|||||||
|
|
||||||
ASCEND_NORTH(0, +1, -1) {
|
ASCEND_NORTH(0, +1, -1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z - 1));
|
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ public enum Moves {
|
|||||||
|
|
||||||
ASCEND_SOUTH(0, +1, +1) {
|
ASCEND_SOUTH(0, +1, +1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z + 1));
|
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ public enum Moves {
|
|||||||
|
|
||||||
ASCEND_EAST(+1, +1, 0) {
|
ASCEND_EAST(+1, +1, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementAscend(src, new BetterBlockPos(src.x + 1, src.y + 1, src.z));
|
return new MovementAscend(src, new BetterBlockPos(src.x + 1, src.y + 1, src.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ public enum Moves {
|
|||||||
|
|
||||||
ASCEND_WEST(-1, +1, 0) {
|
ASCEND_WEST(-1, +1, 0) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementAscend(src, new BetterBlockPos(src.x - 1, src.y + 1, src.z));
|
return new MovementAscend(src, new BetterBlockPos(src.x - 1, src.y + 1, src.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +150,9 @@ public enum Moves {
|
|||||||
|
|
||||||
DESCEND_EAST(+1, -1, 0, false, true) {
|
DESCEND_EAST(+1, -1, 0, false, true) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
apply(new CalculationContext(), src.x, src.y, src.z, res);
|
apply(context, src.x, src.y, src.z, res);
|
||||||
if (res.y == src.y - 1) {
|
if (res.y == src.y - 1) {
|
||||||
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
||||||
} else {
|
} else {
|
||||||
@@ -168,9 +168,9 @@ public enum Moves {
|
|||||||
|
|
||||||
DESCEND_WEST(-1, -1, 0, false, true) {
|
DESCEND_WEST(-1, -1, 0, false, true) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
apply(new CalculationContext(), src.x, src.y, src.z, res);
|
apply(context, src.x, src.y, src.z, res);
|
||||||
if (res.y == src.y - 1) {
|
if (res.y == src.y - 1) {
|
||||||
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
||||||
} else {
|
} else {
|
||||||
@@ -186,9 +186,9 @@ public enum Moves {
|
|||||||
|
|
||||||
DESCEND_NORTH(0, -1, -1, false, true) {
|
DESCEND_NORTH(0, -1, -1, false, true) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
apply(new CalculationContext(), src.x, src.y, src.z, res);
|
apply(context, src.x, src.y, src.z, res);
|
||||||
if (res.y == src.y - 1) {
|
if (res.y == src.y - 1) {
|
||||||
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
||||||
} else {
|
} else {
|
||||||
@@ -204,9 +204,9 @@ public enum Moves {
|
|||||||
|
|
||||||
DESCEND_SOUTH(0, -1, +1, false, true) {
|
DESCEND_SOUTH(0, -1, +1, false, true) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
apply(new CalculationContext(), src.x, src.y, src.z, res);
|
apply(context, src.x, src.y, src.z, res);
|
||||||
if (res.y == src.y - 1) {
|
if (res.y == src.y - 1) {
|
||||||
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
return new MovementDescend(src, new BetterBlockPos(res.x, res.y, res.z));
|
||||||
} else {
|
} else {
|
||||||
@@ -222,7 +222,7 @@ public enum Moves {
|
|||||||
|
|
||||||
DIAGONAL_NORTHEAST(+1, 0, -1) {
|
DIAGONAL_NORTHEAST(+1, 0, -1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.EAST);
|
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.EAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ public enum Moves {
|
|||||||
|
|
||||||
DIAGONAL_NORTHWEST(-1, 0, -1) {
|
DIAGONAL_NORTHWEST(-1, 0, -1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.WEST);
|
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.WEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ public enum Moves {
|
|||||||
|
|
||||||
DIAGONAL_SOUTHEAST(+1, 0, +1) {
|
DIAGONAL_SOUTHEAST(+1, 0, +1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.EAST);
|
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.EAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ public enum Moves {
|
|||||||
|
|
||||||
DIAGONAL_SOUTHWEST(-1, 0, +1) {
|
DIAGONAL_SOUTHWEST(-1, 0, +1) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.WEST);
|
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.WEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,8 +270,8 @@ public enum Moves {
|
|||||||
|
|
||||||
PARKOUR_NORTH(0, 0, -4, true, false) {
|
PARKOUR_NORTH(0, 0, -4, true, false) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.NORTH);
|
return MovementParkour.cost(context, src, EnumFacing.NORTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -282,8 +282,8 @@ public enum Moves {
|
|||||||
|
|
||||||
PARKOUR_SOUTH(0, 0, +4, true, false) {
|
PARKOUR_SOUTH(0, 0, +4, true, false) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.SOUTH);
|
return MovementParkour.cost(context, src, EnumFacing.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -294,8 +294,8 @@ public enum Moves {
|
|||||||
|
|
||||||
PARKOUR_EAST(+4, 0, 0, true, false) {
|
PARKOUR_EAST(+4, 0, 0, true, false) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.EAST);
|
return MovementParkour.cost(context, src, EnumFacing.EAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -306,8 +306,8 @@ public enum Moves {
|
|||||||
|
|
||||||
PARKOUR_WEST(-4, 0, 0, true, false) {
|
PARKOUR_WEST(-4, 0, 0, true, false) {
|
||||||
@Override
|
@Override
|
||||||
public Movement apply0(BetterBlockPos src) {
|
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||||
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.WEST);
|
return MovementParkour.cost(context, src, EnumFacing.WEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -335,7 +335,7 @@ public enum Moves {
|
|||||||
this(x, y, z, false, false);
|
this(x, y, z, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Movement apply0(BetterBlockPos src);
|
public abstract Movement apply0(CalculationContext context, BetterBlockPos src);
|
||||||
|
|
||||||
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
||||||
if (dynamicXZ || dynamicY) {
|
if (dynamicXZ || dynamicY) {
|
||||||
|
|||||||
@@ -58,24 +58,24 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
IBlockState srcDown = BlockStateInterface.get(x, y - 1, z);
|
IBlockState srcDown = context.get(x, y - 1, z);
|
||||||
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
// we can jump from soul sand, but not from a bottom slab
|
// we can jump from soul sand, but not from a bottom slab
|
||||||
boolean jumpingFromBottomSlab = MovementHelper.isBottomSlab(srcDown);
|
boolean jumpingFromBottomSlab = MovementHelper.isBottomSlab(srcDown);
|
||||||
IBlockState toPlace = BlockStateInterface.get(destX, y, destZ);
|
IBlockState toPlace = context.get(destX, y, destZ);
|
||||||
boolean jumpingToBottomSlab = MovementHelper.isBottomSlab(toPlace);
|
boolean jumpingToBottomSlab = MovementHelper.isBottomSlab(toPlace);
|
||||||
|
|
||||||
if (jumpingFromBottomSlab && !jumpingToBottomSlab) {
|
if (jumpingFromBottomSlab && !jumpingToBottomSlab) {
|
||||||
return COST_INF;// the only thing we can ascend onto from a bottom slab is another bottom slab
|
return COST_INF;// the only thing we can ascend onto from a bottom slab is another bottom slab
|
||||||
}
|
}
|
||||||
boolean hasToPlace = false;
|
boolean hasToPlace = false;
|
||||||
if (!MovementHelper.canWalkOn(destX, y, destZ, toPlace)) {
|
if (!MovementHelper.canWalkOn(context, destX, y, destZ, toPlace)) {
|
||||||
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
||||||
return COST_INF;
|
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;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
// TODO: add ability to place against .down() as well as the cardinal directions
|
// TODO: add ability to place against .down() as well as the cardinal directions
|
||||||
@@ -87,7 +87,7 @@ public class MovementAscend extends Movement {
|
|||||||
if (againstX == x && againstZ == z) {
|
if (againstX == x && againstZ == z) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(againstX, y, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context, againstX, y, againstZ)) {
|
||||||
hasToPlace = true;
|
hasToPlace = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IBlockState srcUp2 = null;
|
IBlockState srcUp2 = null;
|
||||||
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
|
if (context.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(context, x, y + 1, z) || !((srcUp2 = context.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
|
// HOWEVER, we assume that we're standing in the start position
|
||||||
// that means that src and src.up(1) are both air
|
// 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
|
// maybe they aren't now, but they will be by the time this starts
|
||||||
@@ -138,7 +138,7 @@ public class MovementAscend extends Movement {
|
|||||||
totalCost += context.placeBlockCost();
|
totalCost += context.placeBlockCost();
|
||||||
}
|
}
|
||||||
if (srcUp2 == null) {
|
if (srcUp2 == null) {
|
||||||
srcUp2 = BlockStateInterface.get(x, y + 2, z);
|
srcUp2 = context.get(x, y + 2, z);
|
||||||
}
|
}
|
||||||
totalCost += MovementHelper.getMiningDurationTicks(context, x, y + 2, z, srcUp2, false); // TODO MAKE ABSOLUTELY SURE we don't need includeFalling here, from the falling check above
|
totalCost += MovementHelper.getMiningDurationTicks(context, x, y + 2, z, srcUp2, false); // TODO MAKE ABSOLUTELY SURE we don't need includeFalling here, from the falling check above
|
||||||
if (totalCost >= COST_INF) {
|
if (totalCost >= COST_INF) {
|
||||||
@@ -204,7 +204,7 @@ public class MovementAscend extends Movement {
|
|||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
MovementHelper.moveTowards(state, dest);
|
MovementHelper.moveTowards(state, dest);
|
||||||
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(src.down())) {
|
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(src.down()))) {
|
||||||
return state; // don't jump while walking from a non double slab into a bottom slab
|
return state; // don't jump while walking from a non double slab into a bottom slab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import baritone.pathing.movement.CalculationContext;
|
|||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -58,13 +57,13 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
|
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
|
||||||
Block fromDown = BlockStateInterface.get(x, y - 1, z).getBlock();
|
Block fromDown = context.get(x, y - 1, z).getBlock();
|
||||||
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double totalCost = 0;
|
double totalCost = 0;
|
||||||
IBlockState destDown = BlockStateInterface.get(destX, y - 1, destZ);
|
IBlockState destDown = context.get(destX, y - 1, destZ);
|
||||||
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y - 1, destZ, destDown, false);
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y - 1, destZ, destDown, false);
|
||||||
if (totalCost >= COST_INF) {
|
if (totalCost >= COST_INF) {
|
||||||
return;
|
return;
|
||||||
@@ -88,8 +87,8 @@ public class MovementDescend extends Movement {
|
|||||||
//A is plausibly breakable by either descend or fall
|
//A is plausibly breakable by either descend or fall
|
||||||
//C, D, etc determine the length of the fall
|
//C, D, etc determine the length of the fall
|
||||||
|
|
||||||
IBlockState below = BlockStateInterface.get(destX, y - 2, destZ);
|
IBlockState below = context.get(destX, y - 2, destZ);
|
||||||
if (!MovementHelper.canWalkOn(destX, y - 2, destZ, below)) {
|
if (!MovementHelper.canWalkOn(context, destX, y - 2, destZ, below)) {
|
||||||
dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res);
|
dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -112,13 +111,13 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below, MutableMoveResult res) {
|
public static void dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below, MutableMoveResult res) {
|
||||||
if (frontBreak != 0 && BlockStateInterface.get(destX, y + 2, destZ).getBlock() instanceof BlockFalling) {
|
if (frontBreak != 0 && context.get(destX, y + 2, destZ).getBlock() instanceof BlockFalling) {
|
||||||
// if frontBreak is 0 we can actually get through this without updating the falling block and making it actually fall
|
// if frontBreak is 0 we can actually get through this without updating the falling block and making it actually fall
|
||||||
// but if frontBreak is nonzero, we're breaking blocks in front, so don't let anything fall through this column,
|
// but if frontBreak is nonzero, we're breaking blocks in front, so don't let anything fall through this column,
|
||||||
// and potentially replace the water we're going to fall into
|
// and potentially replace the water we're going to fall into
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkThrough(destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
if (!MovementHelper.canWalkThrough(context, destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int fallHeight = 3; true; fallHeight++) {
|
for (int fallHeight = 3; true; fallHeight++) {
|
||||||
@@ -128,9 +127,9 @@ public class MovementDescend extends Movement {
|
|||||||
// this check prevents it from getting the block at y=-1 and crashing
|
// this check prevents it from getting the block at y=-1 and crashing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
|
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
|
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) && context.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
|
// 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)
|
// 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()) {
|
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||||
@@ -146,10 +145,10 @@ public class MovementDescend extends Movement {
|
|||||||
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
|
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkThrough(destX, newY, destZ, ontoBlock)) {
|
if (MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(destX, newY, destZ, ontoBlock)) {
|
if (!MovementHelper.canWalkOn(context, destX, newY, destZ, ontoBlock)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||||
@@ -183,7 +182,7 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockPos playerFeet = playerFeet();
|
BlockPos playerFeet = playerFeet();
|
||||||
if (playerFeet.equals(dest) && (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads
|
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
|
// 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);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
/* else {
|
/* else {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import baritone.pathing.movement.CalculationContext;
|
|||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
@@ -57,16 +56,16 @@ public class MovementDiagonal extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
Block fromDown = BlockStateInterface.get(x, y - 1, z).getBlock();
|
Block fromDown = context.get(x, y - 1, z).getBlock();
|
||||||
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState destInto = BlockStateInterface.get(destX, y, destZ);
|
IBlockState destInto = context.get(destX, y, destZ);
|
||||||
if (!MovementHelper.canWalkThrough(destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(destX, y + 1, destZ)) {
|
if (!MovementHelper.canWalkThrough(context, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context, destX, y + 1, destZ)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState destWalkOn = BlockStateInterface.get(destX, y - 1, destZ);
|
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
|
||||||
if (!MovementHelper.canWalkOn(destX, y - 1, destZ, destWalkOn)) {
|
if (!MovementHelper.canWalkOn(context, destX, y - 1, destZ, destWalkOn)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double multiplier = WALK_ONE_BLOCK_COST;
|
double multiplier = WALK_ONE_BLOCK_COST;
|
||||||
@@ -77,16 +76,16 @@ public class MovementDiagonal extends Movement {
|
|||||||
if (fromDown == Blocks.SOUL_SAND) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
|
Block cuttingOver1 = context.get(x, y - 1, destZ).getBlock();
|
||||||
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) {
|
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
|
Block cuttingOver2 = context.get(destX, y - 1, z).getBlock();
|
||||||
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) {
|
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
|
IBlockState pb0 = context.get(x, y, destZ);
|
||||||
IBlockState pb2 = BlockStateInterface.get(destX, y, z);
|
IBlockState pb2 = context.get(destX, y, z);
|
||||||
double optionA = MovementHelper.getMiningDurationTicks(context, x, y, destZ, pb0, false);
|
double optionA = MovementHelper.getMiningDurationTicks(context, x, y, destZ, pb0, false);
|
||||||
double optionB = MovementHelper.getMiningDurationTicks(context, destX, y, z, pb2, false);
|
double optionB = MovementHelper.getMiningDurationTicks(context, destX, y, z, pb2, false);
|
||||||
if (optionA != 0 && optionB != 0) {
|
if (optionA != 0 && optionB != 0) {
|
||||||
@@ -94,13 +93,13 @@ public class MovementDiagonal extends Movement {
|
|||||||
// so no need to check pb1 as well, might as well return early here
|
// so no need to check pb1 as well, might as well return early here
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState pb1 = BlockStateInterface.get(x, y + 1, destZ);
|
IBlockState pb1 = context.get(x, y + 1, destZ);
|
||||||
optionA += MovementHelper.getMiningDurationTicks(context, x, y + 1, destZ, pb1, true);
|
optionA += MovementHelper.getMiningDurationTicks(context, x, y + 1, destZ, pb1, true);
|
||||||
if (optionA != 0 && optionB != 0) {
|
if (optionA != 0 && optionB != 0) {
|
||||||
// same deal, if pb1 makes optionA nonzero and option B already was nonzero, pb3 can't affect the result
|
// same deal, if pb1 makes optionA nonzero and option B already was nonzero, pb3 can't affect the result
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z);
|
IBlockState pb3 = context.get(destX, y + 1, z);
|
||||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
|
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && 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
|
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -115,7 +114,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
boolean water = false;
|
boolean water = false;
|
||||||
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.isWater(destInto.getBlock())) {
|
if (MovementHelper.isWater(context.getBlock(x, y, z)) || MovementHelper.isWater(destInto.getBlock())) {
|
||||||
// Ignore previous multiplier
|
// Ignore previous multiplier
|
||||||
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
|
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
|
||||||
// Not even touching the blocks below
|
// Not even touching the blocks below
|
||||||
@@ -145,7 +144,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
state.setStatus(MovementStatus.SUCCESS);
|
state.setStatus(MovementStatus.SUCCESS);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (!BlockStateInterface.isLiquid(playerFeet())) {
|
if (!MovementHelper.isLiquid(playerFeet())) {
|
||||||
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
MovementHelper.moveTowards(state, dest);
|
MovementHelper.moveTowards(state, dest);
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import baritone.pathing.movement.CalculationContext;
|
|||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
@@ -48,10 +47,10 @@ public class MovementDownward extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z) {
|
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||||
if (!MovementHelper.canWalkOn(x, y - 2, z)) {
|
if (!MovementHelper.canWalkOn(context, x, y - 2, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState d = BlockStateInterface.get(x, y - 1, z);
|
IBlockState d = context.get(x, y - 1, z);
|
||||||
Block td = d.getBlock();
|
Block td = d.getBlock();
|
||||||
boolean ladder = td == Blocks.LADDER || td == Blocks.VINE;
|
boolean ladder = td == Blocks.LADDER || td == Blocks.VINE;
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
|
|||||||
@@ -19,13 +19,15 @@ package baritone.pathing.movement.movements;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.*;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
|
import baritone.api.utils.RotationUtils;
|
||||||
|
import baritone.api.utils.VecUtils;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
@@ -63,18 +65,18 @@ public class MovementFall extends Movement {
|
|||||||
|
|
||||||
BlockPos playerFeet = playerFeet();
|
BlockPos playerFeet = playerFeet();
|
||||||
Rotation targetRotation = null;
|
Rotation targetRotation = null;
|
||||||
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
if (!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()) {
|
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player().posY - dest.getY() < mc.playerController.getBlockReachDistance()) {
|
if (player().posY - dest.getY() < playerController().getBlockReachDistance()) {
|
||||||
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_WATER);
|
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_WATER);
|
||||||
|
|
||||||
targetRotation = new Rotation(player().rotationYaw, 90.0F);
|
targetRotation = new Rotation(player().rotationYaw, 90.0F);
|
||||||
|
|
||||||
RayTraceResult trace = RayTraceUtils.simulateRayTrace(player().rotationYaw, 90.0F);
|
RayTraceResult trace = mc.objectMouseOver;
|
||||||
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK) {
|
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && player().rotationPitch > 89.0F) {
|
||||||
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,8 +86,8 @@ public class MovementFall extends Movement {
|
|||||||
} else {
|
} else {
|
||||||
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
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 (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
|
||||||
if (BlockStateInterface.isWater(dest)) {
|
if (MovementHelper.isWater(dest)) {
|
||||||
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
||||||
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
||||||
if (player().motionY >= 0) {
|
if (player().motionY >= 0) {
|
||||||
|
|||||||
@@ -67,40 +67,50 @@ public class MovementParkour extends Movement {
|
|||||||
if (!Baritone.settings().allowParkour.get()) {
|
if (!Baritone.settings().allowParkour.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState standingOn = BlockStateInterface.get(x, y - 1, z);
|
IBlockState standingOn = context.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 || MovementHelper.isBottomSlab(standingOn)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int xDiff = dir.getXOffset();
|
int xDiff = dir.getXOffset();
|
||||||
int zDiff = dir.getZOffset();
|
int zDiff = dir.getZOffset();
|
||||||
IBlockState adj = BlockStateInterface.get(x + xDiff, y - 1, z + zDiff);
|
IBlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
|
||||||
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
if (MovementHelper.canWalkOn(context,x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MovementHelper.fullyPassable(x + xDiff, y, z + zDiff)) {
|
if (!MovementHelper.fullyPassable(context,x + xDiff, y, z + zDiff)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(x + xDiff, y + 1, z + zDiff)) {
|
if (!MovementHelper.fullyPassable(context,x + xDiff, y + 1, z + zDiff)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(x + xDiff, y + 2, z + zDiff)) {
|
if (!MovementHelper.fullyPassable(context,x + xDiff, y + 2, z + zDiff)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(x, y + 2, z)) {
|
if (!MovementHelper.fullyPassable(context,x, y + 2, z)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 2; i <= (context.canSprint() ? 4 : 3); i++) {
|
int maxJump;
|
||||||
|
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
|
||||||
|
maxJump = 2; // 1 block gap
|
||||||
|
} else {
|
||||||
|
if (context.canSprint()) {
|
||||||
|
maxJump = 4;
|
||||||
|
} else {
|
||||||
|
maxJump = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 2; i <= maxJump; i++) {
|
||||||
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
|
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
|
||||||
for (int y2 = 0; y2 < 4; y2++) {
|
for (int y2 = 0; y2 < 4; y2++) {
|
||||||
if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) {
|
if (!MovementHelper.fullyPassable(context,x + xDiff * i, y + y2, z + zDiff * i)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(x + xDiff * i, y - 1, z + zDiff * i)) {
|
if (MovementHelper.canWalkOn(context,x + xDiff * i, y - 1, z + zDiff * i)) {
|
||||||
res.x = x + xDiff * i;
|
res.x = x + xDiff * i;
|
||||||
res.y = y;
|
res.y = y;
|
||||||
res.z = z + zDiff * i;
|
res.z = z + zDiff * i;
|
||||||
@@ -108,7 +118,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!context.canSprint()) {
|
if (maxJump != 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Baritone.settings().allowParkourPlace.get()) {
|
if (!Baritone.settings().allowParkourPlace.get()) {
|
||||||
@@ -120,11 +130,11 @@ public class MovementParkour extends Movement {
|
|||||||
}
|
}
|
||||||
int destX = x + 4 * xDiff;
|
int destX = x + 4 * xDiff;
|
||||||
int destZ = z + 4 * zDiff;
|
int destZ = z + 4 * zDiff;
|
||||||
IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ);
|
IBlockState toPlace = context.get(destX, y - 1, destZ);
|
||||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
@@ -133,7 +143,7 @@ public class MovementParkour extends Movement {
|
|||||||
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
|
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(againstX, y - 1, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context,againstX, y - 1, againstZ)) {
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = y;
|
res.y = y;
|
||||||
res.z = destZ;
|
res.z = destZ;
|
||||||
@@ -217,7 +227,7 @@ public class MovementParkour extends Movement {
|
|||||||
double faceY = (dest.getY() + against1.getY()) * 0.5D;
|
double faceY = (dest.getY() + against1.getY()) * 0.5D;
|
||||||
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
||||||
Rotation place = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
|
Rotation place = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
|
||||||
RayTraceResult res = RayTraceUtils.rayTraceTowards(place);
|
RayTraceResult res = RayTraceUtils.rayTraceTowards(player(), place, playerController().getBlockReachDistance());
|
||||||
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) {
|
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) {
|
||||||
state.setTarget(new MovementState.MovementTarget(place, true));
|
state.setTarget(new MovementState.MovementTarget(place, true));
|
||||||
}
|
}
|
||||||
@@ -251,4 +261,4 @@ public class MovementParkour extends Movement {
|
|||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import baritone.utils.BlockStateInterface;
|
|||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -47,9 +46,9 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z) {
|
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||||
Block fromDown = BlockStateInterface.get(x, y, z).getBlock();
|
Block fromDown = context.get(x, y, z).getBlock();
|
||||||
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
||||||
IBlockState fromDownDown = BlockStateInterface.get(x, y - 1, z);
|
IBlockState fromDownDown = context.get(x, y - 1, z);
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -58,18 +57,18 @@ public class MovementPillar extends Movement {
|
|||||||
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fromDown instanceof BlockVine && !hasAgainst(x, y, z)) {
|
if (fromDown instanceof BlockVine && !hasAgainst(context, x, y, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState toBreak = BlockStateInterface.get(x, y + 2, z);
|
IBlockState toBreak = context.get(x, y + 2, z);
|
||||||
Block toBreakBlock = toBreak.getBlock();
|
Block toBreakBlock = toBreak.getBlock();
|
||||||
if (toBreakBlock instanceof BlockFenceGate) {
|
if (toBreakBlock instanceof BlockFenceGate) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
Block srcUp = null;
|
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();
|
srcUp = context.get(x, y + 1, z).getBlock();
|
||||||
if (BlockStateInterface.isWater(srcUp)) {
|
if (MovementHelper.isWater(srcUp)) {
|
||||||
return LADDER_UP_ONE_COST;
|
return LADDER_UP_ONE_COST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,11 +83,11 @@ public class MovementPillar extends Movement {
|
|||||||
if (toBreakBlock instanceof BlockLadder || toBreakBlock instanceof BlockVine) {
|
if (toBreakBlock instanceof BlockLadder || toBreakBlock instanceof BlockVine) {
|
||||||
hardness = 0; // we won't actually need to break the ladder / vine because we're going to use it
|
hardness = 0; // we won't actually need to break the ladder / vine because we're going to use it
|
||||||
} else {
|
} else {
|
||||||
IBlockState check = BlockStateInterface.get(x, y + 3, z);
|
IBlockState check = context.get(x, y + 3, z);
|
||||||
if (check.getBlock() instanceof BlockFalling) {
|
if (check.getBlock() instanceof BlockFalling) {
|
||||||
// see MovementAscend's identical check for breaking a falling block above our head
|
// see MovementAscend's identical check for breaking a falling block above our head
|
||||||
if (srcUp == null) {
|
if (srcUp == null) {
|
||||||
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
|
srcUp = context.get(x, y + 1, z).getBlock();
|
||||||
}
|
}
|
||||||
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -113,24 +112,24 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasAgainst(int x, int y, int z) {
|
public static boolean hasAgainst(CalculationContext context, int x, int y, int z) {
|
||||||
return BlockStateInterface.get(x + 1, y, z).isBlockNormalCube() ||
|
return context.get(x + 1, y, z).isBlockNormalCube() ||
|
||||||
BlockStateInterface.get(x - 1, y, z).isBlockNormalCube() ||
|
context.get(x - 1, y, z).isBlockNormalCube() ||
|
||||||
BlockStateInterface.get(x, y, z + 1).isBlockNormalCube() ||
|
context.get(x, y, z + 1).isBlockNormalCube() ||
|
||||||
BlockStateInterface.get(x, y, z - 1).isBlockNormalCube();
|
context.get(x, y, z - 1).isBlockNormalCube();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockPos getAgainst(BlockPos vine) {
|
public static BlockPos getAgainst(CalculationContext context, BetterBlockPos vine) {
|
||||||
if (BlockStateInterface.get(vine.north()).isBlockNormalCube()) {
|
if (context.get(vine.north()).isBlockNormalCube()) {
|
||||||
return vine.north();
|
return vine.north();
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(vine.south()).isBlockNormalCube()) {
|
if (context.get(vine.south()).isBlockNormalCube()) {
|
||||||
return vine.south();
|
return vine.south();
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(vine.east()).isBlockNormalCube()) {
|
if (context.get(vine.east()).isBlockNormalCube()) {
|
||||||
return vine.east();
|
return vine.east();
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(vine.west()).isBlockNormalCube()) {
|
if (context.get(vine.west()).isBlockNormalCube()) {
|
||||||
return vine.west();
|
return vine.west();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -144,7 +143,7 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IBlockState fromDown = BlockStateInterface.get(src);
|
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
|
// stay centered while swimming up a water column
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
||||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
||||||
@@ -158,16 +157,16 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
|
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
|
||||||
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
||||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
Rotation rotation = RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(positionToPlace),
|
VecUtils.getBlockPosCenter(positionToPlace),
|
||||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch));
|
new Rotation(player().rotationYaw, player().rotationPitch));
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
state.setTarget(new MovementState.MovementTarget(new Rotation(mc.player.rotationYaw, rotation.getPitch()), true));
|
state.setTarget(new MovementState.MovementTarget(new Rotation(player().rotationYaw, rotation.getPitch()), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder;
|
boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder;
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
BlockPos against = vine ? getAgainst(src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
|
BlockPos against = vine ? getAgainst(new CalculationContext(), src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
|
||||||
if (against == null) {
|
if (against == null) {
|
||||||
logDebug("Unable to climb vines");
|
logDebug("Unable to climb vines");
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
@@ -176,7 +175,7 @@ public class MovementPillar extends Movement {
|
|||||||
if (playerFeet().equals(against.up()) || playerFeet().equals(dest)) {
|
if (playerFeet().equals(against.up()) || playerFeet().equals(dest)) {
|
||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
}
|
}
|
||||||
if (MovementHelper.isBottomSlab(src.down())) {
|
if (MovementHelper.isBottomSlab(BlockStateInterface.get(src.down()))) {
|
||||||
state.setInput(InputOverrideHandler.Input.JUMP, true);
|
state.setInput(InputOverrideHandler.Input.JUMP, true);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -215,10 +214,10 @@ public class MovementPillar extends Movement {
|
|||||||
|
|
||||||
if (!blockIsThere) {
|
if (!blockIsThere) {
|
||||||
Block fr = BlockStateInterface.get(src).getBlock();
|
Block fr = BlockStateInterface.get(src).getBlock();
|
||||||
if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) {
|
if (!(fr instanceof BlockAir || fr.isReplaceable(world(), src))) {
|
||||||
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
|
||||||
blockIsThere = false;
|
blockIsThere = false;
|
||||||
} else if (Minecraft.getMinecraft().player.isSneaking()) { // 1 tick after we're able to place
|
} else if (player().isSneaking()) { // 1 tick after we're able to place
|
||||||
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,9 +239,9 @@ public class MovementPillar extends Movement {
|
|||||||
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.isWater(dest.up())) {
|
if (MovementHelper.isWater(dest.up())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.prepared(state);
|
return super.prepared(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
IBlockState pb0 = BlockStateInterface.get(destX, y + 1, destZ);
|
IBlockState pb0 = context.get(destX, y + 1, destZ);
|
||||||
IBlockState pb1 = BlockStateInterface.get(destX, y, destZ);
|
IBlockState pb1 = context.get(destX, y, destZ);
|
||||||
IBlockState destOn = BlockStateInterface.get(destX, y - 1, destZ);
|
IBlockState destOn = context.get(destX, y - 1, destZ);
|
||||||
Block srcDown = BlockStateInterface.getBlock(x, y - 1, z);
|
Block srcDown = context.getBlock(x, y - 1, z);
|
||||||
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
if (MovementHelper.canWalkOn(context, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
||||||
double WC = WALK_ONE_BLOCK_COST;
|
double WC = WALK_ONE_BLOCK_COST;
|
||||||
boolean water = false;
|
boolean water = false;
|
||||||
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
||||||
WC = context.waterWalkSpeed();
|
WC = context.waterWalkSpeed();
|
||||||
water = true;
|
water = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -101,8 +101,8 @@ public class MovementTraverse extends Movement {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
|
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
|
||||||
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
|
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
||||||
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
|
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
||||||
@@ -121,7 +121,7 @@ public class MovementTraverse extends Movement {
|
|||||||
if (againstX == x && againstZ == z) {
|
if (againstX == x && againstZ == z) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(againstX, y - 1, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context, againstX, y - 1, againstZ)) {
|
||||||
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ public class MovementTraverse extends Movement {
|
|||||||
if (playerFeet().equals(dest)) {
|
if (playerFeet().equals(dest)) {
|
||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
}
|
}
|
||||||
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
|
if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
|
||||||
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
|
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
|
||||||
@@ -265,7 +265,7 @@ public class MovementTraverse extends Movement {
|
|||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
|
||||||
|
|
||||||
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
||||||
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get()) && RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) && RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
||||||
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
|
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
|
||||||
|
|||||||
+11
-5
@@ -15,17 +15,18 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.path;
|
||||||
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.utils.pathing.PathBase;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CutoffPath implements IPath {
|
public class CutoffPath extends PathBase {
|
||||||
|
|
||||||
private final List<BetterBlockPos> path;
|
private final List<BetterBlockPos> path;
|
||||||
|
|
||||||
@@ -35,11 +36,16 @@ public class CutoffPath implements IPath {
|
|||||||
|
|
||||||
private final Goal goal;
|
private final Goal goal;
|
||||||
|
|
||||||
CutoffPath(IPath prev, int lastPositionToInclude) {
|
public CutoffPath(IPath prev, int firstPositionToInclude, int lastPositionToInclude) {
|
||||||
path = prev.positions().subList(0, lastPositionToInclude + 1);
|
path = prev.positions().subList(firstPositionToInclude, lastPositionToInclude + 1);
|
||||||
movements = prev.movements().subList(0, lastPositionToInclude + 1);
|
movements = prev.movements().subList(firstPositionToInclude, lastPositionToInclude);
|
||||||
numNodes = prev.getNumNodesConsidered();
|
numNodes = prev.getNumNodesConsidered();
|
||||||
goal = prev.getGoal();
|
goal = prev.getGoal();
|
||||||
|
sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CutoffPath(IPath prev, int lastPositionToInclude) {
|
||||||
|
this(prev, 0, lastPositionToInclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -454,6 +454,43 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
return pathPosition;
|
return pathPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PathExecutor trySplice(PathExecutor next) {
|
||||||
|
if (next == null) {
|
||||||
|
return cutIfTooLong();
|
||||||
|
}
|
||||||
|
return SplicedPath.trySplice(path, next.path).map(path -> {
|
||||||
|
if (!path.getDest().equals(next.getPath().getDest())) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
PathExecutor ret = new PathExecutor(path);
|
||||||
|
ret.pathPosition = pathPosition;
|
||||||
|
ret.currentMovementOriginalCostEstimate = currentMovementOriginalCostEstimate;
|
||||||
|
ret.costEstimateIndex = costEstimateIndex;
|
||||||
|
ret.ticksOnCurrent = ticksOnCurrent;
|
||||||
|
return ret;
|
||||||
|
}).orElse(cutIfTooLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PathExecutor cutIfTooLong() {
|
||||||
|
if (pathPosition > Baritone.settings().maxPathHistoryLength.get()) {
|
||||||
|
int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.get();
|
||||||
|
CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1);
|
||||||
|
if (!newPath.getDest().equals(path.getDest())) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
logDebug("Discarding earliest segment movements, length cut from " + path.length() + " to " + newPath.length());
|
||||||
|
PathExecutor ret = new PathExecutor(newPath);
|
||||||
|
ret.pathPosition = pathPosition - cutoffAmt;
|
||||||
|
ret.currentMovementOriginalCostEstimate = currentMovementOriginalCostEstimate;
|
||||||
|
if (costEstimateIndex != null) {
|
||||||
|
ret.costEstimateIndex = costEstimateIndex - cutoffAmt;
|
||||||
|
}
|
||||||
|
ret.ticksOnCurrent = ticksOnCurrent;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPath getPath() {
|
public IPath getPath() {
|
||||||
return path;
|
return path;
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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.pathing.path;
|
||||||
|
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.movement.IMovement;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.utils.pathing.PathBase;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SplicedPath extends PathBase {
|
||||||
|
private final List<BetterBlockPos> path;
|
||||||
|
|
||||||
|
private final List<IMovement> movements;
|
||||||
|
|
||||||
|
private final int numNodes;
|
||||||
|
|
||||||
|
private final Goal goal;
|
||||||
|
|
||||||
|
private SplicedPath(List<BetterBlockPos> path, List<IMovement> movements, int numNodesConsidered, Goal goal) {
|
||||||
|
this.path = path;
|
||||||
|
this.movements = movements;
|
||||||
|
this.numNodes = numNodesConsidered;
|
||||||
|
this.goal = goal;
|
||||||
|
sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Goal getGoal() {
|
||||||
|
return goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IMovement> movements() {
|
||||||
|
return Collections.unmodifiableList(movements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BetterBlockPos> positions() {
|
||||||
|
return Collections.unmodifiableList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumNodesConsidered() {
|
||||||
|
return numNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<SplicedPath> trySplice(IPath first, IPath second) {
|
||||||
|
if (second == null || first == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (!Objects.equals(first.getGoal(), second.getGoal())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (!first.getDest().equals(second.getSrc())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
HashSet<BetterBlockPos> a = new HashSet<>(first.positions());
|
||||||
|
for (int i = 1; i < second.length(); i++) {
|
||||||
|
if (a.contains(second.positions().get(i))) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<BetterBlockPos> positions = new ArrayList<>();
|
||||||
|
List<IMovement> movements = new ArrayList<>();
|
||||||
|
positions.addAll(first.positions());
|
||||||
|
positions.addAll(second.positions().subList(1, second.length()));
|
||||||
|
movements.addAll(first.movements());
|
||||||
|
movements.addAll(second.movements());
|
||||||
|
return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.process.ICustomGoalProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As set by ExampleBaritoneControl or something idk
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current goal
|
||||||
|
*/
|
||||||
|
private Goal goal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current process state.
|
||||||
|
*
|
||||||
|
* @see State
|
||||||
|
*/
|
||||||
|
private State state;
|
||||||
|
|
||||||
|
public CustomGoalProcess(Baritone baritone) {
|
||||||
|
super(baritone, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGoal(Goal goal) {
|
||||||
|
this.goal = goal;
|
||||||
|
this.state = State.GOAL_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void path() {
|
||||||
|
this.state = State.PATH_REQUESTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Goal getGoal() {
|
||||||
|
return this.goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return this.state != State.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
switch (this.state) {
|
||||||
|
case GOAL_SET:
|
||||||
|
if (!baritone.getPathingBehavior().isPathing() && Objects.equals(baritone.getPathingBehavior().getGoal(), this.goal)) {
|
||||||
|
this.state = State.NONE;
|
||||||
|
}
|
||||||
|
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
|
case PATH_REQUESTED:
|
||||||
|
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
||||||
|
this.state = State.EXECUTING;
|
||||||
|
return ret;
|
||||||
|
case EXECUTING:
|
||||||
|
if (calcFailed) {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
|
if (this.goal == null || this.goal.isInGoal(playerFeet())) {
|
||||||
|
onLostControl(); // we're there xd
|
||||||
|
}
|
||||||
|
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLostControl() {
|
||||||
|
this.state = State.NONE;
|
||||||
|
this.goal = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName() {
|
||||||
|
return "Custom Goal " + this.goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected enum State {
|
||||||
|
NONE,
|
||||||
|
GOAL_SET,
|
||||||
|
PATH_REQUESTED,
|
||||||
|
EXECUTING
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
|
import baritone.api.pathing.goals.GoalNear;
|
||||||
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
|
import baritone.api.process.IFollowProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follow an entity
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public final class FollowProcess extends BaritoneProcessHelper implements IFollowProcess {
|
||||||
|
|
||||||
|
private Predicate<Entity> filter;
|
||||||
|
private List<Entity> cache;
|
||||||
|
|
||||||
|
public FollowProcess(Baritone baritone) {
|
||||||
|
super(baritone, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
scanWorld();
|
||||||
|
Goal goal = new GoalComposite(cache.stream().map(this::towards).toArray(Goal[]::new));
|
||||||
|
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Goal towards(Entity following) {
|
||||||
|
// lol this is trashy but it works
|
||||||
|
BlockPos pos;
|
||||||
|
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
||||||
|
pos = new BlockPos(following);
|
||||||
|
} else {
|
||||||
|
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
||||||
|
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
||||||
|
}
|
||||||
|
return new GoalNear(pos, Baritone.settings().followRadius.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean followable(Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entity.isDead) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entity.equals(player())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!world().loadedEntityList.contains(entity) && !world().playerEntities.contains(entity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanWorld() {
|
||||||
|
cache = Stream.of(world().loadedEntityList, world().playerEntities).flatMap(List::stream).filter(this::followable).filter(this.filter).distinct().collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
if (filter == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
scanWorld();
|
||||||
|
return !cache.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLostControl() {
|
||||||
|
filter = null;
|
||||||
|
cache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName() {
|
||||||
|
return "Follow " + cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void follow(Predicate<Entity> filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Entity> following() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Predicate<Entity> currentFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
|
import baritone.api.pathing.goals.GoalGetToBlock;
|
||||||
|
import baritone.api.process.IGetToBlockProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
||||||
|
private Block gettingTo;
|
||||||
|
private List<BlockPos> knownLocations;
|
||||||
|
|
||||||
|
private int tickCount = 0;
|
||||||
|
|
||||||
|
public GetToBlockProcess(Baritone baritone) {
|
||||||
|
super(baritone, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getToBlock(Block block) {
|
||||||
|
gettingTo = block;
|
||||||
|
knownLocations = null;
|
||||||
|
rescan(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return gettingTo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
if (knownLocations == null) {
|
||||||
|
rescan(new ArrayList<>());
|
||||||
|
}
|
||||||
|
if (knownLocations.isEmpty()) {
|
||||||
|
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
|
||||||
|
if (isSafeToCancel) {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
|
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
|
}
|
||||||
|
if (calcFailed) {
|
||||||
|
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
|
||||||
|
if (isSafeToCancel) {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
|
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
|
}
|
||||||
|
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||||
|
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||||
|
List<BlockPos> current = new ArrayList<>(knownLocations);
|
||||||
|
Baritone.getExecutor().execute(() -> rescan(current));
|
||||||
|
}
|
||||||
|
Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new));
|
||||||
|
if (goal.isInGoal(playerFeet())) {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
|
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLostControl() {
|
||||||
|
gettingTo = null;
|
||||||
|
knownLocations = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName() {
|
||||||
|
return "Get To Block " + gettingTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rescan(List<BlockPos> known) {
|
||||||
|
knownLocations = MineProcess.searchWorld(Collections.singletonList(gettingTo), 64, baritone.getWorldProvider(), world(), known);
|
||||||
|
}
|
||||||
|
}
|
||||||
+118
-65
@@ -15,25 +15,31 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.behavior;
|
package baritone.process;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.IMineBehavior;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.pathing.goals.*;
|
import baritone.api.pathing.goals.*;
|
||||||
|
import baritone.api.process.IMineProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.api.utils.RotationUtils;
|
import baritone.api.utils.RotationUtils;
|
||||||
import baritone.cache.CachedChunk;
|
import baritone.cache.CachedChunk;
|
||||||
import baritone.cache.ChunkPacker;
|
import baritone.cache.ChunkPacker;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.cache.WorldScanner;
|
import baritone.cache.WorldScanner;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.item.EntityItem;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -44,26 +50,28 @@ import java.util.stream.Collectors;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
public final class MineProcess extends BaritoneProcessHelper implements IMineProcess {
|
||||||
|
|
||||||
|
private static final int ORE_LOCATIONS_COUNT = 64;
|
||||||
|
|
||||||
private List<Block> mining;
|
private List<Block> mining;
|
||||||
private List<BlockPos> knownOreLocations;
|
private List<BlockPos> knownOreLocations;
|
||||||
private BlockPos branchPoint;
|
private BlockPos branchPoint;
|
||||||
|
private GoalRunAway branchPointRunaway;
|
||||||
private int desiredQuantity;
|
private int desiredQuantity;
|
||||||
|
private int tickCount;
|
||||||
|
|
||||||
public MineBehavior(Baritone baritone) {
|
public MineProcess(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public boolean isActive() {
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
return mining != null;
|
||||||
cancel();
|
}
|
||||||
return;
|
|
||||||
}
|
@Override
|
||||||
if (mining == null) {
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (desiredQuantity > 0) {
|
if (desiredQuantity > 0) {
|
||||||
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 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();
|
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
|
||||||
@@ -71,66 +79,92 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
if (curr >= desiredQuantity) {
|
if (curr >= desiredQuantity) {
|
||||||
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
|
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (calcFailed) {
|
||||||
|
logDirect("Unable to find any path to " + mining + ", canceling Mine");
|
||||||
|
cancel();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||||
if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
|
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
|
||||||
|
baritone.getExecutor().execute(() -> rescan(curr));
|
||||||
}
|
}
|
||||||
if (Baritone.settings().legitMine.get()) {
|
if (Baritone.settings().legitMine.get()) {
|
||||||
addNearby();
|
addNearby();
|
||||||
}
|
}
|
||||||
updateGoal();
|
Goal goal = updateGoal();
|
||||||
baritone.getPathingBehavior().revalidateGoal();
|
if (goal == null) {
|
||||||
|
// none in range
|
||||||
|
// maybe say something in chat? (ahem impact)
|
||||||
|
cancel();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateGoal() {
|
@Override
|
||||||
if (mining == null) {
|
public void onLostControl() {
|
||||||
return;
|
mine(0, (Block[]) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName() {
|
||||||
|
return "Mine " + mining;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Goal updateGoal() {
|
||||||
List<BlockPos> locs = knownOreLocations;
|
List<BlockPos> locs = knownOreLocations;
|
||||||
if (!locs.isEmpty()) {
|
if (!locs.isEmpty()) {
|
||||||
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
|
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
|
// 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)));
|
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new));
|
||||||
knownOreLocations = locs;
|
knownOreLocations = locs2;
|
||||||
return;
|
return goal;
|
||||||
}
|
}
|
||||||
// we don't know any ore locations at the moment
|
// we don't know any ore locations at the moment
|
||||||
if (!Baritone.settings().legitMine.get()) {
|
if (!Baritone.settings().legitMine.get()) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
// only in non-Xray mode (aka legit mode) do we do this
|
// only in non-Xray mode (aka legit mode) do we do this
|
||||||
|
int y = Baritone.settings().legitMineYLevel.get();
|
||||||
if (branchPoint == null) {
|
if (branchPoint == null) {
|
||||||
int y = Baritone.settings().legitMineYLevel.get();
|
/*if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
||||||
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
|
||||||
// cool, path is over and we are at desired y
|
// cool, path is over and we are at desired y
|
||||||
branchPoint = playerFeet();
|
branchPoint = playerFeet();
|
||||||
|
branchPointRunaway = null;
|
||||||
} else {
|
} else {
|
||||||
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
|
return new GoalYLevel(y);
|
||||||
return;
|
}*/
|
||||||
}
|
branchPoint = playerFeet();
|
||||||
}
|
}
|
||||||
|
// TODO shaft mode, mine 1x1 shafts to either side
|
||||||
if (playerFeet().equals(branchPoint)) {
|
// TODO also, see if the GoalRunAway with maintain Y at 11 works even from the surface
|
||||||
// TODO mine 1x1 shafts to either side
|
if (branchPointRunaway == null) {
|
||||||
branchPoint = branchPoint.north(10);
|
branchPointRunaway = new GoalRunAway(1, Optional.of(y), branchPoint) {
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
|
return branchPointRunaway;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rescan() {
|
private void rescan(List<BlockPos> already) {
|
||||||
if (mining == null) {
|
if (mining == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Baritone.settings().legitMine.get()) {
|
if (Baritone.settings().legitMine.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<BlockPos> locs = searchWorld(mining, 64);
|
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, baritone.getWorldProvider(), world(), already);
|
||||||
|
locs.addAll(droppedItemsScan(mining, world()));
|
||||||
if (locs.isEmpty()) {
|
if (locs.isEmpty()) {
|
||||||
logDebug("No locations for " + mining + " known, cancelling");
|
logDebug("No locations for " + mining + " known, cancelling");
|
||||||
mine(0, (String[]) null);
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
knownOreLocations = locs;
|
knownOreLocations = locs;
|
||||||
@@ -158,13 +192,39 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BlockPos> searchWorld(List<Block> mining, int max) {
|
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(new BlockPos(entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
public static List<BlockPos> searchWorld(List<Block> mining, int max, WorldProvider provider, World world, List<BlockPos> alreadyKnown) {
|
||||||
List<BlockPos> locs = new ArrayList<>();
|
List<BlockPos> locs = new ArrayList<>();
|
||||||
List<Block> uninteresting = new ArrayList<>();
|
List<Block> uninteresting = new ArrayList<>();
|
||||||
//long b = System.currentTimeMillis();
|
//long b = System.currentTimeMillis();
|
||||||
for (Block m : mining) {
|
for (Block m : mining) {
|
||||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
||||||
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
locs.addAll(provider.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
||||||
} else {
|
} else {
|
||||||
uninteresting.add(m);
|
uninteresting.add(m);
|
||||||
}
|
}
|
||||||
@@ -178,34 +238,38 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
|
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
|
||||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||||
}
|
}
|
||||||
return prune(locs, mining, max);
|
locs.addAll(alreadyKnown);
|
||||||
|
return prune(locs, mining, max, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNearby() {
|
public void addNearby() {
|
||||||
|
knownOreLocations.addAll(droppedItemsScan(mining, world()));
|
||||||
BlockPos playerFeet = playerFeet();
|
BlockPos playerFeet = playerFeet();
|
||||||
int searchDist = 4;//why four? idk
|
int searchDist = 4;//why four? idk
|
||||||
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
||||||
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
|
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
|
||||||
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
||||||
BlockPos pos = new BlockPos(x, y, 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
|
if (mining.contains(BlockStateInterface.getBlock(pos)) && RotationUtils.reachable(player(), pos, playerController().getBlockReachDistance()).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.add(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
knownOreLocations = prune(knownOreLocations, mining, 64);
|
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max) {
|
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
|
List<BlockPos> locs = locs2
|
||||||
.stream()
|
.stream()
|
||||||
|
.distinct()
|
||||||
|
|
||||||
// remove any that are within loaded chunks that aren't actually what we want
|
// 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()))
|
.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)
|
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
||||||
.filter(MineBehavior::plausibleToBreak)
|
.filter(MineProcess::plausibleToBreak)
|
||||||
|
|
||||||
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
|
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -217,7 +281,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean plausibleToBreak(BlockPos pos) {
|
public static boolean plausibleToBreak(BlockPos pos) {
|
||||||
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
|
if (MovementHelper.avoidBreaking(new CalculationContext(), pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// bedrock above and below makes it implausible, otherwise we're good
|
// bedrock above and below makes it implausible, otherwise we're good
|
||||||
@@ -225,13 +289,8 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mine(int quantity, String... blocks) {
|
public void mineByName(int quantity, String... blocks) {
|
||||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
|
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).toArray(Block[]::new));
|
||||||
this.desiredQuantity = quantity;
|
|
||||||
this.knownOreLocations = new ArrayList<>();
|
|
||||||
this.branchPoint = null;
|
|
||||||
rescan();
|
|
||||||
updateGoal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -240,13 +299,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
|||||||
this.desiredQuantity = quantity;
|
this.desiredQuantity = quantity;
|
||||||
this.knownOreLocations = new ArrayList<>();
|
this.knownOreLocations = new ArrayList<>();
|
||||||
this.branchPoint = null;
|
this.branchPoint = null;
|
||||||
rescan();
|
this.branchPointRunaway = null;
|
||||||
updateGoal();
|
rescan(new ArrayList<>());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() {
|
|
||||||
mine(0, (String[]) null);
|
|
||||||
baritone.getPathingBehavior().cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,8 +105,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup Baritone's pathing goal and (if needed) begin pathing
|
// Setup Baritone's pathing goal and (if needed) begin pathing
|
||||||
Baritone.INSTANCE.getPathingBehavior().setGoal(GOAL);
|
Baritone.INSTANCE.getCustomGoalProcess().setGoalAndPath(GOAL);
|
||||||
Baritone.INSTANCE.getPathingBehavior().path();
|
|
||||||
|
|
||||||
// If we have reached our goal, print a message and safely close the game
|
// If we have reached our goal, print a message and safely close the game
|
||||||
if (GOAL.isInGoal(playerFeet())) {
|
if (GOAL.isInGoal(playerFeet())) {
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.process.IBaritoneProcess;
|
||||||
|
|
||||||
|
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
|
||||||
|
public static final double DEFAULT_PRIORITY = 0;
|
||||||
|
|
||||||
|
protected final Baritone baritone;
|
||||||
|
private final double priority;
|
||||||
|
|
||||||
|
public BaritoneProcessHelper(Baritone baritone) {
|
||||||
|
this(baritone, DEFAULT_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaritoneProcessHelper(Baritone baritone, double priority) {
|
||||||
|
this.baritone = baritone;
|
||||||
|
this.priority = priority;
|
||||||
|
baritone.getPathingControlManager().registerProcess(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Baritone associatedWith() {
|
||||||
|
return baritone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTemporary() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double priority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ package baritone.utils;
|
|||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -32,6 +33,7 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
* between attempts, then we re-initialize the breaking process.
|
* between attempts, then we re-initialize the breaking process.
|
||||||
*/
|
*/
|
||||||
private static BlockPos lastBlock;
|
private static BlockPos lastBlock;
|
||||||
|
private static boolean didBreakLastTick;
|
||||||
|
|
||||||
private BlockBreakHelper() {}
|
private BlockBreakHelper() {}
|
||||||
|
|
||||||
@@ -48,7 +50,23 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
public static void stopBreakingBlock() {
|
public static void stopBreakingBlock() {
|
||||||
if (mc.playerController != null) {
|
if (mc.playerController != null) {
|
||||||
mc.playerController.resetBlockRemoving();
|
mc.playerController.resetBlockRemoving();
|
||||||
}
|
}
|
||||||
lastBlock = null;
|
lastBlock = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean tick(boolean isLeftClick) {
|
||||||
|
RayTraceResult trace = mc.objectMouseOver;
|
||||||
|
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
||||||
|
|
||||||
|
// If we're forcing left click, we're in a gui screen, and we're looking
|
||||||
|
// at a block, break the block without a direct game input manipulation.
|
||||||
|
if (mc.currentScreen != null && isLeftClick && isBlockTrace) {
|
||||||
|
tryBreakBlock(trace.getBlockPos(), trace.sideHit);
|
||||||
|
didBreakLastTick = true;
|
||||||
|
} else if (didBreakLastTick) {
|
||||||
|
stopBreakingBlock();
|
||||||
|
didBreakLastTick = false;
|
||||||
|
}
|
||||||
|
return !didBreakLastTick && isLeftClick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ package baritone.utils;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.cache.CachedRegion;
|
import baritone.cache.CachedRegion;
|
||||||
import baritone.cache.WorldData;
|
import baritone.cache.WorldData;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockLiquid;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,16 +35,31 @@ import net.minecraft.world.chunk.Chunk;
|
|||||||
*/
|
*/
|
||||||
public class BlockStateInterface implements Helper {
|
public class BlockStateInterface implements Helper {
|
||||||
|
|
||||||
private static Chunk prev = null;
|
private final World world;
|
||||||
private static CachedRegion prevCached = null;
|
private final WorldData worldData;
|
||||||
|
|
||||||
|
|
||||||
|
private Chunk prev = null;
|
||||||
|
private CachedRegion prevCached = null;
|
||||||
|
|
||||||
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
|
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
|
||||||
|
|
||||||
public static IBlockState get(BlockPos pos) {
|
public BlockStateInterface(World world, WorldData worldData) {
|
||||||
return get(pos.getX(), pos.getY(), pos.getZ());
|
this.worldData = worldData;
|
||||||
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBlockState get(int x, int y, int z) {
|
public static Block getBlock(BlockPos pos) { // won't be called from the pathing thread because the pathing thread doesn't make a single blockpos pog
|
||||||
|
return get(pos).getBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IBlockState get(BlockPos pos) {
|
||||||
|
return new CalculationContext().get(pos); // immense iq
|
||||||
|
// can't just do world().get because that doesn't work for out of bounds
|
||||||
|
// and toBreak and stuff fails when the movement is instantiated out of load range but it's not able to BlockStateInterface.get what it's going to walk on
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState get0(int x, int y, int z) {
|
||||||
|
|
||||||
// Invalid vertical position
|
// Invalid vertical position
|
||||||
if (y < 0 || y >= 256) {
|
if (y < 0 || y >= 256) {
|
||||||
@@ -62,7 +77,7 @@ public class BlockStateInterface implements Helper {
|
|||||||
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
||||||
return cached.getBlockState(x, y, z);
|
return cached.getBlockState(x, y, z);
|
||||||
}
|
}
|
||||||
Chunk chunk = mc.world.getChunk(x >> 4, z >> 4);
|
Chunk chunk = world.getChunk(x >> 4, z >> 4);
|
||||||
if (chunk.isLoaded()) {
|
if (chunk.isLoaded()) {
|
||||||
prev = chunk;
|
prev = chunk;
|
||||||
return chunk.getBlockState(x, y, z);
|
return chunk.getBlockState(x, y, z);
|
||||||
@@ -72,11 +87,10 @@ public class BlockStateInterface implements Helper {
|
|||||||
// except here, it's 512x512 tiles instead of 16x16, so even better repetition
|
// except here, it's 512x512 tiles instead of 16x16, so even better repetition
|
||||||
CachedRegion cached = prevCached;
|
CachedRegion cached = prevCached;
|
||||||
if (cached == null || cached.getX() != x >> 9 || cached.getZ() != z >> 9) {
|
if (cached == null || cached.getX() != x >> 9 || cached.getZ() != z >> 9) {
|
||||||
WorldData world = WorldProvider.INSTANCE.getCurrentWorld();
|
if (worldData == null) {
|
||||||
if (world == null) {
|
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
CachedRegion region = world.cache.getRegion(x >> 9, z >> 9);
|
CachedRegion region = worldData.cache.getRegion(x >> 9, z >> 9);
|
||||||
if (region == null) {
|
if (region == null) {
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
@@ -90,12 +104,12 @@ public class BlockStateInterface implements Helper {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLoaded(int x, int z) {
|
public boolean isLoaded(int x, int z) {
|
||||||
Chunk prevChunk = prev;
|
Chunk prevChunk = prev;
|
||||||
if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) {
|
if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
prevChunk = mc.world.getChunk(x >> 4, z >> 4);
|
prevChunk = world.getChunk(x >> 4, z >> 4);
|
||||||
if (prevChunk.isLoaded()) {
|
if (prevChunk.isLoaded()) {
|
||||||
prev = prevChunk;
|
prev = prevChunk;
|
||||||
return true;
|
return true;
|
||||||
@@ -104,71 +118,14 @@ public class BlockStateInterface implements Helper {
|
|||||||
if (prevRegion != null && prevRegion.getX() == x >> 9 && prevRegion.getZ() == z >> 9) {
|
if (prevRegion != null && prevRegion.getX() == x >> 9 && prevRegion.getZ() == z >> 9) {
|
||||||
return prevRegion.isCached(x & 511, z & 511);
|
return prevRegion.isCached(x & 511, z & 511);
|
||||||
}
|
}
|
||||||
WorldData world = WorldProvider.INSTANCE.getCurrentWorld();
|
if (worldData == null) {
|
||||||
if (world == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
prevRegion = world.cache.getRegion(x >> 9, z >> 9);
|
prevRegion = worldData.cache.getRegion(x >> 9, z >> 9);
|
||||||
if (prevRegion == null) {
|
if (prevRegion == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
prevCached = prevRegion;
|
prevCached = prevRegion;
|
||||||
return prevRegion.isCached(x & 511, z & 511);
|
return prevRegion.isCached(x & 511, z & 511);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearCachedChunk() {
|
|
||||||
prev = null;
|
|
||||||
prevCached = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Block getBlock(BlockPos pos) {
|
|
||||||
return get(pos).getBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ import baritone.behavior.Behavior;
|
|||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
import baritone.cache.ChunkPacker;
|
import baritone.cache.ChunkPacker;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
|
import baritone.process.CustomGoalProcess;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -46,6 +47,35 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class ExampleBaritoneControl extends Behavior implements Helper {
|
public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||||
|
|
||||||
|
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" +
|
||||||
|
"damn - Daniel ";
|
||||||
|
|
||||||
public ExampleBaritoneControl(Baritone baritone) {
|
public ExampleBaritoneControl(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone);
|
||||||
}
|
}
|
||||||
@@ -70,6 +100,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
public boolean runCommand(String msg0) {
|
public boolean runCommand(String msg0) {
|
||||||
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
||||||
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||||
|
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
||||||
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
|
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
|
||||||
for (Settings.Setting<Boolean> setting : toggleable) {
|
for (Settings.Setting<Boolean> setting : toggleable) {
|
||||||
if (msg.equalsIgnoreCase(setting.getName())) {
|
if (msg.equalsIgnoreCase(setting.getName())) {
|
||||||
@@ -85,6 +116,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
|
||||||
|
for (String line : HELP_MSG.split("\n")) {
|
||||||
|
logDirect(line);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (msg.contains(" ")) {
|
if (msg.contains(" ")) {
|
||||||
String[] data = msg.split(" ");
|
String[] data = msg.split(" ");
|
||||||
if (data.length == 2) {
|
if (data.length == 2) {
|
||||||
@@ -151,21 +188,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("unable to parse integer " + ex);
|
logDirect("unable to parse integer " + ex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoal(goal);
|
||||||
logDirect("Goal: " + goal);
|
logDirect("Goal: " + goal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("path")) {
|
if (msg.equals("path")) {
|
||||||
if (!pathingBehavior.path()) {
|
if (pathingBehavior.getGoal() == null) {
|
||||||
if (pathingBehavior.getGoal() == null) {
|
logDirect("No goal.");
|
||||||
logDirect("No goal.");
|
} else if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
|
||||||
} else {
|
logDirect("Already in goal");
|
||||||
if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
|
} else if (pathingBehavior.isPathing()) {
|
||||||
logDirect("Already in goal");
|
logDirect("Currently executing a path. Please cancel it first.");
|
||||||
} else {
|
} else {
|
||||||
logDirect("Currently executing a path. Please cancel it first.");
|
customGoalProcess.setGoalAndPath(pathingBehavior.getGoal());
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -179,7 +214,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
Chunk chunk = cli.getLoadedChunk(x, z);
|
Chunk chunk = cli.getLoadedChunk(x, z);
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
count++;
|
count++;
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().queueForPacking(chunk);
|
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().queueForPacking(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,21 +222,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("axis")) {
|
if (msg.equals("axis")) {
|
||||||
pathingBehavior.setGoal(new GoalAxis());
|
customGoalProcess.setGoalAndPath(new GoalAxis());
|
||||||
pathingBehavior.path();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("cancel") || msg.equals("stop")) {
|
if (msg.equals("cancel") || msg.equals("stop")) {
|
||||||
baritone.getMineBehavior().cancel();
|
pathingBehavior.cancelEverything();
|
||||||
baritone.getFollowBehavior().cancel();
|
|
||||||
pathingBehavior.cancel();
|
|
||||||
logDirect("ok canceled");
|
logDirect("ok canceled");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("forcecancel")) {
|
if (msg.equals("forcecancel")) {
|
||||||
baritone.getMineBehavior().cancel();
|
pathingBehavior.cancelEverything();
|
||||||
baritone.getFollowBehavior().cancel();
|
|
||||||
pathingBehavior.cancel();
|
|
||||||
AbstractNodeCostSearch.forceCancel();
|
AbstractNodeCostSearch.forceCancel();
|
||||||
pathingBehavior.forceCancel();
|
pathingBehavior.forceCancel();
|
||||||
logDirect("ok force canceled");
|
logDirect("ok force canceled");
|
||||||
@@ -224,15 +254,17 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Inverting goal of player feet");
|
logDirect("Inverting goal of player feet");
|
||||||
runAwayFrom = playerFeet();
|
runAwayFrom = playerFeet();
|
||||||
}
|
}
|
||||||
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
|
customGoalProcess.setGoalAndPath(new GoalRunAway(1, runAwayFrom) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!pathingBehavior.path()) {
|
return true;
|
||||||
logDirect("Currently executing a path. Please cancel it first.");
|
}
|
||||||
}
|
if (msg.startsWith("followplayers")) {
|
||||||
|
baritone.getFollowProcess().follow(EntityPlayer.class::isInstance); // O P P A
|
||||||
|
logDirect("Following any players");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("follow")) {
|
if (msg.startsWith("follow")) {
|
||||||
@@ -252,23 +284,24 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Not found");
|
logDirect("Not found");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
baritone.getFollowBehavior().follow(toFollow.get());
|
Entity effectivelyFinal = toFollow.get();
|
||||||
|
baritone.getFollowProcess().follow(x -> effectivelyFinal.equals(x));
|
||||||
logDirect("Following " + toFollow.get());
|
logDirect("Following " + toFollow.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("reloadall")) {
|
if (msg.equals("reloadall")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("saveall")) {
|
if (msg.equals("saveall")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save();
|
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().save();
|
||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("find")) {
|
if (msg.startsWith("find")) {
|
||||||
String blockType = msg.substring(4).trim();
|
String blockType = msg.substring(4).trim();
|
||||||
LinkedList<BlockPos> locs = WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, 4);
|
LinkedList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, 4);
|
||||||
logDirect("Have " + locs.size() + " locations");
|
logDirect("Have " + locs.size() + " locations");
|
||||||
for (BlockPos pos : locs) {
|
for (BlockPos pos : locs) {
|
||||||
Block actually = BlockStateInterface.get(pos).getBlock();
|
Block actually = BlockStateInterface.get(pos).getBlock();
|
||||||
@@ -284,7 +317,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
int quantity = Integer.parseInt(blockTypes[1]);
|
int quantity = Integer.parseInt(blockTypes[1]);
|
||||||
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
|
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
|
||||||
Objects.requireNonNull(block);
|
Objects.requireNonNull(block);
|
||||||
baritone.getMineBehavior().mine(quantity, block);
|
baritone.getMineProcess().mine(quantity, block);
|
||||||
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
||||||
return true;
|
return true;
|
||||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
|
||||||
@@ -295,14 +328,14 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
baritone.getMineBehavior().mine(0, blockTypes);
|
baritone.getMineProcess().mineByName(0, blockTypes);
|
||||||
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
|
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("thisway")) {
|
if (msg.startsWith("thisway")) {
|
||||||
try {
|
try {
|
||||||
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
|
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoal(goal);
|
||||||
logDirect("Goal: " + goal);
|
logDirect("Goal: " + goal);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
|
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
|
||||||
@@ -320,7 +353,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Set<IWaypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getByTag(tag);
|
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag);
|
||||||
// might as well show them from oldest to newest
|
// might as well show them from oldest to newest
|
||||||
List<IWaypoint> sorted = new ArrayList<>(waypoints);
|
List<IWaypoint> sorted = new ArrayList<>(waypoints);
|
||||||
sorted.sort(Comparator.comparingLong(IWaypoint::getCreationTimestamp));
|
sorted.sort(Comparator.comparingLong(IWaypoint::getCreationTimestamp));
|
||||||
@@ -348,7 +381,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
name = parts[0];
|
name = parts[0];
|
||||||
}
|
}
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
|
||||||
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
|
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -365,69 +398,59 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
Block block = ChunkPacker.stringToBlock(mining);
|
Block block = ChunkPacker.stringToBlock(mining);
|
||||||
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
logDirect("No locations for " + mining + " known, cancelling");
|
logDirect("No locations for " + mining + " known, cancelling");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<BlockPos> locs = baritone.getMineBehavior().searchWorld(Collections.singletonList(block), 64);
|
baritone.getGetToBlockProcess().getToBlock(block);
|
||||||
if (locs.isEmpty()) {
|
|
||||||
logDirect("No locations for " + mining + " known, cancelling");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pathingBehavior.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
|
||||||
pathingBehavior.path();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
|
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
logDirect("None saved for tag " + tag);
|
logDirect("None saved for tag " + tag);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
if (!pathingBehavior.path() && !goal.isInGoal(playerFeet())) {
|
|
||||||
logDirect("Currently executing a path. Please cancel it first.");
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("spawn") || msg.equals("bed")) {
|
if (msg.equals("spawn") || msg.equals("bed")) {
|
||||||
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
|
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
BlockPos spawnPoint = player().getBedLocation();
|
BlockPos spawnPoint = player().getBedLocation();
|
||||||
// for some reason the default spawnpoint is underground sometimes
|
// for some reason the default spawnpoint is underground sometimes
|
||||||
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
|
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
|
||||||
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
|
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
} else {
|
} else {
|
||||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
Goal goal = new GoalGetToBlock(waypoint.getLocation());
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
logDirect("Set goal to most recent bed " + goal);
|
logDirect("Set goal to most recent bed " + goal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("sethome")) {
|
if (msg.equals("sethome")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet()));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet()));
|
||||||
logDirect("Saved. Say home to set goal.");
|
logDirect("Saved. Say home to set goal.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("home")) {
|
if (msg.equals("home")) {
|
||||||
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
|
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
logDirect("home not saved");
|
logDirect("home not saved");
|
||||||
} else {
|
} else {
|
||||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||||
pathingBehavior.setGoal(goal);
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
pathingBehavior.path();
|
|
||||||
logDirect("Going to saved home " + goal);
|
logDirect("Going to saved home " + goal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("costs")) {
|
if (msg.equals("costs")) {
|
||||||
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(), playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
||||||
while (moves.contains(null)) {
|
while (moves.contains(null)) {
|
||||||
moves.remove(null);
|
moves.remove(null);
|
||||||
}
|
}
|
||||||
@@ -443,11 +466,6 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("pause")) {
|
|
||||||
boolean enabled = pathingBehavior.toggle();
|
|
||||||
logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + ".");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (msg.equals("damn")) {
|
if (msg.equals("damn")) {
|
||||||
logDirect("daniel");
|
logDirect("daniel");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import baritone.api.utils.Rotation;
|
|||||||
import net.minecraft.block.BlockSlab;
|
import net.minecraft.block.BlockSlab;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
@@ -51,10 +52,23 @@ public interface Helper {
|
|||||||
Minecraft mc = Minecraft.getMinecraft();
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
default EntityPlayerSP player() {
|
default EntityPlayerSP player() {
|
||||||
|
if (!mc.isCallingFromMinecraftThread()) {
|
||||||
|
throw new IllegalStateException("h00000000");
|
||||||
|
}
|
||||||
return mc.player;
|
return mc.player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default PlayerControllerMP playerController() { // idk
|
||||||
|
if (!mc.isCallingFromMinecraftThread()) {
|
||||||
|
throw new IllegalStateException("h00000000");
|
||||||
|
}
|
||||||
|
return mc.playerController;
|
||||||
|
}
|
||||||
|
|
||||||
default WorldClient world() {
|
default WorldClient world() {
|
||||||
|
if (!mc.isCallingFromMinecraftThread()) {
|
||||||
|
throw new IllegalStateException("h00000000");
|
||||||
|
}
|
||||||
return mc.world;
|
return mc.world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,13 @@
|
|||||||
|
|
||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.behavior.Behavior;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -30,16 +35,16 @@ import java.util.Map;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 11:20 PM
|
* @since 7/31/2018 11:20 PM
|
||||||
*/
|
*/
|
||||||
public final class InputOverrideHandler implements Helper {
|
public final class InputOverrideHandler extends Behavior implements Helper {
|
||||||
|
|
||||||
|
public InputOverrideHandler(Baritone baritone) {
|
||||||
|
super(baritone);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps keybinds to whether or not we are forcing their state down.
|
* Maps inputs to whether or not we are forcing their state down.
|
||||||
*/
|
*/
|
||||||
private final Map<KeyBinding, Boolean> inputForceStateMap = new HashMap<>();
|
private final Map<Input, Boolean> inputForceStateMap = new HashMap<>();
|
||||||
|
|
||||||
public final void clearAllKeys() {
|
|
||||||
inputForceStateMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not we are forcing down the specified {@link KeyBinding}.
|
* Returns whether or not we are forcing down the specified {@link KeyBinding}.
|
||||||
@@ -48,7 +53,17 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
* @return Whether or not it is being forced down
|
* @return Whether or not it is being forced down
|
||||||
*/
|
*/
|
||||||
public final boolean isInputForcedDown(KeyBinding key) {
|
public final boolean isInputForcedDown(KeyBinding key) {
|
||||||
return inputForceStateMap.getOrDefault(key, false);
|
return isInputForcedDown(Input.getInputForBind(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not we are forcing down the specified {@link Input}.
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
* @return Whether or not it is being forced down
|
||||||
|
*/
|
||||||
|
public final boolean isInputForcedDown(Input input) {
|
||||||
|
return input == null ? false : this.inputForceStateMap.getOrDefault(input, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,11 +73,47 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
* @param forced Whether or not the state is being forced
|
* @param forced Whether or not the state is being forced
|
||||||
*/
|
*/
|
||||||
public final void setInputForceState(Input input, boolean forced) {
|
public final void setInputForceState(Input input, boolean forced) {
|
||||||
inputForceStateMap.put(input.getKeyBinding(), forced);
|
this.inputForceStateMap.put(input, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Enum} representing the possible inputs that we may want to force.
|
* Clears the override state for all keys
|
||||||
|
*/
|
||||||
|
public final void clearAllKeys() {
|
||||||
|
this.inputForceStateMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onProcessKeyBinds() {
|
||||||
|
// Simulate the key being held down this tick
|
||||||
|
for (InputOverrideHandler.Input input : Input.values()) {
|
||||||
|
KeyBinding keyBinding = input.getKeyBinding();
|
||||||
|
|
||||||
|
if (isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
|
||||||
|
int keyCode = keyBinding.getKeyCode();
|
||||||
|
|
||||||
|
if (keyCode < Keyboard.KEYBOARD_SIZE) {
|
||||||
|
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Baritone.settings().leftClickWorkaround.get()) {
|
||||||
|
boolean stillClick = BlockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT.keyBinding));
|
||||||
|
setInputForceState(Input.CLICK_LEFT, stillClick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link Enum} representing the inputs that control the player's
|
||||||
|
* behavior. This includes moving, interacting with blocks, jumping,
|
||||||
|
* sneaking, and sprinting.
|
||||||
*/
|
*/
|
||||||
public enum Input {
|
public enum Input {
|
||||||
|
|
||||||
@@ -111,6 +162,11 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
*/
|
*/
|
||||||
SPRINT(mc.gameSettings.keyBindSprint);
|
SPRINT(mc.gameSettings.keyBindSprint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of {@link KeyBinding} to {@link Input}. Values should be queried through {@link #getInputForBind(KeyBinding)}
|
||||||
|
*/
|
||||||
|
private static final Map<KeyBinding, Input> bindToInputMap = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual game {@link KeyBinding} being forced.
|
* The actual game {@link KeyBinding} being forced.
|
||||||
*/
|
*/
|
||||||
@@ -126,5 +182,15 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
public final KeyBinding getKeyBinding() {
|
public final KeyBinding getKeyBinding() {
|
||||||
return this.keyBinding;
|
return this.keyBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the {@link Input} constant that is associated with the specified {@link KeyBinding}.
|
||||||
|
*
|
||||||
|
* @param binding The {@link KeyBinding} to find the associated {@link Input} for
|
||||||
|
* @return The {@link Input} associated with the specified {@link KeyBinding}
|
||||||
|
*/
|
||||||
|
public static Input getInputForBind(KeyBinding binding) {
|
||||||
|
return bindToInputMap.computeIfAbsent(binding, b -> Arrays.stream(values()).filter(input -> input.keyBinding == b).findFirst().orElse(null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.process.IBaritoneProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.behavior.PathingBehavior;
|
||||||
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
|
import baritone.pathing.path.PathExecutor;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PathingControlManager {
|
||||||
|
private final Baritone baritone;
|
||||||
|
private final HashSet<IBaritoneProcess> processes; // unGh
|
||||||
|
private IBaritoneProcess inControlLastTick;
|
||||||
|
private IBaritoneProcess inControlThisTick;
|
||||||
|
private PathingCommand command;
|
||||||
|
|
||||||
|
public PathingControlManager(Baritone baritone) {
|
||||||
|
this.baritone = baritone;
|
||||||
|
this.processes = new HashSet<>();
|
||||||
|
baritone.registerEventListener(new AbstractGameEventListener() { // needs to be after all behavior ticks
|
||||||
|
@Override
|
||||||
|
public void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
postTick();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerProcess(IBaritoneProcess process) {
|
||||||
|
process.onLostControl(); // make sure it's reset
|
||||||
|
processes.add(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelEverything() {
|
||||||
|
for (IBaritoneProcess proc : processes) {
|
||||||
|
proc.onLostControl();
|
||||||
|
if (proc.isActive() && !proc.isTemporary()) { // it's okay for a temporary thing (like combat pause) to maintain control even if you say to cancel
|
||||||
|
// but not for a non temporary thing
|
||||||
|
throw new IllegalStateException(proc.displayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBaritoneProcess inControlThisTick() {
|
||||||
|
return inControlThisTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preTick() {
|
||||||
|
inControlLastTick = inControlThisTick;
|
||||||
|
command = doTheStuff();
|
||||||
|
if (command == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
|
switch (command.commandType) {
|
||||||
|
case REQUEST_PAUSE:
|
||||||
|
p.requestPause();
|
||||||
|
break;
|
||||||
|
case CANCEL_AND_SET_GOAL:
|
||||||
|
p.secretInternalSetGoal(command.goal);
|
||||||
|
p.cancelSegmentIfSafe();
|
||||||
|
break;
|
||||||
|
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SET_GOAL_AND_PATH:
|
||||||
|
// now this i can do
|
||||||
|
if (command.goal != null) {
|
||||||
|
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command.goal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postTick() {
|
||||||
|
// if we did this in pretick, it would suck
|
||||||
|
// we use the time between ticks as calculation time
|
||||||
|
// therefore, we only cancel and recalculate after the tick for the current path has executed
|
||||||
|
// "it would suck" means it would actually execute a path every other tick
|
||||||
|
if (command == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
|
switch (command.commandType) {
|
||||||
|
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (command.goal == null || forceRevalidate(command.goal) || revalidateGoal(command.goal)) {
|
||||||
|
// pwnage
|
||||||
|
p.softCancelIfSafe();
|
||||||
|
}
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
break;
|
||||||
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (Baritone.settings().cancelOnGoalInvalidation.get() && (command.goal == null || revalidateGoal(command.goal))) {
|
||||||
|
p.softCancelIfSafe();
|
||||||
|
}
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean forceRevalidate(Goal newGoal) {
|
||||||
|
PathExecutor current = baritone.getPathingBehavior().getCurrent();
|
||||||
|
if (current != null) {
|
||||||
|
if (newGoal.isInGoal(current.getPath().getDest())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !newGoal.toString().equals(current.getPath().getGoal().toString());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean revalidateGoal(Goal newGoal) {
|
||||||
|
PathExecutor current = baritone.getPathingBehavior().getCurrent();
|
||||||
|
if (current != null) {
|
||||||
|
Goal intended = current.getPath().getGoal();
|
||||||
|
BlockPos end = current.getPath().getDest();
|
||||||
|
if (intended.isInGoal(end) && !newGoal.isInGoal(end)) {
|
||||||
|
// this path used to end in the goal
|
||||||
|
// but the goal has changed, so there's no reason to continue...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PathingCommand doTheStuff() {
|
||||||
|
List<IBaritoneProcess> inContention = processes.stream().filter(IBaritoneProcess::isActive).sorted(Comparator.comparingDouble(IBaritoneProcess::priority)).collect(Collectors.toList());
|
||||||
|
boolean found = false;
|
||||||
|
boolean cancelOthers = false;
|
||||||
|
PathingCommand exec = null;
|
||||||
|
for (int i = inContention.size() - 1; i >= 0; i--) { // truly a gamer moment
|
||||||
|
IBaritoneProcess proc = inContention.get(i);
|
||||||
|
if (found) {
|
||||||
|
if (cancelOthers) {
|
||||||
|
proc.onLostControl();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
|
||||||
|
if (exec == null) {
|
||||||
|
if (proc.isActive()) {
|
||||||
|
throw new IllegalStateException(proc.displayName());
|
||||||
|
}
|
||||||
|
proc.onLostControl();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//System.out.println("Executing command " + exec.commandType + " " + exec.goal + " from " + proc.displayName());
|
||||||
|
inControlThisTick = proc;
|
||||||
|
found = true;
|
||||||
|
cancelOthers = !proc.isTemporary();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exec;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ package baritone.utils;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.init.Enchantments;
|
import net.minecraft.init.Enchantments;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
@@ -36,7 +37,7 @@ import java.util.function.Function;
|
|||||||
*
|
*
|
||||||
* @author Avery, Brady, leijurv
|
* @author Avery, Brady, leijurv
|
||||||
*/
|
*/
|
||||||
public class ToolSet implements Helper {
|
public class ToolSet {
|
||||||
/**
|
/**
|
||||||
* A cache mapping a {@link Block} to how long it will take to break
|
* A cache mapping a {@link Block} to how long it will take to break
|
||||||
* with this toolset, given the optimum tool is used.
|
* with this toolset, given the optimum tool is used.
|
||||||
@@ -48,8 +49,11 @@ public class ToolSet implements Helper {
|
|||||||
*/
|
*/
|
||||||
private final Function<Block, Double> backendCalculation;
|
private final Function<Block, Double> backendCalculation;
|
||||||
|
|
||||||
public ToolSet() {
|
private final EntityPlayerSP player;
|
||||||
|
|
||||||
|
public ToolSet(EntityPlayerSP player) {
|
||||||
breakStrengthCache = new HashMap<>();
|
breakStrengthCache = new HashMap<>();
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
if (Baritone.settings().considerPotionEffects.get()) {
|
if (Baritone.settings().considerPotionEffects.get()) {
|
||||||
double amplifier = potionAmplifier();
|
double amplifier = potionAmplifier();
|
||||||
@@ -98,7 +102,7 @@ public class ToolSet implements Helper {
|
|||||||
int materialCost = Integer.MIN_VALUE;
|
int materialCost = Integer.MIN_VALUE;
|
||||||
IBlockState blockState = b.getDefaultState();
|
IBlockState blockState = b.getDefaultState();
|
||||||
for (byte i = 0; i < 9; i++) {
|
for (byte i = 0; i < 9; i++) {
|
||||||
ItemStack itemStack = player().inventory.getStackInSlot(i);
|
ItemStack itemStack = player.inventory.getStackInSlot(i);
|
||||||
double v = calculateStrVsBlock(itemStack, blockState);
|
double v = calculateStrVsBlock(itemStack, blockState);
|
||||||
if (v > value) {
|
if (v > value) {
|
||||||
value = v;
|
value = v;
|
||||||
@@ -123,7 +127,7 @@ public class ToolSet implements Helper {
|
|||||||
* @return A double containing the destruction ticks with the best tool
|
* @return A double containing the destruction ticks with the best tool
|
||||||
*/
|
*/
|
||||||
private double getBestDestructionTime(Block b) {
|
private double getBestDestructionTime(Block b) {
|
||||||
ItemStack stack = player().inventory.getStackInSlot(getBestSlot(b));
|
ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b));
|
||||||
return calculateStrVsBlock(stack, b.getDefaultState());
|
return calculateStrVsBlock(stack, b.getDefaultState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,11 +168,11 @@ public class ToolSet implements Helper {
|
|||||||
*/
|
*/
|
||||||
private double potionAmplifier() {
|
private double potionAmplifier() {
|
||||||
double speed = 1;
|
double speed = 1;
|
||||||
if (player().isPotionActive(MobEffects.HASTE)) {
|
if (player.isPotionActive(MobEffects.HASTE)) {
|
||||||
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
speed *= 1 + (player.getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
||||||
}
|
}
|
||||||
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
|
if (player.isPotionActive(MobEffects.MINING_FATIGUE)) {
|
||||||
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
switch (player.getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
||||||
case 0:
|
case 0:
|
||||||
speed *= 0.3;
|
speed *= 0.3;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -17,9 +17,13 @@
|
|||||||
|
|
||||||
package baritone.utils.accessor;
|
package baritone.utils.accessor;
|
||||||
|
|
||||||
|
import baritone.cache.WorldProvider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see WorldProvider
|
||||||
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:36 AM
|
* @since 8/4/2018 11:36 AM
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
|
|
||||||
package baritone.utils.accessor;
|
package baritone.utils.accessor;
|
||||||
|
|
||||||
|
import net.minecraft.world.WorldProvider;
|
||||||
import net.minecraft.world.chunk.storage.IChunkLoader;
|
import net.minecraft.world.chunk.storage.IChunkLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see WorldProvider
|
||||||
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:33 AM
|
* @since 8/4/2018 11:33 AM
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,10 +17,14 @@
|
|||||||
|
|
||||||
package baritone.utils.pathing;
|
package baritone.utils.pathing;
|
||||||
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.world.border.WorldBorder;
|
import net.minecraft.world.border.WorldBorder;
|
||||||
|
|
||||||
public class BetterWorldBorder implements Helper {
|
/**
|
||||||
|
* Essentially, a "rule" for the path finder, prevents proposed movements from attempting to venture
|
||||||
|
* into the world border, and prevents actual movements from placing blocks in the world border.
|
||||||
|
*/
|
||||||
|
public class BetterWorldBorder {
|
||||||
|
|
||||||
private final double minX;
|
private final double minX;
|
||||||
private final double maxX;
|
private final double maxX;
|
||||||
private final double minZ;
|
private final double minZ;
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils.pathing;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.pathing.path.CutoffPath;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
|
public abstract class PathBase implements IPath {
|
||||||
|
@Override
|
||||||
|
public IPath cutoffAtLoadedChunks(World world) {
|
||||||
|
for (int i = 0; i < positions().size(); i++) {
|
||||||
|
BlockPos pos = positions().get(i);
|
||||||
|
if (world.getChunk(pos) instanceof EmptyChunk) {
|
||||||
|
return new CutoffPath(this, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPath staticCutoff(Goal destination) {
|
||||||
|
if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if (destination == null || destination.isInGoal(getDest())) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
|
||||||
|
int newLength = (int) ((length() - 1) * factor);
|
||||||
|
return new CutoffPath(this, newLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,18 +42,6 @@ public enum PathingBlockType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PathingBlockType fromBits(boolean b1, boolean b2) {
|
public static PathingBlockType fromBits(boolean b1, boolean b2) {
|
||||||
if (b1) {
|
return b1 ? b2 ? SOLID : AVOID : b2 ? WATER : AIR;
|
||||||
if (b2) {
|
|
||||||
return PathingBlockType.SOLID;
|
|
||||||
} else {
|
|
||||||
return PathingBlockType.AVOID;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (b2) {
|
|
||||||
return PathingBlockType.WATER;
|
|
||||||
} else {
|
|
||||||
return PathingBlockType.AIR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user