Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ce574266f | |||
| a5b9885767 | |||
| 2daedecf92 | |||
| db24822d2f | |||
| 59320d9b85 | |||
| 9dfcef6356 | |||
| ae3fc14b52 | |||
| f8681d179d | |||
| f23630064e | |||
| bec7f9be96 | |||
| 09e94eaa8e | |||
| 5f29bb3e7f | |||
| 1ad6a0d5b5 | |||
| f727e71eaf | |||
| 14f006c3a5 | |||
| 200211c186 | |||
| 5ca214534d | |||
| 85ea21e83b | |||
| 7d572d748b | |||
| fbcae10f96 | |||
| a4495ce80a | |||
| f5478f6169 | |||
| ae1e229619 | |||
| bc5982b994 | |||
| e971d5d43f | |||
| ee9519d891 | |||
| 58bb209158 | |||
| 23dc97ad5e | |||
| 84b580b001 | |||
| 227b303669 | |||
| 712a0a3905 | |||
| 76427b8ecb | |||
| 8b6d621d20 | |||
| 7898b24bac | |||
| 39648c5dc6 | |||
| 83e6b2fdfe | |||
| 816727d65b | |||
| 0e012adb6c | |||
| 539b0e64c8 | |||
| 258700ee7b | |||
| 1da72ba473 | |||
| c2c69f243e | |||
| dffbb8e4c8 | |||
| bebdede33b | |||
| 50d37bb311 | |||
| bbb73008ac | |||
| c324f11a96 | |||
| c4eb6be0fe | |||
| 64200030d2 | |||
| 4d7e74365b | |||
| b9b25e7e6b | |||
| 8a4f48f08d | |||
| ae9ab03e51 | |||
| 02478ee887 | |||
| 57f238de7d | |||
| 77938a77e8 | |||
| d41aa5f9ae | |||
| 0ef3386ebf | |||
| 9703de86d3 | |||
| 764e8d7daa | |||
| 18f5c129a4 | |||
| 807d6a0cf4 | |||
| a0ab2a8ba7 | |||
| 90d0fb7efb | |||
| fe4290b218 | |||
| cc04342358 | |||
| 66da826eab | |||
| dcb93dab50 | |||
| f8c0b4c1c1 | |||
| c41f65d4f6 | |||
| 54811fb643 | |||
| 92442dcdb9 | |||
| 68af1f3bb3 | |||
| a796e9c047 | |||
| 2c32cadf18 | |||
| 32cd519bcf | |||
| 88908d8776 | |||
| 79bd26968a | |||
| 2d288c7a47 | |||
| 2c46458bc1 | |||
| 9c37414e50 | |||
| fb667c3b4d | |||
| da07b63e0a | |||
| 1fe262929e | |||
| 0ee93aea23 | |||
| 836b41a3aa | |||
| c370461a24 | |||
| a753fe5df9 | |||
| 27aeba3f8b | |||
| 141a9f92cb | |||
| 5e4f0b47c5 | |||
| d0a88987a8 | |||
| 9cb199d40a | |||
| a1d218b37a | |||
| 7ae1a9f6e4 | |||
| fd74fcabc0 | |||
| 4da155c0ed | |||
| 7a3f7f9a9e | |||
| 1212d34f91 |
@@ -25,8 +25,6 @@ Here are some links to help to get started:
|
|||||||
|
|
||||||
- [Installation](INSTALL.md)
|
- [Installation](INSTALL.md)
|
||||||
|
|
||||||
There's also some useful information down below
|
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
## Command Line
|
## Command Line
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
Objects.requireNonNull(extension);
|
Objects.requireNonNull(extension);
|
||||||
|
|
||||||
// for some reason cant use Class.forName
|
// for some reason cant use Class.forName
|
||||||
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass();
|
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
||||||
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
||||||
f_replacer.setAccessible(true);
|
f_replacer.setAccessible(true);
|
||||||
Object replacer = f_replacer.get(extension);
|
Object replacer = f_replacer.get(extension);
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ public enum MappingType {
|
|||||||
SEARGE,
|
SEARGE,
|
||||||
NOTCH,
|
NOTCH,
|
||||||
CUSTOM // forgegradle
|
CUSTOM // forgegradle
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,4 +60,4 @@ public class ReobfWrapper {
|
|||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import baritone.api.behavior.ILookBehavior;
|
|||||||
import baritone.api.behavior.IPathingBehavior;
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.cache.IWorldProvider;
|
import baritone.api.cache.IWorldProvider;
|
||||||
import baritone.api.event.listener.IEventBus;
|
import baritone.api.event.listener.IEventBus;
|
||||||
|
import baritone.api.pathing.calc.IPathingControlManager;
|
||||||
import baritone.api.process.ICustomGoalProcess;
|
import baritone.api.process.ICustomGoalProcess;
|
||||||
import baritone.api.process.IFollowProcess;
|
import baritone.api.process.IFollowProcess;
|
||||||
import baritone.api.process.IGetToBlockProcess;
|
import baritone.api.process.IGetToBlockProcess;
|
||||||
@@ -64,6 +65,8 @@ public interface IBaritone {
|
|||||||
*/
|
*/
|
||||||
IWorldProvider getWorldProvider();
|
IWorldProvider getWorldProvider();
|
||||||
|
|
||||||
|
IPathingControlManager getPathingControlManager();
|
||||||
|
|
||||||
IInputOverrideHandler getInputOverrideHandler();
|
IInputOverrideHandler getInputOverrideHandler();
|
||||||
|
|
||||||
ICustomGoalProcess getCustomGoalProcess();
|
ICustomGoalProcess getCustomGoalProcess();
|
||||||
|
|||||||
@@ -68,6 +68,16 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
|
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) beacuse it uses hunger
|
||||||
|
*/
|
||||||
|
public Setting<Double> jumpPenalty = new Setting<>(2D);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walking on water uses up hunger really quick, so penalize it
|
||||||
|
*/
|
||||||
|
public Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
||||||
* Reliability: questionable.
|
* Reliability: questionable.
|
||||||
@@ -101,6 +111,15 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow descending diagonally
|
||||||
|
* <p>
|
||||||
|
* Safer than allowParkour yet still slightly unsafe, can make contact with unchecked adjacent blocks, so it's unsafe in the nether.
|
||||||
|
* <p>
|
||||||
|
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||||
*/
|
*/
|
||||||
@@ -153,10 +172,8 @@ public class Settings {
|
|||||||
* metric gets better and better with each block, instead of slightly worse.
|
* metric gets better and better with each block, instead of slightly worse.
|
||||||
* <p>
|
* <p>
|
||||||
* Finding the optimal path is worth it, so it's the default.
|
* Finding the optimal path is worth it, so it's the default.
|
||||||
* <p>
|
|
||||||
* This value is an expression instead of a literal so that it's exactly equal to SPRINT_ONE_BLOCK_COST defined in ActionCosts.java
|
|
||||||
*/
|
*/
|
||||||
public Setting<Double> costHeuristic = new Setting<>(20 / 5.612);
|
public Setting<Double> costHeuristic = new Setting<>(3.563);
|
||||||
|
|
||||||
// a bunch of obscure internal A* settings that you probably don't want to change
|
// a bunch of obscure internal A* settings that you probably don't want to change
|
||||||
/**
|
/**
|
||||||
@@ -435,10 +452,6 @@ public class Settings {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
||||||
* <p>
|
|
||||||
* {@code false}: works on cosmic prisons
|
|
||||||
* <p>
|
|
||||||
* LOL
|
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
|
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
|
|||||||
@Override
|
@Override
|
||||||
default void onPlayerUpdate(PlayerUpdateEvent event) {}
|
default void onPlayerUpdate(PlayerUpdateEvent event) {}
|
||||||
|
|
||||||
@Override
|
|
||||||
default void onProcessKeyBinds() {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void onSendChatMessage(ChatEvent event) {}
|
default void onSendChatMessage(ChatEvent event) {}
|
||||||
|
|
||||||
|
|||||||
@@ -49,11 +49,6 @@ public interface IGameEventListener {
|
|||||||
*/
|
*/
|
||||||
void onPlayerUpdate(PlayerUpdateEvent event);
|
void onPlayerUpdate(PlayerUpdateEvent event);
|
||||||
|
|
||||||
/**
|
|
||||||
* Run once per game tick from before keybinds are processed.
|
|
||||||
*/
|
|
||||||
void onProcessKeyBinds();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs whenever the client player sends a message to the server.
|
* Runs whenever the client player sends a message to the server.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public interface IPathFinder {
|
|||||||
*
|
*
|
||||||
* @param primaryTimeout If a path is found, the path finder will stop after this amount of time
|
* @param primaryTimeout If a path is found, the path finder will stop after this amount of time
|
||||||
* @param failureTimeout If a path isn't found, the path finder will continue for this amount of time
|
* @param failureTimeout If a path isn't found, the path finder will continue for this amount of time
|
||||||
*
|
|
||||||
* @return The final path
|
* @return The final path
|
||||||
*/
|
*/
|
||||||
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
|
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ public interface Goal {
|
|||||||
* @param x The goal X position
|
* @param x The goal X position
|
||||||
* @param y The goal Y position
|
* @param y The goal Y position
|
||||||
* @param z The goal Z position
|
* @param z The goal Z position
|
||||||
*
|
|
||||||
* @return Whether or not it satisfies this goal
|
* @return Whether or not it satisfies this goal
|
||||||
*/
|
*/
|
||||||
boolean isInGoal(int x, int y, int z);
|
boolean isInGoal(int x, int y, int z);
|
||||||
@@ -44,7 +43,6 @@ public interface Goal {
|
|||||||
* @param x The goal X position
|
* @param x The goal X position
|
||||||
* @param y The goal Y position
|
* @param y The goal Y position
|
||||||
* @param z The goal Z position
|
* @param z The goal Z position
|
||||||
*
|
|
||||||
* @return The estimate number of ticks to satisfy the goal
|
* @return The estimate number of ticks to satisfy the goal
|
||||||
*/
|
*/
|
||||||
double heuristic(int x, int y, int z);
|
double heuristic(int x, int y, int z);
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ public final class BetterBlockPos extends BlockPos {
|
|||||||
public final int x;
|
public final int x;
|
||||||
public final int y;
|
public final int y;
|
||||||
public final int z;
|
public final int z;
|
||||||
|
public static long numCreated;
|
||||||
|
|
||||||
|
static {
|
||||||
|
numCreated = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
numCreated++;
|
||||||
|
}
|
||||||
|
|
||||||
public BetterBlockPos(int x, int y, int z) {
|
public BetterBlockPos(int x, int y, int z) {
|
||||||
super(x, y, z);
|
super(x, y, z);
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ import net.minecraft.client.settings.KeyBinding;
|
|||||||
*/
|
*/
|
||||||
public interface IInputOverrideHandler extends IBehavior {
|
public interface IInputOverrideHandler extends IBehavior {
|
||||||
|
|
||||||
default boolean isInputForcedDown(KeyBinding key) {
|
Boolean isInputForcedDown(KeyBinding key);
|
||||||
return isInputForcedDown(Input.getInputForBind(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isInputForcedDown(Input input);
|
boolean isInputForcedDown(Input input);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package baritone.api.utils;
|
|||||||
import baritone.api.cache.IWorldData;
|
import baritone.api.cache.IWorldData;
|
||||||
import net.minecraft.block.BlockSlab;
|
import net.minecraft.block.BlockSlab;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
@@ -37,7 +36,7 @@ public interface IPlayerContext {
|
|||||||
|
|
||||||
EntityPlayerSP player();
|
EntityPlayerSP player();
|
||||||
|
|
||||||
PlayerControllerMP playerController();
|
IPlayerController playerController();
|
||||||
|
|
||||||
World world();
|
World world();
|
||||||
|
|
||||||
|
|||||||
+21
-2
@@ -17,11 +17,30 @@
|
|||||||
|
|
||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.inventory.ClickType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 12/14/2018
|
||||||
*/
|
*/
|
||||||
public class Logger {
|
public interface IPlayerController {
|
||||||
|
|
||||||
|
boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side);
|
||||||
|
|
||||||
|
void resetBlockRemoving();
|
||||||
|
|
||||||
|
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
|
||||||
|
|
||||||
|
void setGameType(GameType type);
|
||||||
|
|
||||||
|
GameType getGameType();
|
||||||
|
|
||||||
|
default double getBlockReachDistance() {
|
||||||
|
return this.getGameType().isCreative() ? 5.0F : 4.5F;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ package baritone.api.utils;
|
|||||||
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class PathCalculationResult {
|
public class PathCalculationResult {
|
||||||
@@ -31,11 +32,9 @@ public class PathCalculationResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PathCalculationResult(Type type, IPath path) {
|
public PathCalculationResult(Type type, IPath path) {
|
||||||
|
Objects.requireNonNull(type);
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
if (type == null) {
|
|
||||||
throw new IllegalArgumentException("come on");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Optional<IPath> getPath() {
|
public final Optional<IPath> getPath() {
|
||||||
|
|||||||
@@ -127,6 +127,16 @@ public final class RotationUtils {
|
|||||||
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
|
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ctx Context for the viewing entity
|
||||||
|
* @param pos The target block position
|
||||||
|
* @return The optional rotation
|
||||||
|
* @see #reachable(EntityPlayerSP, BlockPos, double)
|
||||||
|
*/
|
||||||
|
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
|
||||||
|
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the specified entity is able to reach the center of any of the sides
|
* Determines if the specified entity is able to reach the center of any of the sides
|
||||||
* of the specified block. It first checks if the block center is reachable, and if so,
|
* of the specified block. It first checks if the block center is reachable, and if so,
|
||||||
|
|||||||
@@ -18,56 +18,77 @@
|
|||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
import baritone.api.Settings;
|
import baritone.api.Settings;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.BufferedReader;
|
||||||
import java.io.FileOutputStream;
|
import java.io.BufferedWriter;
|
||||||
import java.util.*;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.minecraft.client.Minecraft.getMinecraft;
|
||||||
|
|
||||||
public class SettingsUtil {
|
public class SettingsUtil {
|
||||||
|
|
||||||
private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt");
|
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||||
|
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>[^ ]+)"); // 2 words separated by spaces
|
||||||
|
|
||||||
private static final Map<Class<?>, SettingsIO> map;
|
private static final Map<Class<?>, SettingsIO> map;
|
||||||
|
|
||||||
|
private static boolean isComment(String line) {
|
||||||
|
return line.startsWith("#") || line.startsWith("//");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void forEachLine(Path file, Consumer<String> consumer) throws IOException {
|
||||||
|
try (BufferedReader scan = Files.newBufferedReader(file)) {
|
||||||
|
String line;
|
||||||
|
while ((line = scan.readLine()) != null) {
|
||||||
|
if (line.isEmpty() || isComment(line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
consumer.accept(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void readAndApply(Settings settings) {
|
public static void readAndApply(Settings settings) {
|
||||||
try (Scanner scan = new Scanner(settingsFile)) {
|
try {
|
||||||
while (scan.hasNextLine()) {
|
forEachLine(SETTINGS_PATH, line -> {
|
||||||
String line = scan.nextLine();
|
Matcher matcher = SETTING_PATTERN.matcher(line);
|
||||||
if (line.isEmpty()) {
|
if (!matcher.matches()) {
|
||||||
continue;
|
System.out.println("Invalid syntax in setting file: " + line);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (line.startsWith("#") || line.startsWith("//")) {
|
|
||||||
continue;
|
String settingName = matcher.group("setting").toLowerCase();
|
||||||
}
|
String settingValue = matcher.group("value");
|
||||||
int space = line.indexOf(" ");
|
|
||||||
if (space == -1) {
|
|
||||||
System.out.println("Skipping invalid line with no space: " + line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String settingName = line.substring(0, space).trim().toLowerCase();
|
|
||||||
String settingValue = line.substring(space).trim();
|
|
||||||
try {
|
try {
|
||||||
parseAndApply(settings, settingName, settingValue);
|
parseAndApply(settings, settingName, settingValue);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
|
||||||
System.out.println("Unable to parse line " + line);
|
System.out.println("Unable to parse line " + line);
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
|
||||||
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
|
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void save(Settings settings) {
|
public static synchronized void save(Settings settings) {
|
||||||
try (FileOutputStream out = new FileOutputStream(settingsFile)) {
|
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
|
||||||
for (Settings.Setting setting : settings.allSettings) {
|
for (Settings.Setting setting : settings.allSettings) {
|
||||||
if (setting.get() == null) {
|
if (setting.get() == null) {
|
||||||
System.out.println("NULL SETTING?" + setting.getName());
|
System.out.println("NULL SETTING?" + setting.getName());
|
||||||
@@ -83,11 +104,11 @@ public class SettingsUtil {
|
|||||||
if (io == null) {
|
if (io == null) {
|
||||||
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName());
|
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName());
|
||||||
}
|
}
|
||||||
out.write((setting.getName() + " " + io.toString.apply(setting.get()) + "\n").getBytes());
|
out.write(setting.getName() + " " + io.toString.apply(setting.get()) + "\n");
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
System.out.println("Exception thrown while saving Baritone settings!");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
System.out.println("Exception while saving Baritone settings!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.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.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
@@ -31,6 +33,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
@Mixin(KeyBinding.class)
|
@Mixin(KeyBinding.class)
|
||||||
public class MixinKeyBinding {
|
public class MixinKeyBinding {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public int pressTime;
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "isKeyDown",
|
method = "isKeyDown",
|
||||||
at = @At("HEAD"),
|
at = @At("HEAD"),
|
||||||
@@ -38,8 +43,26 @@ public class MixinKeyBinding {
|
|||||||
)
|
)
|
||||||
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
||||||
// only the primary baritone forces keys
|
// only the primary baritone forces keys
|
||||||
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
|
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
|
||||||
cir.setReturnValue(true);
|
if (force != null) {
|
||||||
|
cir.setReturnValue(force); // :sunglasses:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "isPressed",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
private void isPressed(CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
// only the primary baritone forces keys
|
||||||
|
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
|
||||||
|
if (force != null && force == false) { // <-- cursed
|
||||||
|
if (pressTime > 0) {
|
||||||
|
Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you");
|
||||||
|
pressTime--;
|
||||||
|
}
|
||||||
|
cir.setReturnValue(force); // :sunglasses:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,15 +96,6 @@ public class MixinMinecraft {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "processKeyBinds",
|
|
||||||
at = @At("HEAD")
|
|
||||||
)
|
|
||||||
private void runTickKeyboard(CallbackInfo ci) {
|
|
||||||
// keyboard input is only the primary baritone
|
|
||||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onProcessKeyBinds();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ public class Baritone implements IBaritone {
|
|||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PathingControlManager getPathingControlManager() {
|
public PathingControlManager getPathingControlManager() {
|
||||||
return this.pathingControlManager;
|
return this.pathingControlManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,10 +55,7 @@ public class InventoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void swapWithHotBar(int inInventory, int inHotbar) {
|
private void swapWithHotBar(int inInventory, int inHotbar) {
|
||||||
if (inInventory < 9) {
|
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
||||||
inInventory += 36;
|
|
||||||
}
|
|
||||||
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int firstValidThrowaway() { // TODO offhand idk
|
private int firstValidThrowaway() { // TODO offhand idk
|
||||||
@@ -81,7 +78,7 @@ public class InventoryBehavior extends Behavior {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (klass.isInstance(stack.getItem())) {
|
if (klass.isInstance(stack.getItem())) {
|
||||||
double speed = ToolSet.calculateStrVsBlock(stack, against.getDefaultState()); // takes into account enchants
|
double speed = ToolSet.calculateSpeedVsBlock(stack, against.getDefaultState()); // takes into account enchants
|
||||||
if (speed > bestSpeed) {
|
if (speed > bestSpeed) {
|
||||||
bestSpeed = speed;
|
bestSpeed = speed;
|
||||||
bestInd = i;
|
bestInd = i;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import baritone.Baritone;
|
|||||||
import baritone.api.event.events.BlockInteractEvent;
|
import baritone.api.event.events.BlockInteractEvent;
|
||||||
import baritone.api.event.events.PacketEvent;
|
import baritone.api.event.events.PacketEvent;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.cache.ContainerMemory;
|
import baritone.cache.ContainerMemory;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
@@ -60,6 +61,14 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
super(baritone);
|
super(baritone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
enderChestWindowId = null;
|
||||||
|
futureInventories.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||||
if (event.getState() == EventState.PRE) {
|
if (event.getState() == EventState.PRE) {
|
||||||
@@ -116,12 +125,10 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
|
|
||||||
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
||||||
System.out.println(packet.getWindowTitle());
|
System.out.println(packet.getWindowTitle());
|
||||||
if (packet.getWindowTitle() instanceof TextComponentTranslation) {
|
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
||||||
// title is not customized (i.e. this isn't just a renamed shulker)
|
// title is not customized (i.e. this isn't just a renamed shulker)
|
||||||
if (((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
enderChestWindowId = packet.getWindowId();
|
||||||
enderChestWindowId = packet.getWindowId();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
futureInventories.stream()
|
futureInventories.stream()
|
||||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
||||||
@@ -177,7 +184,7 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
||||||
BlockStateInterface bsi = new CalculationContext(baritone).bsi();
|
BlockStateInterface bsi = new CalculationContext(baritone).bsi;
|
||||||
Block block = bsi.get0(in).getBlock();
|
Block block = bsi.get0(in).getBlock();
|
||||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
||||||
return null; // other things that have contents, but can be placed adjacent without combining
|
return null; // other things that have contents, but can be placed adjacent without combining
|
||||||
|
|||||||
@@ -433,7 +433,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
Optional<IPath> path = calcResult.getPath();
|
Optional<IPath> path = calcResult.getPath();
|
||||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
||||||
path = path.map(p -> {
|
path = path.map(p -> {
|
||||||
IPath result = p.cutoffAtLoadedChunks(context.bsi());
|
IPath result = p.cutoffAtLoadedChunks(context.bsi);
|
||||||
|
|
||||||
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");
|
||||||
@@ -499,7 +499,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
Goal transformed = goal;
|
Goal transformed = goal;
|
||||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
||||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||||
if (context.world().getChunk(pos) instanceof EmptyChunk) {
|
if (!context.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ())) {
|
||||||
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -179,8 +179,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
if (region == null) {
|
if (region == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
|
int distX = (region.getX() << 9 + 256) - pruneCenter.getX();
|
||||||
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
|
int distZ = (region.getZ() << 9 + 256) - pruneCenter.getZ();
|
||||||
double dist = Math.sqrt(distX * distX + distZ * distZ);
|
double dist = Math.sqrt(distX * distX + distZ * distZ);
|
||||||
if (dist > 1024) {
|
if (dist > 1024) {
|
||||||
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
|
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
|
||||||
@@ -215,7 +215,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
if (mostRecentlyModified == null) {
|
if (mostRecentlyModified == null) {
|
||||||
return new BlockPos(0, 0, 0);
|
return new BlockPos(0, 0, 0);
|
||||||
}
|
}
|
||||||
return new BlockPos(mostRecentlyModified.x * 16 + 8, 0, mostRecentlyModified.z * 16 + 8);
|
return new BlockPos(mostRecentlyModified.x << 4 + 8, 0, mostRecentlyModified.z << 4 + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized List<CachedRegion> allRegions() {
|
private synchronized List<CachedRegion> allRegions() {
|
||||||
|
|||||||
+2
-1
@@ -123,7 +123,8 @@ public class ContainerMemory implements IContainerMemory {
|
|||||||
return out.array();
|
return out.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketBuffer writeItemStacks(List<ItemStack> write, PacketBuffer out) {
|
public static PacketBuffer writeItemStacks(List<ItemStack> write, PacketBuffer out2) {
|
||||||
|
PacketBuffer out = out2; // avoid reassigning an argument LOL
|
||||||
out = new PacketBuffer(out.writeInt(write.size()));
|
out = new PacketBuffer(out.writeInt(write.size()));
|
||||||
for (ItemStack stack : write) {
|
for (ItemStack stack : write) {
|
||||||
out = out.writeItemStack(stack);
|
out = out.writeItemStack(stack);
|
||||||
|
|||||||
+16
-35
@@ -28,8 +28,9 @@ import net.minecraft.world.chunk.BlockStateContainer;
|
|||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public enum WorldScanner implements IWorldScanner {
|
public enum WorldScanner implements IWorldScanner {
|
||||||
@@ -41,7 +42,7 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
if (blocks.contains(null)) {
|
if (blocks.contains(null)) {
|
||||||
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
|
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
|
||||||
}
|
}
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
ArrayList<BlockPos> res = new ArrayList<>();
|
||||||
if (blocks.isEmpty()) {
|
if (blocks.isEmpty()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -71,33 +72,7 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
allUnloaded = false;
|
allUnloaded = false;
|
||||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
|
||||||
chunkX = chunkX << 4;
|
|
||||||
chunkZ = chunkZ << 4;
|
|
||||||
for (int y0 = 0; y0 < 16; y0++) {
|
|
||||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
|
||||||
if (extendedblockstorage == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int yReal = y0 << 4;
|
|
||||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
|
||||||
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
|
||||||
// for better cache locality, iterate in that order
|
|
||||||
for (int y = 0; y < 16; y++) {
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
IBlockState state = bsc.get(x, y, z);
|
|
||||||
if (blocks.contains(state.getBlock())) {
|
|
||||||
int yy = yReal | y;
|
|
||||||
res.add(new BlockPos(chunkX | x, yy, chunkZ | z));
|
|
||||||
if (Math.abs(yy - playerY) < yLevelThreshold) {
|
|
||||||
foundWithinY = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((allUnloaded && foundChunks)
|
if ((allUnloaded && foundChunks)
|
||||||
@@ -124,7 +99,12 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
ArrayList<BlockPos> res = new ArrayList<>();
|
||||||
|
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY) {
|
||||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
for (int y0 = 0; y0 < 16; y0++) {
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
@@ -133,21 +113,22 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
}
|
}
|
||||||
int yReal = y0 << 4;
|
int yReal = y0 << 4;
|
||||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
|
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||||
|
// for better cache locality, iterate in that order
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
IBlockState state = bsc.get(x, y, z);
|
IBlockState state = bsc.get(x, y, z);
|
||||||
if (blocks.contains(state.getBlock())) {
|
if (search.contains(state.getBlock())) {
|
||||||
int yy = yReal | y;
|
int yy = yReal | y;
|
||||||
res.add(new BlockPos((pos.x << 4) | x, yy, (pos.z << 4) | z));
|
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
|
||||||
if (res.size() >= max || Math.abs(yy - playerY) < yLevelThreshold) {
|
if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) {
|
||||||
return res;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
listeners.forEach(l -> l.onPlayerUpdate(event));
|
listeners.forEach(l -> l.onPlayerUpdate(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onProcessKeyBinds() {
|
|
||||||
listeners.forEach(IGameEventListener::onProcessKeyBinds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendChatMessage(ChatEvent event) {
|
public final void onSendChatMessage(ChatEvent event) {
|
||||||
listeners.forEach(l -> l.onSendChatMessage(event));
|
listeners.forEach(l -> l.onSendChatMessage(event));
|
||||||
|
|||||||
@@ -25,11 +25,15 @@ 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.Favoring;
|
import baritone.utils.pathing.Favoring;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +59,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||||
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
||||||
openSet.insert(startNode);
|
openSet.insert(startNode);
|
||||||
startNode.isOpen = true;
|
|
||||||
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
||||||
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
|
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
|
||||||
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
|
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
|
||||||
@@ -64,8 +67,8 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
Favoring favored = favoring;
|
Favoring favored = favoring;
|
||||||
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
|
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder());
|
||||||
long startTime = System.nanoTime() / 1000000L;
|
long startTime = System.currentTimeMillis();
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + primaryTimeout + "ms");
|
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + primaryTimeout + "ms");
|
||||||
@@ -77,12 +80,39 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
int numMovementsConsidered = 0;
|
int numMovementsConsidered = 0;
|
||||||
int numEmptyChunk = 0;
|
int numEmptyChunk = 0;
|
||||||
boolean favoring = !favored.isEmpty();
|
boolean favoring = !favored.isEmpty();
|
||||||
|
int timeCheckInterval = 1 << 6;
|
||||||
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
||||||
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
||||||
|
|
||||||
|
long[] timeConsumed = new long[Moves.values().length];
|
||||||
|
int[] count = new int[Moves.values().length];
|
||||||
|
int[] stateLookup = new int[Moves.values().length];
|
||||||
|
long[] posCreation = new long[Moves.values().length];
|
||||||
|
long heapRemove = 0;
|
||||||
|
int heapRemoveCount = 0;
|
||||||
|
long heapAdd = 0;
|
||||||
|
int heapAddCount = 0;
|
||||||
|
long heapUpdate = 0;
|
||||||
|
int heapUpdateCount = 0;
|
||||||
|
|
||||||
|
long chunk = 0;
|
||||||
|
int chunkCount = 0;
|
||||||
|
|
||||||
|
long goalCheck = 0;
|
||||||
|
int goalCheckCount = 0;
|
||||||
|
|
||||||
|
long getNode = 0;
|
||||||
|
int getNodeCount = 0;
|
||||||
|
int startVal = BlockStateInterface.numTimesChunkSucceeded;
|
||||||
|
int startVal2 = BlockStateInterface.numBlockStateLookups;
|
||||||
|
long startVal3 = BetterBlockPos.numCreated;
|
||||||
|
|
||||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
||||||
long now = System.nanoTime() / 1000000L;
|
if ((numNodes & (timeCheckInterval - 1)) == 0) { // only call this once every 64 nodes (about half a millisecond)
|
||||||
if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) {
|
long now = System.currentTimeMillis(); // since nanoTime is slow on windows (takes many microseconds)
|
||||||
break;
|
if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
try {
|
try {
|
||||||
@@ -90,15 +120,21 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
long before = System.nanoTime();
|
||||||
PathNode currentNode = openSet.removeLowest();
|
PathNode currentNode = openSet.removeLowest();
|
||||||
currentNode.isOpen = false;
|
long t = System.nanoTime();
|
||||||
|
heapRemove += t - before;
|
||||||
|
heapRemoveCount++;
|
||||||
mostRecentConsidered = currentNode;
|
mostRecentConsidered = currentNode;
|
||||||
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.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
|
goalCheck += System.nanoTime() - t;
|
||||||
|
goalCheckCount++;
|
||||||
for (Moves moves : Moves.values()) {
|
for (Moves moves : Moves.values()) {
|
||||||
|
long s = System.nanoTime();
|
||||||
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) && !calcContext.isLoaded(newX, newZ)) {
|
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !calcContext.isLoaded(newX, newZ)) {
|
||||||
@@ -106,6 +142,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
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++;
|
||||||
}
|
}
|
||||||
|
long costStart = System.nanoTime();
|
||||||
|
chunk += costStart - s;
|
||||||
|
chunkCount++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
|
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
|
||||||
@@ -114,8 +153,19 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) {
|
if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
long costStart = System.nanoTime();
|
||||||
|
chunk += costStart - s;
|
||||||
|
chunkCount++;
|
||||||
|
// TODO cache cost
|
||||||
|
int numLookupsBefore = BlockStateInterface.numBlockStateLookups;
|
||||||
|
long numCreatedBefore = BetterBlockPos.numCreated;
|
||||||
res.reset();
|
res.reset();
|
||||||
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
|
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
|
||||||
|
long costEnd = System.nanoTime();
|
||||||
|
stateLookup[moves.ordinal()] += BlockStateInterface.numBlockStateLookups - numLookupsBefore;
|
||||||
|
posCreation[moves.ordinal()] += BetterBlockPos.numCreated - numCreatedBefore;
|
||||||
|
timeConsumed[moves.ordinal()] += costEnd - costStart;
|
||||||
|
count[moves.ordinal()]++;
|
||||||
numMovementsConsidered++;
|
numMovementsConsidered++;
|
||||||
double actionCost = res.cost;
|
double actionCost = res.cost;
|
||||||
if (actionCost >= ActionCosts.COST_INF) {
|
if (actionCost >= ActionCosts.COST_INF) {
|
||||||
@@ -124,10 +174,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
if (actionCost <= 0 || Double.isNaN(actionCost)) {
|
if (actionCost <= 0 || Double.isNaN(actionCost)) {
|
||||||
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
||||||
}
|
}
|
||||||
|
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
|
||||||
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
|
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
|
|
||||||
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
|
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
|
||||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||||
}
|
}
|
||||||
@@ -139,7 +189,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
// see issue #18
|
// see issue #18
|
||||||
actionCost *= favored.calculate(hashCode);
|
actionCost *= favored.calculate(hashCode);
|
||||||
}
|
}
|
||||||
|
long st = System.nanoTime();
|
||||||
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
||||||
|
getNode += System.nanoTime() - st;
|
||||||
|
getNodeCount++;
|
||||||
double tentativeCost = currentNode.cost + actionCost;
|
double tentativeCost = currentNode.cost + actionCost;
|
||||||
if (tentativeCost < neighbor.cost) {
|
if (tentativeCost < neighbor.cost) {
|
||||||
double improvementBy = neighbor.cost - tentativeCost;
|
double improvementBy = neighbor.cost - tentativeCost;
|
||||||
@@ -153,11 +206,16 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
neighbor.previous = currentNode;
|
neighbor.previous = currentNode;
|
||||||
neighbor.cost = tentativeCost;
|
neighbor.cost = tentativeCost;
|
||||||
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
||||||
if (neighbor.isOpen) {
|
if (neighbor.isOpen()) {
|
||||||
|
long bef = System.nanoTime();
|
||||||
openSet.update(neighbor);
|
openSet.update(neighbor);
|
||||||
|
heapUpdate += System.nanoTime() - bef;
|
||||||
|
heapUpdateCount++;
|
||||||
} else {
|
} else {
|
||||||
neighbor.isOpen = true;
|
long bef = System.nanoTime();
|
||||||
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
||||||
|
heapAdd += System.nanoTime() - bef;
|
||||||
|
heapAddCount++;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < bestSoFar.length; i++) {
|
||||||
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
||||||
@@ -175,13 +233,43 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int numBlockState = BlockStateInterface.numBlockStateLookups - startVal2;
|
||||||
|
int numSucc = BlockStateInterface.numTimesChunkSucceeded - startVal;
|
||||||
|
long numSuccc = BetterBlockPos.numCreated - startVal3;
|
||||||
|
|
||||||
|
long totalAccountedTimeMS = 0;
|
||||||
|
totalAccountedTimeMS += heapRemove / 1000000;
|
||||||
|
totalAccountedTimeMS += heapAdd / 1000000;
|
||||||
|
totalAccountedTimeMS += heapUpdate / 1000000;
|
||||||
|
totalAccountedTimeMS += chunk / 1000000;
|
||||||
|
totalAccountedTimeMS += getNode / 1000000;
|
||||||
|
totalAccountedTimeMS += goalCheck / 1000000;
|
||||||
|
System.out.println("Out of " + numBlockState + " block state lookups, " + numSucc + " were in the same chunk as the previous and could be cached");
|
||||||
|
System.out.println("Instantiated " + numSuccc + " BetterBlockPos objects");
|
||||||
|
System.out.println("Remove " + (heapRemove / heapRemoveCount) + " " + heapRemove / 1000000 + "ms " + heapRemoveCount);
|
||||||
|
System.out.println("Add " + (heapAdd / heapAddCount) + " " + heapAdd / 1000000 + "ms " + heapAddCount);
|
||||||
|
System.out.println("Update " + (heapUpdate / heapUpdateCount) + " " + heapUpdate / 1000000 + "ms " + heapUpdateCount);
|
||||||
|
System.out.println("Chunk " + (chunk / chunkCount) + " " + chunk / 1000000 + "ms " + chunkCount);
|
||||||
|
System.out.println("GetNode " + (getNode / getNodeCount) + " " + getNode / 1000000 + "ms " + getNodeCount);
|
||||||
|
System.out.println("GoalCheck " + (goalCheck / goalCheckCount) + " " + goalCheck / 1000000 + "ms " + goalCheckCount);
|
||||||
|
ArrayList<Moves> moves = new ArrayList<>(Arrays.asList(Moves.values()));
|
||||||
|
moves.sort(Comparator.comparingLong(k -> timeConsumed[k.ordinal()] / count[k.ordinal()]));
|
||||||
|
for (Moves move : moves) {
|
||||||
|
int num = count[move.ordinal()];
|
||||||
|
long nanoTime = timeConsumed[move.ordinal()];
|
||||||
|
totalAccountedTimeMS += nanoTime / 1000000;
|
||||||
|
System.out.println(nanoTime / num + " " + move + " " + nanoTime / 1000000 + "ms " + num);
|
||||||
|
System.out.println(stateLookup[move.ordinal()] / num + " " + stateLookup[move.ordinal()]);
|
||||||
|
System.out.println(posCreation[move.ordinal()] / num + " " + posCreation[move.ordinal()]);
|
||||||
|
}
|
||||||
|
System.out.println("Total accounted time: " + totalAccountedTimeMS);
|
||||||
if (cancelRequested) {
|
if (cancelRequested) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
System.out.println(numMovementsConsidered + " movements considered");
|
System.out.println(numMovementsConsidered + " movements considered");
|
||||||
System.out.println("Open set size: " + openSet.size());
|
System.out.println("Open set size: " + openSet.size());
|
||||||
System.out.println("PathNode map size: " + mapSize());
|
System.out.println("PathNode map size: " + mapSize());
|
||||||
System.out.println((int) (numNodes * 1.0 / ((System.nanoTime() / 1000000L - startTime) / 1000F)) + " nodes per second");
|
System.out.println((int) (numNodes * 1.0 / ((System.currentTimeMillis() - startTime) / 1000F)) + " nodes per second");
|
||||||
double bestDist = 0;
|
double bestDist = 0;
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < bestSoFar.length; i++) {
|
||||||
if (bestSoFar[i] == null) {
|
if (bestSoFar[i] == null) {
|
||||||
@@ -192,7 +280,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
bestDist = dist;
|
bestDist = dist;
|
||||||
}
|
}
|
||||||
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered");
|
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered");
|
||||||
if (COEFFICIENTS[i] >= 3) {
|
if (COEFFICIENTS[i] >= 3) {
|
||||||
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
||||||
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
||||||
|
|||||||
@@ -136,11 +136,10 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
* for the node mapped to the specified pos. If no node is found,
|
* for the node mapped to the specified pos. If no node is found,
|
||||||
* a new node is created.
|
* a new node is created.
|
||||||
*
|
*
|
||||||
* @param x The x position of the node
|
* @param x The x position of the node
|
||||||
* @param y The y position of the node
|
* @param y The y position of the node
|
||||||
* @param z The z position of the node
|
* @param z The z position of the node
|
||||||
* @param hashCode The hash code of the node, provided by {@link BetterBlockPos#longHash(int, int, int)}
|
* @param hashCode The hash code of the node, provided by {@link BetterBlockPos#longHash(int, int, int)}
|
||||||
*
|
|
||||||
* @return The associated node
|
* @return The associated node
|
||||||
* @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>
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ class Path extends PathBase {
|
|||||||
Movement move = moves.apply0(context, src);
|
Movement move = moves.apply0(context, src);
|
||||||
if (move.getDest().equals(dest)) {
|
if (move.getDest().equals(dest)) {
|
||||||
// have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
|
// 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);
|
// however, taking into account possible favoring that could skew the node cost, we really want the stricter limit of the two
|
||||||
|
// so we take the minimum of the path node cost difference, and the calculated cost
|
||||||
|
move.override(Math.min(move.calculateCost(context), cost));
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,12 +58,6 @@ public final class PathNode {
|
|||||||
*/
|
*/
|
||||||
public PathNode previous;
|
public PathNode previous;
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this a member of the open set in A*? (only used during pathfinding)
|
|
||||||
* Instead of doing a costly member check in the open set, cache membership in each node individually too.
|
|
||||||
*/
|
|
||||||
public boolean isOpen;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where is this node in the array flattenization of the binary heap? Needed for decrease-key operations.
|
* Where is this node in the array flattenization of the binary heap? Needed for decrease-key operations.
|
||||||
*/
|
*/
|
||||||
@@ -76,12 +70,16 @@ public final class PathNode {
|
|||||||
if (Double.isNaN(estimatedCostToGoal)) {
|
if (Double.isNaN(estimatedCostToGoal)) {
|
||||||
throw new IllegalStateException(goal + " calculated implausible heuristic");
|
throw new IllegalStateException(goal + " calculated implausible heuristic");
|
||||||
}
|
}
|
||||||
this.isOpen = false;
|
this.heapPosition = -1;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOpen() {
|
||||||
|
return heapPosition != -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Possibly reimplement hashCode and equals. They are necessary for this class to function but they could be done better
|
* TODO: Possibly reimplement hashCode and equals. They are necessary for this class to function but they could be done better
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public final class BinaryHeapOpenSet implements IOpenSet {
|
|||||||
@Override
|
@Override
|
||||||
public final void insert(PathNode value) {
|
public final void insert(PathNode value) {
|
||||||
if (size >= array.length - 1) {
|
if (size >= array.length - 1) {
|
||||||
array = Arrays.copyOf(array, array.length * 2);
|
array = Arrays.copyOf(array, array.length << 1);
|
||||||
}
|
}
|
||||||
size++;
|
size++;
|
||||||
value.heapPosition = size;
|
value.heapPosition = size;
|
||||||
|
|||||||
@@ -42,26 +42,28 @@ public class CalculationContext {
|
|||||||
|
|
||||||
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
||||||
|
|
||||||
private final IBaritone baritone;
|
public final IBaritone baritone;
|
||||||
private final EntityPlayerSP player;
|
public final World world;
|
||||||
private final World world;
|
public final WorldData worldData;
|
||||||
private final WorldData worldData;
|
public final BlockStateInterface bsi;
|
||||||
private final BlockStateInterface bsi;
|
public final ToolSet toolSet;
|
||||||
private final ToolSet toolSet;
|
public final boolean hasWaterBucket;
|
||||||
private final boolean hasWaterBucket;
|
public final boolean hasThrowaway;
|
||||||
private final boolean hasThrowaway;
|
public final boolean canSprint;
|
||||||
private final boolean canSprint;
|
public final double placeBlockCost;
|
||||||
private final double placeBlockCost;
|
public final boolean allowBreak;
|
||||||
private final boolean allowBreak;
|
public final boolean allowParkour;
|
||||||
private final boolean allowParkour;
|
public final boolean allowParkourPlace;
|
||||||
private final boolean allowParkourPlace;
|
public final boolean allowJumpAt256;
|
||||||
private final boolean allowJumpAt256;
|
public final boolean assumeWalkOnWater;
|
||||||
private final boolean assumeWalkOnWater;
|
public final boolean allowDiagonalDescend;
|
||||||
private final int maxFallHeightNoWater;
|
public final int maxFallHeightNoWater;
|
||||||
private final int maxFallHeightBucket;
|
public final int maxFallHeightBucket;
|
||||||
private final double waterWalkSpeed;
|
public final double waterWalkSpeed;
|
||||||
private final double breakBlockAdditionalCost;
|
public final double breakBlockAdditionalCost;
|
||||||
private final BetterWorldBorder worldBorder;
|
public final double jumpPenalty;
|
||||||
|
public final double walkOnWaterOnePenalty;
|
||||||
|
public final BetterWorldBorder worldBorder;
|
||||||
|
|
||||||
public CalculationContext(IBaritone baritone) {
|
public CalculationContext(IBaritone baritone) {
|
||||||
this(baritone, false);
|
this(baritone, false);
|
||||||
@@ -69,11 +71,10 @@ public class CalculationContext {
|
|||||||
|
|
||||||
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
|
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
this.player = baritone.getPlayerContext().player();
|
EntityPlayerSP player = baritone.getPlayerContext().player();
|
||||||
this.world = baritone.getPlayerContext().world();
|
this.world = baritone.getPlayerContext().world();
|
||||||
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
||||||
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); // TODO TODO TODO
|
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); // TODO TODO TODO
|
||||||
// new CalculationContext() needs to happen, can't add an argument (i'll beat you), can we get the world provider from currentlyTicking?
|
|
||||||
this.toolSet = new ToolSet(player);
|
this.toolSet = new ToolSet(player);
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(baritone.getPlayerContext(), false);
|
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(baritone.getPlayerContext(), false);
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||||
@@ -84,6 +85,7 @@ public class CalculationContext {
|
|||||||
this.allowParkourPlace = Baritone.settings().allowParkourPlace.get();
|
this.allowParkourPlace = Baritone.settings().allowParkourPlace.get();
|
||||||
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.get();
|
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.get();
|
||||||
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.get();
|
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.get();
|
||||||
|
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.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);
|
||||||
@@ -93,6 +95,8 @@ public class CalculationContext {
|
|||||||
float mult = depth / 3.0F;
|
float mult = depth / 3.0F;
|
||||||
this.waterWalkSpeed = ActionCosts.WALK_ONE_IN_WATER_COST * (1 - mult) + ActionCosts.WALK_ONE_BLOCK_COST * mult;
|
this.waterWalkSpeed = ActionCosts.WALK_ONE_IN_WATER_COST * (1 - mult) + ActionCosts.WALK_ONE_BLOCK_COST * mult;
|
||||||
this.breakBlockAdditionalCost = Baritone.settings().blockBreakAdditionalPenalty.get();
|
this.breakBlockAdditionalCost = Baritone.settings().blockBreakAdditionalPenalty.get();
|
||||||
|
this.jumpPenalty = Baritone.settings().jumpPenalty.get();
|
||||||
|
this.walkOnWaterOnePenalty = Baritone.settings().walkOnWaterOnePenalty.get();
|
||||||
// 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.
|
||||||
@@ -120,7 +124,7 @@ public class CalculationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
||||||
if (!hasThrowaway()) { // only true if allowPlace is true, see constructor
|
if (!hasThrowaway) { // only true if allowPlace is true, see constructor
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPossiblyProtected(x, y, z)) {
|
if (isPossiblyProtected(x, y, z)) {
|
||||||
@@ -130,7 +134,7 @@ public class CalculationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBreakAt(int x, int y, int z) {
|
public boolean canBreakAt(int x, int y, int z) {
|
||||||
if (!allowBreak()) {
|
if (!allowBreak) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !isPossiblyProtected(x, y, z);
|
return !isPossiblyProtected(x, y, z);
|
||||||
@@ -140,76 +144,4 @@ public class CalculationContext {
|
|||||||
// TODO more protection logic here; see #220
|
// TODO more protection logic here; see #220
|
||||||
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() {
|
|
||||||
return toolSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasWaterBucket() {
|
|
||||||
return hasWaterBucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasThrowaway() {
|
|
||||||
return hasThrowaway;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canSprint() {
|
|
||||||
return canSprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double placeBlockCost() {
|
|
||||||
return placeBlockCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean allowBreak() {
|
|
||||||
return allowBreak;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean allowParkour() {
|
|
||||||
return allowParkour;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean allowParkourPlace() {
|
|
||||||
return allowParkourPlace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean allowJumpAt256() {
|
|
||||||
return allowJumpAt256;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean assumeWalkOnWater() {
|
|
||||||
return assumeWalkOnWater;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int maxFallHeightNoWater() {
|
|
||||||
return maxFallHeightNoWater;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int maxFallHeightBucket() {
|
|
||||||
return maxFallHeightBucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double waterWalkSpeed() {
|
|
||||||
return waterWalkSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double breakBlockAdditionalCost() {
|
|
||||||
return breakBlockAdditionalCost;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import baritone.utils.BlockStateInterface;
|
|||||||
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.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -35,7 +34,6 @@ import java.util.Optional;
|
|||||||
|
|
||||||
public abstract class Movement implements IMovement, MovementHelper {
|
public abstract class Movement implements IMovement, MovementHelper {
|
||||||
|
|
||||||
protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST};
|
|
||||||
protected static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
protected static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
||||||
|
|
||||||
protected final IBaritone baritone;
|
protected final IBaritone baritone;
|
||||||
@@ -86,7 +84,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract double calculateCost(CalculationContext context);
|
public abstract double calculateCost(CalculationContext context);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double recalculateCost() {
|
public double recalculateCost() {
|
||||||
@@ -126,13 +124,10 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
rotation,
|
rotation,
|
||||||
currentState.getTarget().hasToForceRotations()));
|
currentState.getTarget().hasToForceRotations()));
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
currentState.getInputStates().forEach((input, forced) -> {
|
currentState.getInputStates().forEach((input, forced) -> {
|
||||||
baritone.getInputOverrideHandler().setInputForceState(input, forced);
|
baritone.getInputOverrideHandler().setInputForceState(input, forced);
|
||||||
});
|
});
|
||||||
currentState.getInputStates().replaceAll((input, forced) -> false);
|
currentState.getInputStates().clear();
|
||||||
|
|
||||||
// If the current status indicates a completed movement
|
// If the current status indicates a completed movement
|
||||||
if (currentState.getStatus().isComplete()) {
|
if (currentState.getStatus().isComplete()) {
|
||||||
@@ -231,7 +226,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkLoadedChunk(CalculationContext context) {
|
public void checkLoadedChunk(CalculationContext context) {
|
||||||
calculatedWhileLoaded = !(context.world().getChunk(getDest()) instanceof EmptyChunk);
|
calculatedWhileLoaded = context.bsi.worldContainsLoadedChunk(dest.x, dest.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -340,24 +340,24 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|
|
||||||
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(context.bsi(), x, y, z, state)) {
|
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
||||||
if (!context.canBreakAt(x, y, z)) {
|
if (!context.canBreakAt(x, y, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (avoidBreaking(context.bsi(), x, y, z, state)) {
|
if (avoidBreaking(context.bsi, x, y, z, state)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockLiquid) {
|
if (block instanceof BlockLiquid) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
||||||
double strVsBlock = context.getToolSet().getStrVsBlock(state);
|
double strVsBlock = context.toolSet.getStrVsBlock(state);
|
||||||
if (strVsBlock <= 0) {
|
if (strVsBlock <= 0) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
|
||||||
double result = m / strVsBlock;
|
double result = m / strVsBlock;
|
||||||
result += context.breakBlockAdditionalCost();
|
result += context.breakBlockAdditionalCost;
|
||||||
if (includeFalling) {
|
if (includeFalling) {
|
||||||
IBlockState above = context.get(x, y + 1, z);
|
IBlockState above = context.get(x, y + 1, z);
|
||||||
if (above.getBlock() instanceof BlockFalling) {
|
if (above.getBlock() instanceof BlockFalling) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package baritone.pathing.movement;
|
|||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.Rotation;
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -29,7 +28,6 @@ import java.util.Optional;
|
|||||||
public class MovementState {
|
public class MovementState {
|
||||||
|
|
||||||
private MovementStatus status;
|
private MovementStatus status;
|
||||||
private MovementTarget goal = new MovementTarget();
|
|
||||||
private MovementTarget target = new MovementTarget();
|
private MovementTarget target = new MovementTarget();
|
||||||
private final Map<Input, Boolean> inputState = new HashMap<>();
|
private final Map<Input, Boolean> inputState = new HashMap<>();
|
||||||
|
|
||||||
@@ -42,15 +40,6 @@ public class MovementState {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MovementTarget getGoal() {
|
|
||||||
return this.goal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MovementState setGoal(MovementTarget goal) {
|
|
||||||
this.goal = goal;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MovementTarget getTarget() {
|
public MovementTarget getTarget() {
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
}
|
||||||
@@ -65,23 +54,12 @@ public class MovementState {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getInput(Input input) {
|
|
||||||
return this.inputState.getOrDefault(input, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Input, Boolean> getInputStates() {
|
public Map<Input, Boolean> getInputStates() {
|
||||||
return this.inputState;
|
return this.inputState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MovementTarget {
|
public static class MovementTarget {
|
||||||
|
|
||||||
/**
|
|
||||||
* Necessary movement to achieve
|
|
||||||
* <p>
|
|
||||||
* TODO: Decide desiredMovement type
|
|
||||||
*/
|
|
||||||
public Vec3d position;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yaw and pitch angles that must be matched
|
* Yaw and pitch angles that must be matched
|
||||||
*/
|
*/
|
||||||
@@ -95,27 +73,14 @@ public class MovementState {
|
|||||||
private boolean forceRotations;
|
private boolean forceRotations;
|
||||||
|
|
||||||
public MovementTarget() {
|
public MovementTarget() {
|
||||||
this(null, null, false);
|
this(null, false);
|
||||||
}
|
|
||||||
|
|
||||||
public MovementTarget(Vec3d position) {
|
|
||||||
this(position, null, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MovementTarget(Rotation rotation, boolean forceRotations) {
|
public MovementTarget(Rotation rotation, boolean forceRotations) {
|
||||||
this(null, rotation, forceRotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MovementTarget(Vec3d position, Rotation rotation, boolean forceRotations) {
|
|
||||||
this.position = position;
|
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
this.forceRotations = forceRotations;
|
this.forceRotations = forceRotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Optional<Vec3d> getPosition() {
|
|
||||||
return Optional.ofNullable(this.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Optional<Rotation> getRotation() {
|
public final Optional<Rotation> getRotation() {
|
||||||
return Optional.ofNullable(this.rotation);
|
return Optional.ofNullable(this.rotation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,18 +52,18 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 toPlace = context.get(destX, y, destZ);
|
IBlockState toPlace = context.get(destX, y, destZ);
|
||||||
boolean hasToPlace = false;
|
boolean hasToPlace = false;
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, y, destZ, toPlace)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) {
|
||||||
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi())) {
|
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
@@ -73,7 +73,7 @@ public class MovementAscend extends Movement {
|
|||||||
if (againstX == x && againstZ == z) { // we might be able to backplace now, but it doesn't matter because it will have been broken by the time we'd need to use it
|
if (againstX == x && againstZ == z) { // we might be able to backplace now, but it doesn't matter because it will have been broken by the time we'd need to use it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(context.bsi(), againstX, againstY, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
|
||||||
hasToPlace = true;
|
hasToPlace = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IBlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
|
IBlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
|
||||||
if (context.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(context.bsi(), x, y + 1, z) || !(srcUp2.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.bsi, x, y + 1, z) || !(srcUp2.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
|
||||||
@@ -115,23 +115,23 @@ public class MovementAscend extends Movement {
|
|||||||
if (jumpingToBottomSlab) {
|
if (jumpingToBottomSlab) {
|
||||||
if (jumpingFromBottomSlab) {
|
if (jumpingFromBottomSlab) {
|
||||||
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST); // we hit space immediately on entering this action
|
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST); // we hit space immediately on entering this action
|
||||||
|
walk += context.jumpPenalty;
|
||||||
} else {
|
} else {
|
||||||
walk = WALK_ONE_BLOCK_COST; // we don't hit space we just walk into the slab
|
walk = WALK_ONE_BLOCK_COST; // we don't hit space we just walk into the slab
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// jumpingFromBottomSlab must be false
|
||||||
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
|
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
|
||||||
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
||||||
} else {
|
} else {
|
||||||
walk = WALK_ONE_BLOCK_COST;
|
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST);
|
||||||
}
|
}
|
||||||
|
walk += context.jumpPenalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cracks knuckles
|
double totalCost = walk;
|
||||||
|
|
||||||
double totalCost = 0;
|
|
||||||
totalCost += walk;
|
|
||||||
if (hasToPlace) {
|
if (hasToPlace) {
|
||||||
totalCost += context.placeBlockCost();
|
totalCost += context.placeBlockCost;
|
||||||
}
|
}
|
||||||
// start with srcUp2 since we already have its state
|
// start with srcUp2 since we already have its state
|
||||||
// includeFalling isn't needed because of the falling check above -- if srcUp3 is falling we will have already exited with COST_INF if we'd actually have to break it
|
// includeFalling isn't needed because of the falling check above -- if srcUp3 is falling we will have already exited with COST_INF if we'd actually have to break it
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
MutableMoveResult result = new MutableMoveResult();
|
MutableMoveResult result = new MutableMoveResult();
|
||||||
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
||||||
if (result.y != dest.y) {
|
if (result.y != dest.y) {
|
||||||
@@ -93,7 +93,7 @@ public class MovementDescend extends Movement {
|
|||||||
//C, D, etc determine the length of the fall
|
//C, D, etc determine the length of the fall
|
||||||
|
|
||||||
IBlockState below = context.get(destX, y - 2, destZ);
|
IBlockState below = context.get(destX, y - 2, destZ);
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, y - 2, destZ, below)) {
|
if (!MovementHelper.canWalkOn(context.bsi, 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;
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ public class MovementDescend extends Movement {
|
|||||||
// and potentially replace the water we're going to fall into
|
// and potentially replace the water we're going to fall into
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkThrough(context.bsi(), destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
if (!MovementHelper.canWalkThrough(context.bsi, destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
double costSoFar = 0;
|
double costSoFar = 0;
|
||||||
@@ -140,13 +140,13 @@ public class MovementDescend extends Movement {
|
|||||||
if (ontoBlock.getBlock() == Blocks.WATER && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
|
if (ontoBlock.getBlock() == Blocks.WATER && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
|
||||||
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
|
// 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 (context.assumeWalkOnWater()) {
|
if (context.assumeWalkOnWater) {
|
||||||
return false; // TODO fix
|
return false; // TODO fix
|
||||||
}
|
}
|
||||||
if (MovementHelper.isFlowing(ontoBlock)) {
|
if (MovementHelper.isFlowing(ontoBlock)) {
|
||||||
return false; // TODO flowing check required here?
|
return false; // TODO flowing check required here?
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, newY - 1, destZ)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) {
|
||||||
// we could punch right through the water into something else
|
// we could punch right through the water into something else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -168,23 +168,23 @@ public class MovementDescend extends Movement {
|
|||||||
effectiveStartHeight = newY;
|
effectiveStartHeight = newY;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkThrough(context.bsi(), destX, newY, destZ, ontoBlock)) {
|
if (MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, newY, destZ, ontoBlock)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, newY, destZ, ontoBlock)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||||
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||||
}
|
}
|
||||||
if (context.hasWaterBucket() && unprotectedFallHeight <= context.maxFallHeightBucket() + 1) {
|
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
||||||
res.z = destZ;
|
res.z = destZ;
|
||||||
res.cost = tentativeCost + context.placeBlockCost();
|
res.cost = tentativeCost + context.placeBlockCost;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (unprotectedFallHeight <= context.maxFallHeightNoWater() + 1) {
|
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
|
||||||
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = newY + 1;
|
res.y = newY + 1;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
MutableMoveResult result = new MutableMoveResult();
|
MutableMoveResult result = new MutableMoveResult();
|
||||||
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
||||||
if (result.y != dest.y) {
|
if (result.y != dest.y) {
|
||||||
@@ -65,14 +65,14 @@ public class MovementDiagonal 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) {
|
||||||
IBlockState destInto = context.get(destX, y, destZ);
|
IBlockState destInto = context.get(destX, y, destZ);
|
||||||
if (!MovementHelper.canWalkThrough(context.bsi(), destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi(), destX, y + 1, destZ)) {
|
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
|
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
|
||||||
boolean descend = false;
|
boolean descend = false;
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, y - 1, destZ, destWalkOn)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) {
|
||||||
descend = true;
|
descend = true;
|
||||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi(), destX, y - 1, destZ, destWalkOn)) {
|
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi, destX, y - 1, destZ, destWalkOn)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,6 +80,8 @@ public class MovementDiagonal extends Movement {
|
|||||||
// For either possible soul sand, that affects half of our walking
|
// For either possible soul sand, that affects half of our walking
|
||||||
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
|
if (destWalkOn.getBlock() == 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;
|
||||||
|
} else if (destWalkOn.getBlock() == Blocks.WATER) {
|
||||||
|
multiplier += context.walkOnWaterOnePenalty * SQRT_2;
|
||||||
}
|
}
|
||||||
Block fromDown = context.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) {
|
||||||
@@ -131,7 +133,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
// 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
|
||||||
multiplier = context.waterWalkSpeed();
|
multiplier = context.waterWalkSpeed;
|
||||||
water = true;
|
water = true;
|
||||||
}
|
}
|
||||||
if (optionA != 0 || optionB != 0) {
|
if (optionA != 0 || optionB != 0) {
|
||||||
@@ -142,7 +144,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// only can sprint if not edging around
|
// only can sprint if not edging around
|
||||||
if (context.canSprint() && !water) {
|
if (context.canSprint && !water) {
|
||||||
// If we aren't edging around anything, and we aren't in water
|
// If we aren't edging around anything, and we aren't in water
|
||||||
// We can sprint =D
|
// We can sprint =D
|
||||||
// Don't check for soul sand, since we can sprint on that too
|
// Don't check for soul sand, since we can sprint on that too
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ public class MovementDownward extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
return cost(context, src.x, src.y, src.z);
|
return cost(context, src.x, src.y, src.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
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(context.bsi(), x, y - 2, z)) {
|
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState down = context.get(x, y - 1, z);
|
IBlockState down = context.get(x, y - 1, z);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class MovementFall extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
MutableMoveResult result = new MutableMoveResult();
|
MutableMoveResult result = new MutableMoveResult();
|
||||||
MovementDescend.cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
MovementDescend.cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
|
||||||
if (result.y != dest.y) {
|
if (result.y != dest.y) {
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ public class MovementParkour extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) {
|
public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) {
|
||||||
if (!context.allowParkour()) {
|
if (!context.allowParkour) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (y == 256 && !context.allowJumpAt256()) {
|
if (y == 256 && !context.allowJumpAt256) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
|
IBlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
|
||||||
if (MovementHelper.canWalkOn(context.bsi(), x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
if (MovementHelper.canWalkOn(context.bsi, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
||||||
// second most common case -- we could just traverse not parkour
|
// second most common case -- we could just traverse not parkour
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ public class MovementParkour extends Movement {
|
|||||||
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
|
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
|
||||||
maxJump = 2; // 1 block gap
|
maxJump = 2; // 1 block gap
|
||||||
} else {
|
} else {
|
||||||
if (context.canSprint()) {
|
if (context.canSprint) {
|
||||||
maxJump = 4;
|
maxJump = 4;
|
||||||
} else {
|
} else {
|
||||||
maxJump = 3;
|
maxJump = 3;
|
||||||
@@ -111,18 +111,18 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(context.bsi(), x + xDiff * i, y - 1, z + zDiff * i)) {
|
if (MovementHelper.canWalkOn(context.bsi, 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;
|
||||||
res.cost = costFromJumpDistance(i);
|
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (maxJump != 4) {
|
if (maxJump != 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!context.allowParkourPlace()) {
|
if (!context.allowParkourPlace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int destX = x + 4 * xDiff;
|
int destX = x + 4 * xDiff;
|
||||||
@@ -131,7 +131,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState toReplace = context.get(destX, y - 1, destZ);
|
IBlockState toReplace = context.get(destX, y - 1, destZ);
|
||||||
if (!MovementHelper.isReplacable(destX, y - 1, destZ, toReplace, context.bsi())) {
|
if (!MovementHelper.isReplacable(destX, y - 1, destZ, toReplace, context.bsi)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
@@ -141,11 +141,11 @@ 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(context.bsi(), againstX, againstY, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = y;
|
res.y = y;
|
||||||
res.z = destZ;
|
res.z = destZ;
|
||||||
res.cost = costFromJumpDistance(4) + context.placeBlockCost();
|
res.cost = costFromJumpDistance(4) + context.placeBlockCost + context.jumpPenalty;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ public class MovementParkour extends Movement {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
cost(context, src.x, src.y, src.z, direction, res);
|
cost(context, src.x, src.y, src.z, direction, res);
|
||||||
if (res.x != dest.x || res.z != dest.z) {
|
if (res.x != dest.x || res.z != dest.z) {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
return cost(context, src.x, src.y, src.z);
|
return cost(context, src.x, src.y, src.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ 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 (from instanceof BlockVine && !hasAgainst(context, x, y, z)) { // TODO this vine can't be climbed, but we could place a pillar still since vines are replacable, no? perhaps the pillar jump would be impossible because of the slowdown actually.
|
if (from == Blocks.VINE && !hasAgainst(context, x, y, z)) { // TODO this vine can't be climbed, but we could place a pillar still since vines are replacable, no? perhaps the pillar jump would be impossible because of the slowdown actually.
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState toBreak = context.get(x, y + 2, z);
|
IBlockState toBreak = context.get(x, y + 2, z);
|
||||||
@@ -76,7 +76,7 @@ public class MovementPillar extends Movement {
|
|||||||
if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) { // we need to place a block where we started to jump on it
|
if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) { // we need to place a block where we started to jump on it
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater())) {
|
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater)) {
|
||||||
// otherwise, if we're standing in water, we cannot pillar
|
// otherwise, if we're standing in water, we cannot pillar
|
||||||
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
|
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
|
||||||
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
|
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
|
||||||
@@ -112,7 +112,7 @@ public class MovementPillar extends Movement {
|
|||||||
if (ladder) {
|
if (ladder) {
|
||||||
return LADDER_UP_ONE_COST + hardness * 5;
|
return LADDER_UP_ONE_COST + hardness * 5;
|
||||||
} else {
|
} else {
|
||||||
return JUMP_ONE_BLOCK_COST + context.placeBlockCost() + hardness;
|
return JUMP_ONE_BLOCK_COST + context.placeBlockCost + context.jumpPenalty + hardness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +159,8 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
|
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
|
||||||
boolean vine = fromDown.getBlock() instanceof BlockVine;
|
boolean vine = fromDown.getBlock() == Blocks.VINE;
|
||||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(positionToPlace),
|
VecUtils.getBlockPosCenter(positionToPlace),
|
||||||
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
|
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ import baritone.pathing.movement.Movement;
|
|||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockDoor;
|
||||||
|
import net.minecraft.block.BlockFenceGate;
|
||||||
|
import net.minecraft.block.BlockSlab;
|
||||||
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.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
@@ -57,7 +60,7 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
public double calculateCost(CalculationContext context) {
|
||||||
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,15 +69,17 @@ public class MovementTraverse extends Movement {
|
|||||||
IBlockState pb1 = context.get(destX, y, destZ);
|
IBlockState pb1 = context.get(destX, y, destZ);
|
||||||
IBlockState destOn = context.get(destX, y - 1, destZ);
|
IBlockState destOn = context.get(destX, y - 1, destZ);
|
||||||
Block srcDown = context.getBlock(x, y - 1, z);
|
Block srcDown = context.getBlock(x, y - 1, z);
|
||||||
if (MovementHelper.canWalkOn(context.bsi(), destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
if (MovementHelper.canWalkOn(context.bsi, 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 (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
||||||
WC = context.waterWalkSpeed();
|
WC = context.waterWalkSpeed;
|
||||||
water = true;
|
water = true;
|
||||||
} else {
|
} else {
|
||||||
if (destOn.getBlock() == Blocks.SOUL_SAND) {
|
if (destOn.getBlock() == Blocks.SOUL_SAND) {
|
||||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
|
} else if (destOn.getBlock() == Blocks.WATER) {
|
||||||
|
WC += context.walkOnWaterOnePenalty;
|
||||||
}
|
}
|
||||||
if (srcDown == Blocks.SOUL_SAND) {
|
if (srcDown == Blocks.SOUL_SAND) {
|
||||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
@@ -86,7 +91,7 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
|
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
|
||||||
if (hardness1 == 0 && hardness2 == 0) {
|
if (hardness1 == 0 && hardness2 == 0) {
|
||||||
if (!water && context.canSprint()) {
|
if (!water && context.canSprint) {
|
||||||
// If there's nothing in the way, and this isn't water, and we aren't sneak placing
|
// If there's nothing in the way, and this isn't water, and we aren't sneak placing
|
||||||
// We can sprint =D
|
// We can sprint =D
|
||||||
// Don't check for soul sand, since we can sprint on that too
|
// Don't check for soul sand, since we can sprint on that too
|
||||||
@@ -103,7 +108,7 @@ public class MovementTraverse extends Movement {
|
|||||||
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (MovementHelper.isReplacable(destX, y - 1, destZ, destOn, context.bsi())) {
|
if (MovementHelper.isReplacable(destX, y - 1, destZ, destOn, context.bsi)) {
|
||||||
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
||||||
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
||||||
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
||||||
@@ -117,7 +122,7 @@ public class MovementTraverse extends Movement {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
|
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
|
||||||
double WC = throughWater ? context.waterWalkSpeed() : WALK_ONE_BLOCK_COST;
|
double WC = throughWater ? context.waterWalkSpeed : WALK_ONE_BLOCK_COST;
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||||
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||||
@@ -125,8 +130,8 @@ public class MovementTraverse extends Movement {
|
|||||||
if (againstX == x && againstZ == z) { // this would be a backplace
|
if (againstX == x && againstZ == z) { // this would be a backplace
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(context.bsi(), againstX, againstY, againstZ)) { // found a side place option
|
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) { // found a side place option
|
||||||
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
return WC + context.placeBlockCost + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now that we've checked all possible directions to side place, we actually need to backplace
|
// now that we've checked all possible directions to side place, we actually need to backplace
|
||||||
@@ -136,8 +141,8 @@ public class MovementTraverse extends Movement {
|
|||||||
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
|
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
|
||||||
return COST_INF; // this is obviously impossible
|
return COST_INF; // this is obviously impossible
|
||||||
}
|
}
|
||||||
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are sneak backplacing, we are sneaking lol
|
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
|
||||||
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
return WC + context.placeBlockCost + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
@@ -181,7 +186,7 @@ public class MovementTraverse extends Movement {
|
|||||||
state.setInput(Input.SNEAK, false);
|
state.setInput(Input.SNEAK, false);
|
||||||
|
|
||||||
Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
|
Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
|
||||||
boolean ladder = fd instanceof BlockLadder || fd instanceof BlockVine;
|
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
|
||||||
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
||||||
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
||||||
|
|
||||||
@@ -234,7 +239,7 @@ public class MovementTraverse extends Movement {
|
|||||||
state.setInput(Input.SPRINT, true);
|
state.setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
|
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
|
||||||
if (whereAmI.getY() != dest.getY() && ladder && (destDown instanceof BlockVine || destDown instanceof BlockLadder)) {
|
if (whereAmI.getY() != dest.getY() && ladder && (destDown == Blocks.VINE || destDown == Blocks.LADDER)) {
|
||||||
new MovementPillar(baritone, dest.down(), dest).updateState(state); // i'm sorry
|
new MovementPillar(baritone, dest.down(), dest).updateState(state); // i'm sorry
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println("Should be at " + whereShouldIBe + " actually am at " + whereAmI);
|
|
||||||
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
||||||
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
|
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
|
||||||
if (whereAmI.equals(path.positions().get(i))) {
|
if (whereAmI.equals(path.positions().get(i))) {
|
||||||
@@ -374,14 +373,15 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
|
|
||||||
private void sprintIfRequested() {
|
private void sprintIfRequested() {
|
||||||
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
|
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
|
||||||
if (!new CalculationContext(behavior.baritone).canSprint()) {
|
if (!new CalculationContext(behavior.baritone).canSprint) {
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
||||||
ctx.player().setSprinting(false);
|
ctx.player().setSprinting(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the movement requested sprinting, then we're done
|
// if the movement requested sprinting, then we're done
|
||||||
if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(mc.gameSettings.keyBindSprint)) {
|
if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT)) {
|
||||||
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
||||||
if (!ctx.player().isSprinting()) {
|
if (!ctx.player().isSprinting()) {
|
||||||
ctx.player().setSprinting(true);
|
ctx.player().setSprinting(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Goal towards(Entity following) {
|
private Goal towards(Entity following) {
|
||||||
// lol this is trashy but it works
|
|
||||||
BlockPos pos;
|
BlockPos pos;
|
||||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
||||||
pos = new BlockPos(following);
|
pos = new BlockPos(following);
|
||||||
@@ -79,7 +78,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
if (entity.equals(ctx.player())) {
|
if (entity.equals(ctx.player())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ctx.world().loadedEntityList.contains(entity) || ctx.world().playerEntities.contains(entity);
|
return ctx.world().loadedEntityList.contains(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scanWorld() {
|
private void scanWorld() {
|
||||||
|
|||||||
@@ -154,4 +154,4 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
|||||||
}
|
}
|
||||||
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
|
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ 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.World;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -210,7 +209,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
//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(ctx.worldData().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
||||||
} else {
|
} else {
|
||||||
uninteresting.add(m);
|
uninteresting.add(m);
|
||||||
}
|
}
|
||||||
@@ -249,16 +248,17 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max) {
|
public static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max) {
|
||||||
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world());
|
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
|
||||||
List<BlockPos> locs = locs2
|
List<BlockPos> locs = locs2
|
||||||
.stream()
|
.stream()
|
||||||
.distinct()
|
.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 -> ctx.world().getChunk(pos) instanceof EmptyChunk || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
|
|
||||||
|
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
|
||||||
|
|
||||||
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
||||||
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi(), pos))
|
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi, pos))
|
||||||
|
|
||||||
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
|
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ import net.minecraft.world.GameType;
|
|||||||
import net.minecraft.world.WorldSettings;
|
import net.minecraft.world.WorldSettings;
|
||||||
import net.minecraft.world.WorldType;
|
import net.minecraft.world.WorldType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for automatically testing Baritone's pathing algorithm by automatically creating a world with a specific
|
||||||
|
* seed, setting a specified goal, and only allowing a certain amount of ticks to pass before the pathing test is
|
||||||
|
* considered a failure. In order to test locally, docker may be used, or through an IDE: Create a run config which runs
|
||||||
|
* in a separate directory from the primary one (./run), and set the enrivonmental variable {@code BARITONE_AUTO_TEST}
|
||||||
|
* to {@code true}.
|
||||||
|
*
|
||||||
|
* @author leijurv, Brady
|
||||||
|
*/
|
||||||
public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||||
|
|
||||||
public static final BaritoneAutoTest INSTANCE = new BaritoneAutoTest();
|
public static final BaritoneAutoTest INSTANCE = new BaritoneAutoTest();
|
||||||
|
|||||||
@@ -23,16 +23,10 @@ import baritone.api.utils.IPlayerContext;
|
|||||||
|
|
||||||
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
|
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
|
||||||
|
|
||||||
public static final double DEFAULT_PRIORITY = 0;
|
|
||||||
|
|
||||||
protected final Baritone baritone;
|
protected final Baritone baritone;
|
||||||
protected final IPlayerContext ctx;
|
protected final IPlayerContext ctx;
|
||||||
private final double priority;
|
private final double priority;
|
||||||
|
|
||||||
public BaritoneProcessHelper(Baritone baritone) {
|
|
||||||
this(baritone, DEFAULT_PRIORITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaritoneProcessHelper(Baritone baritone, double priority) {
|
public BaritoneProcessHelper(Baritone baritone, double priority) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
this.ctx = baritone.getPlayerContext();
|
this.ctx = baritone.getPlayerContext();
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
@@ -31,11 +29,6 @@ import net.minecraft.util.math.RayTraceResult;
|
|||||||
*/
|
*/
|
||||||
public final class BlockBreakHelper implements Helper {
|
public final class BlockBreakHelper implements Helper {
|
||||||
|
|
||||||
/**
|
|
||||||
* The last block that we tried to break, if this value changes
|
|
||||||
* between attempts, then we re-initialize the breaking process.
|
|
||||||
*/
|
|
||||||
private BlockPos lastBlock;
|
|
||||||
private boolean didBreakLastTick;
|
private boolean didBreakLastTick;
|
||||||
|
|
||||||
private IPlayerContext playerContext;
|
private IPlayerContext playerContext;
|
||||||
@@ -45,42 +38,20 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tryBreakBlock(BlockPos pos, EnumFacing side) {
|
public void tryBreakBlock(BlockPos pos, EnumFacing side) {
|
||||||
if (!pos.equals(lastBlock)) {
|
|
||||||
playerContext.playerController().clickBlock(pos, side);
|
|
||||||
}
|
|
||||||
if (playerContext.playerController().onPlayerDamageBlock(pos, side)) {
|
if (playerContext.playerController().onPlayerDamageBlock(pos, side)) {
|
||||||
playerContext.player().swingArm(EnumHand.MAIN_HAND);
|
playerContext.player().swingArm(EnumHand.MAIN_HAND);
|
||||||
}
|
}
|
||||||
lastBlock = pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopBreakingBlock() {
|
public void stopBreakingBlock() {
|
||||||
if (playerContext.playerController() != null) {
|
// The player controller will never be null, but the player can be
|
||||||
|
if (playerContext.player() != null) {
|
||||||
playerContext.playerController().resetBlockRemoving();
|
playerContext.playerController().resetBlockRemoving();
|
||||||
}
|
}
|
||||||
lastBlock = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fakeBreak() {
|
|
||||||
if (playerContext != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()) {
|
|
||||||
// for a non primary player, we need to fake break always, CLICK_LEFT has no effect
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!Baritone.settings().leftClickWorkaround.get()) {
|
|
||||||
// if this setting is false, we CLICK_LEFT regardless of gui status
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return mc.currentScreen != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean tick(boolean isLeftClick) {
|
|
||||||
if (!fakeBreak()) {
|
|
||||||
if (didBreakLastTick) {
|
|
||||||
stopBreakingBlock();
|
|
||||||
}
|
|
||||||
return isLeftClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void tick(boolean isLeftClick) {
|
||||||
RayTraceResult trace = playerContext.objectMouseOver();
|
RayTraceResult trace = playerContext.objectMouseOver();
|
||||||
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
||||||
|
|
||||||
@@ -91,6 +62,5 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
stopBreakingBlock();
|
stopBreakingBlock();
|
||||||
didBreakLastTick = false;
|
didBreakLastTick = false;
|
||||||
}
|
}
|
||||||
return false; // fakeBreak is true so no matter what we aren't forcing CLICK_LEFT
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,15 @@ import net.minecraft.world.chunk.Chunk;
|
|||||||
*/
|
*/
|
||||||
public class BlockStateInterface {
|
public class BlockStateInterface {
|
||||||
|
|
||||||
|
public static int numBlockStateLookups = 0;
|
||||||
|
public static int numTimesChunkSucceeded = 0;
|
||||||
private final Long2ObjectMap<Chunk> loadedChunks;
|
private final Long2ObjectMap<Chunk> loadedChunks;
|
||||||
private final WorldData worldData;
|
private final WorldData worldData;
|
||||||
|
|
||||||
private Chunk prev = null;
|
private Chunk prev = null;
|
||||||
private CachedRegion prevCached = null;
|
private CachedRegion prevCached = null;
|
||||||
|
|
||||||
|
private final boolean useTheRealWorld;
|
||||||
|
|
||||||
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
|
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
|
||||||
|
|
||||||
public BlockStateInterface(IPlayerContext ctx) {
|
public BlockStateInterface(IPlayerContext ctx) {
|
||||||
@@ -64,6 +67,7 @@ public class BlockStateInterface {
|
|||||||
} else {
|
} else {
|
||||||
this.loadedChunks = worldLoaded; // this will only be used on the main thread
|
this.loadedChunks = worldLoaded; // this will only be used on the main thread
|
||||||
}
|
}
|
||||||
|
this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.get();
|
||||||
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
|
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@@ -88,13 +92,13 @@ public class BlockStateInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IBlockState get0(int x, int y, int z) { // Mickey resigned
|
public IBlockState get0(int x, int y, int z) { // Mickey resigned
|
||||||
|
numBlockStateLookups++;
|
||||||
// Invalid vertical position
|
// Invalid vertical position
|
||||||
if (y < 0 || y >= 256) {
|
if (y < 0 || y >= 256) {
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Baritone.settings().pathThroughCachedOnly.get()) {
|
if (useTheRealWorld) {
|
||||||
Chunk cached = prev;
|
Chunk cached = prev;
|
||||||
// there's great cache locality in block state lookups
|
// there's great cache locality in block state lookups
|
||||||
// generally it's within each movement
|
// generally it's within each movement
|
||||||
@@ -103,6 +107,7 @@ public class BlockStateInterface {
|
|||||||
// which is a Long2ObjectOpenHashMap.get
|
// which is a Long2ObjectOpenHashMap.get
|
||||||
// see issue #113
|
// see issue #113
|
||||||
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
||||||
|
numTimesChunkSucceeded++;
|
||||||
return cached.getBlockState(x, y, z);
|
return cached.getBlockState(x, y, z);
|
||||||
}
|
}
|
||||||
Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
|
Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
|
||||||
|
|||||||
@@ -18,12 +18,15 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.api.utils.IInputOverrideHandler;
|
import baritone.api.utils.IInputOverrideHandler;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import org.lwjgl.input.Keyboard;
|
import net.minecraft.util.MovementInput;
|
||||||
|
import net.minecraft.util.MovementInputFromOptions;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -57,8 +60,18 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
|
|||||||
* @return Whether or not it is being forced down
|
* @return Whether or not it is being forced down
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean isInputForcedDown(KeyBinding key) {
|
public final Boolean isInputForcedDown(KeyBinding key) {
|
||||||
return isInputForcedDown(Input.getInputForBind(key));
|
Input input = Input.getInputForBind(key);
|
||||||
|
if (input == null || !inControl()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (input == Input.CLICK_LEFT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input == Input.CLICK_RIGHT) {
|
||||||
|
return isInputForcedDown(Input.CLICK_RIGHT);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,29 +104,25 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
|
|||||||
this.inputForceStateMap.clear();
|
this.inputForceStateMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onProcessKeyBinds() {
|
|
||||||
// Simulate the key being held down this tick
|
|
||||||
for (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
|
@Override
|
||||||
public final void onTick(TickEvent event) {
|
public final void onTick(TickEvent event) {
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean stillClick = blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
|
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
|
||||||
setInputForceState(Input.CLICK_LEFT, stillClick);
|
|
||||||
|
MovementInput desired = inControl()
|
||||||
|
? new PlayerMovementInput(this)
|
||||||
|
: new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings);
|
||||||
|
|
||||||
|
if (ctx.player().movementInput.getClass() != desired.getClass()) {
|
||||||
|
ctx.player().movementInput = desired; // only set it if it was previously incorrect
|
||||||
|
// gotta do it this way, or else it constantly thinks you're beginning a double tap W sprint lol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inControl() {
|
||||||
|
return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockBreakHelper getBlockBreakHelper() {
|
public BlockBreakHelper getBlockBreakHelper() {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import baritone.pathing.path.PathExecutor;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class PathingControlManager implements IPathingControlManager {
|
public class PathingControlManager implements IPathingControlManager {
|
||||||
private final Baritone baritone;
|
private final Baritone baritone;
|
||||||
@@ -64,8 +64,7 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
command = null;
|
command = null;
|
||||||
for (IBaritoneProcess proc : processes) {
|
for (IBaritoneProcess proc : processes) {
|
||||||
proc.onLostControl();
|
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
|
if (proc.isActive() && !proc.isTemporary()) { // it's okay only 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());
|
throw new IllegalStateException(proc.displayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,11 +82,12 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
|
|
||||||
public void preTick() {
|
public void preTick() {
|
||||||
inControlLastTick = inControlThisTick;
|
inControlLastTick = inControlThisTick;
|
||||||
command = doTheStuff();
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
|
command = executeProcesses();
|
||||||
if (command == null) {
|
if (command == null) {
|
||||||
|
p.cancelSegmentIfSafe();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PathingBehavior p = baritone.getPathingBehavior();
|
|
||||||
switch (command.commandType) {
|
switch (command.commandType) {
|
||||||
case REQUEST_PAUSE:
|
case REQUEST_PAUSE:
|
||||||
p.requestPause();
|
p.requestPause();
|
||||||
@@ -170,32 +170,30 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PathingCommand doTheStuff() {
|
public PathingCommand executeProcesses() {
|
||||||
List<IBaritoneProcess> inContention = processes.stream().filter(IBaritoneProcess::isActive).sorted(Comparator.comparingDouble(IBaritoneProcess::priority)).collect(Collectors.toList());
|
Stream<IBaritoneProcess> inContention = processes.stream()
|
||||||
boolean found = false;
|
.filter(IBaritoneProcess::isActive)
|
||||||
boolean cancelOthers = false;
|
.sorted(Comparator.comparingDouble(IBaritoneProcess::priority).reversed());
|
||||||
PathingCommand exec = null;
|
|
||||||
for (int i = inContention.size() - 1; i >= 0; i--) { // truly a gamer moment
|
|
||||||
IBaritoneProcess proc = inContention.get(i);
|
Iterator<IBaritoneProcess> iterator = inContention.iterator();
|
||||||
if (found) {
|
while (iterator.hasNext()) {
|
||||||
if (cancelOthers) {
|
IBaritoneProcess proc = iterator.next();
|
||||||
proc.onLostControl();
|
|
||||||
|
PathingCommand exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
|
||||||
|
if (exec == null) {
|
||||||
|
if (proc.isActive()) {
|
||||||
|
throw new IllegalStateException(proc.displayName() + " returned null PathingCommand");
|
||||||
}
|
}
|
||||||
|
proc.onLostControl();
|
||||||
} else {
|
} 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;
|
inControlThisTick = proc;
|
||||||
found = true;
|
if (!proc.isTemporary()) {
|
||||||
cancelOthers = !proc.isTemporary();
|
iterator.forEachRemaining(IBaritoneProcess::onLostControl);
|
||||||
|
}
|
||||||
|
return exec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return exec;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.api.utils.input.Input;
|
||||||
|
import net.minecraft.util.MovementInput;
|
||||||
|
|
||||||
|
public class PlayerMovementInput extends MovementInput {
|
||||||
|
private final InputOverrideHandler handler;
|
||||||
|
|
||||||
|
public PlayerMovementInput(InputOverrideHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlayerMoveState() {
|
||||||
|
this.moveStrafe = 0.0F;
|
||||||
|
this.moveForward = 0.0F;
|
||||||
|
|
||||||
|
jump = handler.isInputForcedDown(Input.JUMP); // oppa
|
||||||
|
|
||||||
|
if (this.forwardKeyDown = handler.isInputForcedDown(Input.MOVE_FORWARD)) {
|
||||||
|
this.moveForward++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.backKeyDown = handler.isInputForcedDown(Input.MOVE_BACK)) {
|
||||||
|
this.moveForward--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.leftKeyDown = handler.isInputForcedDown(Input.MOVE_LEFT)) {
|
||||||
|
this.moveStrafe++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.rightKeyDown = handler.isInputForcedDown(Input.MOVE_RIGHT)) {
|
||||||
|
this.moveStrafe--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sneak = handler.isInputForcedDown(Input.SNEAK)) {
|
||||||
|
this.moveStrafe *= 0.3D;
|
||||||
|
this.moveForward *= 0.3D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -103,7 +103,7 @@ public class ToolSet {
|
|||||||
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 = calculateSpeedVsBlock(itemStack, blockState);
|
||||||
if (v > value) {
|
if (v > value) {
|
||||||
value = v;
|
value = v;
|
||||||
best = i;
|
best = i;
|
||||||
@@ -128,7 +128,7 @@ public class ToolSet {
|
|||||||
*/
|
*/
|
||||||
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 calculateSpeedVsBlock(stack, b.getDefaultState());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,7 +138,7 @@ public class ToolSet {
|
|||||||
* @param state the blockstate to be mined
|
* @param state the blockstate to be mined
|
||||||
* @return how long it would take in ticks
|
* @return how long it would take in ticks
|
||||||
*/
|
*/
|
||||||
public static double calculateStrVsBlock(ItemStack item, IBlockState state) {
|
public static double calculateSpeedVsBlock(ItemStack item, IBlockState state) {
|
||||||
float hardness = state.getBlockHardness(null, null);
|
float hardness = state.getBlockHardness(null, null);
|
||||||
if (hardness < 0) {
|
if (hardness < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -154,11 +154,10 @@ public class ToolSet {
|
|||||||
|
|
||||||
speed /= hardness;
|
speed /= hardness;
|
||||||
if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
|
if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
|
||||||
speed /= 30;
|
return speed / 30;
|
||||||
} else {
|
} else {
|
||||||
speed /= 100;
|
return speed / 100;
|
||||||
}
|
}
|
||||||
return speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,7 +179,7 @@ public class ToolSet {
|
|||||||
speed *= 0.09;
|
speed *= 0.09;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
speed *= 0.0027;
|
speed *= 0.0027; // you might think that 0.09*0.3 = 0.027 so that should be next, that would make too much sense. it's 0.0027.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
speed *= 0.00081;
|
speed *= 0.00081;
|
||||||
|
|||||||
@@ -23,16 +23,12 @@ import baritone.api.utils.BetterBlockPos;
|
|||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public final class Favoring {
|
public final class Favoring {
|
||||||
private List<Avoidance> avoidances;
|
|
||||||
private final Long2DoubleOpenHashMap favorings;
|
private final Long2DoubleOpenHashMap favorings;
|
||||||
|
|
||||||
public Favoring(IPlayerContext ctx, IPath previous) {
|
public Favoring(IPlayerContext ctx, IPath previous) {
|
||||||
this(previous);
|
this(previous);
|
||||||
avoidances = Avoidance.create(ctx);
|
for (Avoidance avoid : Avoidance.create(ctx)) {
|
||||||
for (Avoidance avoid : avoidances) {
|
|
||||||
avoid.applySpherical(favorings);
|
avoid.applySpherical(favorings);
|
||||||
}
|
}
|
||||||
System.out.println("Favoring size: " + favorings.size());
|
System.out.println("Favoring size: " + favorings.size());
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
|
|
||||||
public abstract class PathBase implements IPath {
|
public abstract class PathBase implements IPath {
|
||||||
@Override
|
@Override
|
||||||
public PathBase cutoffAtLoadedChunks(Object bsi0) {
|
public PathBase cutoffAtLoadedChunks(Object bsi0) { // <-- cursed cursed cursed
|
||||||
BlockStateInterface bsi = (BlockStateInterface) bsi0;
|
BlockStateInterface bsi = (BlockStateInterface) bsi0;
|
||||||
for (int i = 0; i < positions().size(); i++) {
|
for (int i = 0; i < positions().size(); i++) {
|
||||||
BlockPos pos = positions().get(i);
|
BlockPos pos = positions().get(i);
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ package baritone.utils.player;
|
|||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.cache.IWorldData;
|
import baritone.api.cache.IWorldData;
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlayerControllerMP playerController() {
|
public IPlayerController playerController() {
|
||||||
return mc.playerController;
|
return PrimaryPlayerController.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils.player;
|
||||||
|
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
|
import baritone.utils.Helper;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.inventory.ClickType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 12/14/2018
|
||||||
|
*/
|
||||||
|
public enum PrimaryPlayerController implements IPlayerController, Helper {
|
||||||
|
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side) {
|
||||||
|
return mc.playerController.onPlayerDamageBlock(pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetBlockRemoving() {
|
||||||
|
mc.playerController.resetBlockRemoving();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player) {
|
||||||
|
return mc.playerController.windowClick(windowId, slotId, mouseButton, type, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGameType(GameType type) {
|
||||||
|
mc.playerController.setGameType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GameType getGameType() {
|
||||||
|
return mc.playerController.getCurrentGameType();
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -44,4 +44,4 @@ public class CachedRegionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,4 +167,4 @@ public class OpenSetsTest {
|
|||||||
assertTrue(set.isEmpty());
|
assertTrue(set.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,4 +47,4 @@ public class GoalGetToBlockTest {
|
|||||||
}
|
}
|
||||||
assertTrue(acceptableOffsets.toString(), acceptableOffsets.isEmpty());
|
assertTrue(acceptableOffsets.toString(), acceptableOffsets.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,4 @@ public class ActionCostsTest {
|
|||||||
return fallDistance;
|
return fallDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,4 +136,4 @@ public class BetterBlockPosTest {
|
|||||||
long after2 = System.nanoTime() / 1000000L;
|
long after2 = System.nanoTime() / 1000000L;
|
||||||
System.out.println((after1 - before1) + " " + (after2 - before2));
|
System.out.println((after1 - before1) + " " + (after2 - before2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,4 +29,4 @@ public class PathingBlockTypeTest {
|
|||||||
assertTrue(type == PathingBlockType.fromBits(bits[0], bits[1]));
|
assertTrue(type == PathingBlockType.fromBits(bits[0], bits[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user