Compare commits

...

99 Commits

Author SHA1 Message Date
Leijurv 9ce574266f Merge branch 'master' into benchmark 2019-01-17 12:24:23 -08:00
Leijurv a5b9885767 not even used 2019-01-17 12:22:36 -08:00
Leijurv 2daedecf92 maybe fix 2019-01-16 17:42:43 -08:00
Brady db24822d2f Fix cursed exception 2019-01-16 13:50:15 -06:00
Brady 59320d9b85 Auto test class javadoc 2019-01-16 13:37:39 -06:00
Leijurv 9dfcef6356 crucial performance optimization 2019-01-15 17:21:50 -08:00
Leijurv ae3fc14b52 refactor name 2019-01-14 19:52:31 -08:00
Leijurv f8681d179d TODO use nanotime when calc starts on dec 31 2019-01-13 00:00:52 -08:00
Leijurv f23630064e reorder 2019-01-12 22:33:46 -08:00
Leijurv bec7f9be96 this lets proguard optimize out one more double division 2019-01-11 13:18:31 -08:00
Leijurv 09e94eaa8e not anymore 2019-01-11 13:02:03 -08:00
Leijurv 5f29bb3e7f gotta go fast 2019-01-10 18:55:55 -08:00
Leijurv 1ad6a0d5b5 remove all that crap lol 2019-01-10 18:21:02 -08:00
Brady f727e71eaf Expose IPathingControlManager in IBaritone 2019-01-10 19:57:09 -06:00
Leijurv 14f006c3a5 Merge branch 'epic-movement-input' 2019-01-10 17:25:57 -08:00
Leijurv 200211c186 dont continue walking if there is no process in charge 2019-01-10 13:52:52 -08:00
Leijurv 5ca214534d mouse stuff 2019-01-09 19:11:53 -08:00
Leijurv 85ea21e83b epic movement input 2019-01-09 18:22:34 -08:00
Leijurv 7d572d748b shouldnt be needed actually 2019-01-09 15:13:48 -08:00
Leijurv fbcae10f96 cherry picked fix from builder 2019-01-09 15:13:09 -08:00
Leijurv a4495ce80a tweaks 2019-01-08 22:00:33 -08:00
Leijurv f5478f6169 Merge pull request #306 from babbaj/master
fix garbage code
2019-01-08 21:56:27 -08:00
babbaj ae1e229619 fix garbage code 2019-01-09 05:39:37 -05:00
Leijurv bc5982b994 fine lol 2019-01-08 20:45:35 -08:00
Leijurv e971d5d43f prevent favoring from affecting movement cost thresholds 2019-01-08 14:56:21 -08:00
Leijurv ee9519d891 tweaks 2019-01-07 08:53:39 -08:00
Leijurv 58bb209158 Merge pull request #305 from babbaj/master
real gamers do it like this
2019-01-07 08:45:26 -08:00
babbaj 23dc97ad5e oops that should have been static 2019-01-07 01:25:39 -05:00
Leijurv 84b580b001 cursed 2019-01-06 22:21:52 -08:00
babbaj 227b303669 value doesnt have to be lowercase 2019-01-07 01:16:52 -05:00
babbaj 712a0a3905 refactor SettingsUtil to be more epic 2019-01-07 01:08:46 -05:00
EvilSourcerer 76427b8ecb real gamers use bufferedreader 2019-01-06 19:10:47 -06:00
Leijurv 8b6d621d20 crucial performance optimization 2019-01-05 23:38:24 -08:00
Leijurv 7898b24bac mc is weird 2019-01-04 23:37:00 -08:00
Leijurv 39648c5dc6 comment 2019-01-03 23:40:43 -08:00
Leijurv 83e6b2fdfe cursed 2019-01-02 21:08:31 -08:00
Leijurv 816727d65b not happening 2019-01-01 22:32:43 -08:00
Leijurv 0e012adb6c unneeded 2018-12-31 08:00:43 -10:00
Leijurv 539b0e64c8 bitshift 2: electric boogaloo 2018-12-30 07:36:10 -10:00
Leijurv 258700ee7b bitshift 2018-12-29 14:50:21 -10:00
Leijurv 1da72ba473 unneeded 2018-12-28 17:17:43 -10:00
Leijurv c2c69f243e nothing is trashy in baritone 2018-12-27 16:16:12 -10:00
Brady dffbb8e4c8 Overload reachable with IPlayerContext parameter 2018-12-27 17:15:32 -06:00
Leijurv bebdede33b unneeded 2018-12-26 18:07:14 -10:00
Leijurv 50d37bb311 lol 2018-12-25 20:07:26 -08:00
Leijurv bbb73008ac stupid 2018-12-24 18:42:01 -08:00
Brady c324f11a96 Fix bad block breaking that NCP doesn't agree with 2018-12-24 12:15:23 -06:00
Leijurv c4eb6be0fe dumb 2018-12-23 23:09:02 -08:00
Leijurv 64200030d2 brady was too optimistic 2018-12-22 20:38:44 -08:00
Leijurv 4d7e74365b reformat 2018-12-21 17:54:16 -08:00
Leijurv b9b25e7e6b no more stupid wrapper getters 2018-12-20 21:22:18 -08:00
Leijurv 8a4f48f08d diagonal descend option 2018-12-20 21:06:56 -08:00
Leijurv ae9ab03e51 walk on water hunger penalty 2018-12-19 22:01:47 -08:00
Leijurv 02478ee887 wtF 2018-12-19 21:30:58 -08:00
Leijurv 57f238de7d that was a big screwup 2018-12-19 17:02:09 -08:00
Leijurv 77938a77e8 add jump penalty 2018-12-19 14:37:11 -08:00
Leijurv d41aa5f9ae epicly fast 2018-12-19 12:59:07 -08:00
Leijurv 0ef3386ebf appease codacy 2018-12-19 12:48:41 -08:00
Brady 9703de86d3 Fix NullPointerException 2018-12-18 19:36:43 -06:00
Brady 764e8d7daa Add windowClick to IPlayerController 2018-12-18 19:27:45 -06:00
Brady 18f5c129a4 Remove dependency for PlayerControllerMP implementation 2018-12-18 19:25:23 -06:00
Leijurv 807d6a0cf4 crucial performance optimization 2018-12-18 16:22:54 -08:00
Leijurv a0ab2a8ba7 timing meme 2018-12-18 16:16:32 -08:00
Leijurv 90d0fb7efb simplify check 2018-12-17 18:27:31 -08:00
Leijurv fe4290b218 little fix 2018-12-16 20:14:21 -08:00
Leijurv cc04342358 epic performance 2018-12-16 16:26:48 -08:00
Leijurv 66da826eab fix toxic cloud 2018-12-15 22:25:50 -08:00
Leijurv dcb93dab50 Merge branch 'master' into benchmark 2018-11-23 13:42:20 -08:00
Leijurv f8c0b4c1c1 Merge branch 'master' into benchmark 2018-11-13 13:30:51 -08:00
Leijurv c41f65d4f6 clean up benchmark branch 2018-09-27 11:38:32 -07:00
Leijurv 54811fb643 merge 2018-09-27 10:22:37 -07:00
Leijurv 92442dcdb9 total accounted time 2018-09-26 13:58:11 -07:00
Leijurv 68af1f3bb3 Merge branch 'master' into benchmark 2018-09-26 13:46:29 -07:00
Leijurv a796e9c047 merge 2018-09-26 13:45:00 -07:00
Leijurv 2c32cadf18 count BetterBlockPos 2018-09-22 08:55:46 -07:00
Leijurv 32cd519bcf merge 2018-09-22 08:51:03 -07:00
Leijurv 88908d8776 more better block pos 2018-09-22 08:47:02 -07:00
Leijurv 79bd26968a count betterblockpos instantiation 2018-09-21 22:10:25 -07:00
Leijurv 2d288c7a47 Merge branch 'master' into benchmark 2018-09-21 21:58:26 -07:00
Leijurv 2c46458bc1 merge 2018-09-11 13:57:01 -07:00
Brady 9c37414e50 Merge branch 'master' into benchmark 2018-09-07 19:31:01 -05:00
Leijurv fb667c3b4d merge 2018-09-04 15:41:35 -07:00
Leijurv da07b63e0a measure 2018-08-31 12:57:38 -07:00
Leijurv 1fe262929e forgot print 2018-08-31 12:04:55 -07:00
Leijurv 0ee93aea23 cache chunk in BlockStateInterface 2018-08-31 11:51:43 -07:00
Leijurv 836b41a3aa num lookups check 2018-08-31 11:51:08 -07:00
Leijurv c370461a24 merge 2018-08-31 11:45:45 -07:00
Leijurv a753fe5df9 bench the whole loop 2018-08-29 14:46:58 -07:00
Leijurv 27aeba3f8b Merge branch 'master' into benchmark 2018-08-29 14:16:32 -07:00
Leijurv 141a9f92cb node map performance, fixes #107 2018-08-29 13:21:54 -07:00
Leijurv 5e4f0b47c5 merge 2018-08-29 12:24:45 -07:00
leijurv d0a88987a8 format 2018-08-29 07:38:35 -07:00
leijurv 9cb199d40a also bench getnode 2018-08-28 21:31:16 -07:00
leijurv a1d218b37a merge 2018-08-28 21:17:12 -07:00
leijurv 7ae1a9f6e4 3x faster cache check 2018-08-28 21:14:50 -07:00
leijurv fd74fcabc0 way more bench checks 2018-08-28 21:10:56 -07:00
leijurv 4da155c0ed 20% improvement to cached chunk check performance 2018-08-28 21:10:41 -07:00
leijurv 7a3f7f9a9e Merge branch 'master' into benchmark 2018-08-28 20:51:42 -07:00
Leijurv 1212d34f91 rudimentary benchmark 2018-08-28 15:48:36 -07:00
66 changed files with 617 additions and 480 deletions
-2
View File
@@ -25,8 +25,6 @@ Here are some links to help to get started:
- [Installation](INSTALL.md)
There's also some useful information down below
# Setup
## Command Line
@@ -208,7 +208,7 @@ public class ProguardTask extends BaritoneGradleTask {
Objects.requireNonNull(extension);
// 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");
f_replacer.setAccessible(true);
Object replacer = f_replacer.get(extension);
@@ -26,4 +26,4 @@ public enum MappingType {
SEARGE,
NOTCH,
CUSTOM // forgegradle
}
}
@@ -60,4 +60,4 @@ public class ReobfWrapper {
throw new IllegalStateException(ex);
}
}
}
}
+3
View File
@@ -21,6 +21,7 @@ import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IFollowProcess;
import baritone.api.process.IGetToBlockProcess;
@@ -64,6 +65,8 @@ public interface IBaritone {
*/
IWorldProvider getWorldProvider();
IPathingControlManager getPathingControlManager();
IInputOverrideHandler getInputOverrideHandler();
ICustomGoalProcess getCustomGoalProcess();
+20 -7
View File
@@ -68,6 +68,16 @@ public class Settings {
*/
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.
* Reliability: questionable.
@@ -101,6 +111,15 @@ public class Settings {
*/
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.)
*/
@@ -153,10 +172,8 @@ public class Settings {
* metric gets better and better with each block, instead of slightly worse.
* <p>
* 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
/**
@@ -435,10 +452,6 @@ public class Settings {
/**
* {@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);
@@ -36,9 +36,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onPlayerUpdate(PlayerUpdateEvent event) {}
@Override
default void onProcessKeyBinds() {}
@Override
default void onSendChatMessage(ChatEvent event) {}
@@ -49,11 +49,6 @@ public interface IGameEventListener {
*/
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.
*
@@ -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 failureTimeout If a path isn't found, the path finder will continue for this amount of time
*
* @return The final path
*/
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
@@ -33,7 +33,6 @@ public interface Goal {
* @param x The goal X position
* @param y The goal Y position
* @param z The goal Z position
*
* @return Whether or not it satisfies this goal
*/
boolean isInGoal(int x, int y, int z);
@@ -44,7 +43,6 @@ public interface Goal {
* @param x The goal X position
* @param y The goal Y position
* @param z The goal Z position
*
* @return The estimate number of ticks to satisfy the goal
*/
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 y;
public final int z;
public static long numCreated;
static {
numCreated = 0;
}
{
numCreated++;
}
public BetterBlockPos(int x, int y, int z) {
super(x, y, z);
@@ -27,9 +27,7 @@ import net.minecraft.client.settings.KeyBinding;
*/
public interface IInputOverrideHandler extends IBehavior {
default boolean isInputForcedDown(KeyBinding key) {
return isInputForcedDown(Input.getInputForBind(key));
}
Boolean isInputForcedDown(KeyBinding key);
boolean isInputForcedDown(Input input);
@@ -20,7 +20,6 @@ package baritone.api.utils;
import baritone.api.cache.IWorldData;
import net.minecraft.block.BlockSlab;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -37,7 +36,7 @@ public interface IPlayerContext {
EntityPlayerSP player();
PlayerControllerMP playerController();
IPlayerController playerController();
World world();
@@ -17,11 +17,30 @@
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
* @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 java.util.Objects;
import java.util.Optional;
public class PathCalculationResult {
@@ -31,11 +32,9 @@ public class PathCalculationResult {
}
public PathCalculationResult(Type type, IPath path) {
Objects.requireNonNull(type);
this.path = path;
this.type = type;
if (type == null) {
throw new IllegalArgumentException("come on");
}
}
public final Optional<IPath> getPath() {
@@ -127,6 +127,16 @@ public final class RotationUtils {
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
* of the specified block. It first checks if the block center is reachable, and if so,
@@ -18,56 +18,77 @@
package baritone.api.utils;
import baritone.api.Settings;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
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.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraft.client.Minecraft.getMinecraft;
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 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) {
try (Scanner scan = new Scanner(settingsFile)) {
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.isEmpty()) {
continue;
try {
forEachLine(SETTINGS_PATH, line -> {
Matcher matcher = SETTING_PATTERN.matcher(line);
if (!matcher.matches()) {
System.out.println("Invalid syntax in setting file: " + line);
return;
}
if (line.startsWith("#") || line.startsWith("//")) {
continue;
}
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();
String settingName = matcher.group("setting").toLowerCase();
String settingValue = matcher.group("value");
try {
parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Unable to parse line " + line);
ex.printStackTrace();
}
}
});
} catch (Exception ex) {
ex.printStackTrace();
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) {
try (FileOutputStream out = new FileOutputStream(settingsFile)) {
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
for (Settings.Setting setting : settings.allSettings) {
if (setting.get() == null) {
System.out.println("NULL SETTING?" + setting.getName());
@@ -83,11 +104,11 @@ public class SettingsUtil {
if (io == null) {
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) {
System.out.println("Exception thrown while saving Baritone settings!");
ex.printStackTrace();
System.out.println("Exception while saving Baritone settings!");
}
}
@@ -18,8 +18,10 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.utils.Helper;
import net.minecraft.client.settings.KeyBinding;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -31,6 +33,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(KeyBinding.class)
public class MixinKeyBinding {
@Shadow
public int pressTime;
@Inject(
method = "isKeyDown",
at = @At("HEAD"),
@@ -38,8 +43,26 @@ public class MixinKeyBinding {
)
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
// only the primary baritone forces keys
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
cir.setReturnValue(true);
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
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(
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
at = @At("HEAD")
+1
View File
@@ -129,6 +129,7 @@ public class Baritone implements IBaritone {
this.initialized = true;
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
@@ -55,10 +55,7 @@ public class InventoryBehavior extends Behavior {
}
private void swapWithHotBar(int inInventory, int inHotbar) {
if (inInventory < 9) {
inInventory += 36;
}
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory, inHotbar, ClickType.SWAP, ctx.player());
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
}
private int firstValidThrowaway() { // TODO offhand idk
@@ -81,7 +78,7 @@ public class InventoryBehavior extends Behavior {
continue;
}
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) {
bestSpeed = speed;
bestInd = i;
@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.cache.ContainerMemory;
import baritone.cache.Waypoint;
@@ -60,6 +61,14 @@ public final class MemoryBehavior extends Behavior {
super(baritone);
}
@Override
public synchronized void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
enderChestWindowId = null;
futureInventories.clear();
}
}
@Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
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(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)
if (((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
enderChestWindowId = packet.getWindowId();
return;
}
enderChestWindowId = packet.getWindowId();
return;
}
futureInventories.stream()
.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) {
BlockStateInterface bsi = new CalculationContext(baritone).bsi();
BlockStateInterface bsi = new CalculationContext(baritone).bsi;
Block block = bsi.get0(in).getBlock();
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
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();
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks(context.bsi());
IPath result = p.cutoffAtLoadedChunks(context.bsi);
if (result instanceof CutoffPath) {
logDebug("Cutting off path at edge of loaded chunks");
@@ -499,7 +499,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
Goal transformed = goal;
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
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());
}
}
+3 -3
View File
@@ -179,8 +179,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (region == null) {
continue;
}
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
int distX = (region.getX() << 9 + 256) - pruneCenter.getX();
int distZ = (region.getZ() << 9 + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
@@ -215,7 +215,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (mostRecentlyModified == null) {
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() {
+2 -1
View File
@@ -123,7 +123,8 @@ public class ContainerMemory implements IContainerMemory {
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()));
for (ItemStack stack : write) {
out = out.writeItemStack(stack);
+16 -35
View File
@@ -28,8 +28,9 @@ import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public enum WorldScanner implements IWorldScanner {
@@ -41,7 +42,7 @@ public enum WorldScanner implements IWorldScanner {
if (blocks.contains(null)) {
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()) {
return res;
}
@@ -71,33 +72,7 @@ public enum WorldScanner implements IWorldScanner {
continue;
}
allUnloaded = false;
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
chunkX = chunkX << 4;
chunkZ = chunkZ << 4;
for (int y0 = 0; y0 < 16; y0++) {
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) {
continue;
}
int yReal = y0 << 4;
BlockStateContainer bsc = extendedblockstorage.getData();
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
// for better cache locality, iterate in that order
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
IBlockState state = bsc.get(x, y, z);
if (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;
}
}
}
}
}
}
scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY);
}
}
if ((allUnloaded && foundChunks)
@@ -124,7 +99,12 @@ public enum WorldScanner implements IWorldScanner {
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();
for (int y0 = 0; y0 < 16; y0++) {
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
@@ -133,21 +113,22 @@ public enum WorldScanner implements IWorldScanner {
}
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())) {
if (search.contains(state.getBlock())) {
int yy = yReal | y;
res.add(new BlockPos((pos.x << 4) | x, yy, (pos.z << 4) | z));
if (res.size() >= max || Math.abs(yy - playerY) < yLevelThreshold) {
return res;
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) {
return;
}
}
}
}
}
}
return res;
}
}
@@ -54,11 +54,6 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onPlayerUpdate(event));
}
@Override
public final void onProcessKeyBinds() {
listeners.forEach(IGameEventListener::onProcessKeyBinds);
}
@Override
public final void onSendChatMessage(ChatEvent 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.movement.CalculationContext;
import baritone.pathing.movement.Moves;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.pathing.BetterWorldBorder;
import baritone.utils.pathing.Favoring;
import baritone.utils.pathing.MutableMoveResult;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;
/**
@@ -55,7 +59,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
startNode.combinedCost = startNode.estimatedCostToGoal;
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
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])
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
@@ -64,8 +67,8 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
}
MutableMoveResult res = new MutableMoveResult();
Favoring favored = favoring;
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
long startTime = System.nanoTime() / 1000000L;
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder());
long startTime = System.currentTimeMillis();
boolean slowPath = Baritone.settings().slowPath.get();
if (slowPath) {
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 numEmptyChunk = 0;
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
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) {
long now = System.nanoTime() / 1000000L;
if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) {
break;
if ((numNodes & (timeCheckInterval - 1)) == 0) { // only call this once every 64 nodes (about half a millisecond)
long now = System.currentTimeMillis(); // since nanoTime is slow on windows (takes many microseconds)
if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) {
break;
}
}
if (slowPath) {
try {
@@ -90,15 +120,21 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
} catch (InterruptedException ex) {
}
}
long before = System.nanoTime();
PathNode currentNode = openSet.removeLowest();
currentNode.isOpen = false;
long t = System.nanoTime();
heapRemove += t - before;
heapRemoveCount++;
mostRecentConsidered = currentNode;
numNodes++;
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));
}
goalCheck += System.nanoTime() - t;
goalCheckCount++;
for (Moves moves : Moves.values()) {
long s = System.nanoTime();
int newX = currentNode.x + moves.xOffset;
int newZ = currentNode.z + moves.zOffset;
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
numEmptyChunk++;
}
long costStart = System.nanoTime();
chunk += costStart - s;
chunkCount++;
continue;
}
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) {
continue;
}
long costStart = System.nanoTime();
chunk += costStart - s;
chunkCount++;
// TODO cache cost
int numLookupsBefore = BlockStateInterface.numBlockStateLookups;
long numCreatedBefore = BetterBlockPos.numCreated;
res.reset();
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++;
double actionCost = res.cost;
if (actionCost >= ActionCosts.COST_INF) {
@@ -124,10 +174,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (actionCost <= 0 || Double.isNaN(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
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)) {
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
actionCost *= favored.calculate(hashCode);
}
long st = System.nanoTime();
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
getNode += System.nanoTime() - st;
getNodeCount++;
double tentativeCost = currentNode.cost + actionCost;
if (tentativeCost < neighbor.cost) {
double improvementBy = neighbor.cost - tentativeCost;
@@ -153,11 +206,16 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
neighbor.previous = currentNode;
neighbor.cost = tentativeCost;
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
if (neighbor.isOpen) {
if (neighbor.isOpen()) {
long bef = System.nanoTime();
openSet.update(neighbor);
heapUpdate += System.nanoTime() - bef;
heapUpdateCount++;
} else {
neighbor.isOpen = true;
long bef = System.nanoTime();
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++) {
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) {
return Optional.empty();
}
System.out.println(numMovementsConsidered + " movements considered");
System.out.println("Open set size: " + openSet.size());
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;
for (int i = 0; i < bestSoFar.length; i++) {
if (bestSoFar[i] == null) {
@@ -192,7 +280,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
bestDist = dist;
}
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) {
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)");
@@ -136,11 +136,10 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
* for the node mapped to the specified pos. If no node is found,
* a new node is created.
*
* @param x The x position of the node
* @param y The y position of the node
* @param z The z position of the node
* @param x The x position of the node
* @param y The y 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)}
*
* @return The associated node
* @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);
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
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;
}
}
@@ -58,12 +58,6 @@ public final class PathNode {
*/
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.
*/
@@ -76,12 +70,16 @@ public final class PathNode {
if (Double.isNaN(estimatedCostToGoal)) {
throw new IllegalStateException(goal + " calculated implausible heuristic");
}
this.isOpen = false;
this.heapPosition = -1;
this.x = x;
this.y = y;
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
*
@@ -59,7 +59,7 @@ public final class BinaryHeapOpenSet implements IOpenSet {
@Override
public final void insert(PathNode value) {
if (size >= array.length - 1) {
array = Arrays.copyOf(array, array.length * 2);
array = Arrays.copyOf(array, array.length << 1);
}
size++;
value.heapPosition = size;
@@ -42,26 +42,28 @@ public class CalculationContext {
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
private final IBaritone baritone;
private final EntityPlayerSP player;
private final World world;
private final WorldData worldData;
private final BlockStateInterface bsi;
private final ToolSet toolSet;
private final boolean hasWaterBucket;
private final boolean hasThrowaway;
private final boolean canSprint;
private final double placeBlockCost;
private final boolean allowBreak;
private final boolean allowParkour;
private final boolean allowParkourPlace;
private final boolean allowJumpAt256;
private final boolean assumeWalkOnWater;
private final int maxFallHeightNoWater;
private final int maxFallHeightBucket;
private final double waterWalkSpeed;
private final double breakBlockAdditionalCost;
private final BetterWorldBorder worldBorder;
public final IBaritone baritone;
public final World world;
public final WorldData worldData;
public final BlockStateInterface bsi;
public final ToolSet toolSet;
public final boolean hasWaterBucket;
public final boolean hasThrowaway;
public final boolean canSprint;
public final double placeBlockCost;
public final boolean allowBreak;
public final boolean allowParkour;
public final boolean allowParkourPlace;
public final boolean allowJumpAt256;
public final boolean assumeWalkOnWater;
public final boolean allowDiagonalDescend;
public final int maxFallHeightNoWater;
public final int maxFallHeightBucket;
public final double waterWalkSpeed;
public final double breakBlockAdditionalCost;
public final double jumpPenalty;
public final double walkOnWaterOnePenalty;
public final BetterWorldBorder worldBorder;
public CalculationContext(IBaritone baritone) {
this(baritone, false);
@@ -69,11 +71,10 @@ public class CalculationContext {
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
this.baritone = baritone;
this.player = baritone.getPlayerContext().player();
EntityPlayerSP player = baritone.getPlayerContext().player();
this.world = baritone.getPlayerContext().world();
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
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.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();
@@ -84,6 +85,7 @@ public class CalculationContext {
this.allowParkourPlace = Baritone.settings().allowParkourPlace.get();
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.get();
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.get();
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.get();
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
int depth = EnchantmentHelper.getDepthStriderModifier(player);
@@ -93,6 +95,8 @@ public class CalculationContext {
float mult = depth / 3.0F;
this.waterWalkSpeed = ActionCosts.WALK_ONE_IN_WATER_COST * (1 - mult) + ActionCosts.WALK_ONE_BLOCK_COST * mult;
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?
// 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.
@@ -120,7 +124,7 @@ public class CalculationContext {
}
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;
}
if (isPossiblyProtected(x, y, z)) {
@@ -130,7 +134,7 @@ public class CalculationContext {
}
public boolean canBreakAt(int x, int y, int z) {
if (!allowBreak()) {
if (!allowBreak) {
return false;
}
return !isPossiblyProtected(x, y, z);
@@ -140,76 +144,4 @@ public class CalculationContext {
// TODO more protection logic here; see #220
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.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList;
import java.util.List;
@@ -35,7 +34,6 @@ import java.util.Optional;
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 final IBaritone baritone;
@@ -86,7 +84,7 @@ public abstract class Movement implements IMovement, MovementHelper {
return cost;
}
protected abstract double calculateCost(CalculationContext context);
public abstract double calculateCost(CalculationContext context);
@Override
public double recalculateCost() {
@@ -126,13 +124,10 @@ public abstract class Movement implements IMovement, MovementHelper {
rotation,
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) -> {
baritone.getInputOverrideHandler().setInputForceState(input, forced);
});
currentState.getInputStates().replaceAll((input, forced) -> false);
currentState.getInputStates().clear();
// If the current status indicates a completed movement
if (currentState.getStatus().isComplete()) {
@@ -231,7 +226,7 @@ public abstract class Movement implements IMovement, MovementHelper {
}
public void checkLoadedChunk(CalculationContext context) {
calculatedWhileLoaded = !(context.world().getChunk(getDest()) instanceof EmptyChunk);
calculatedWhileLoaded = context.bsi.worldContainsLoadedChunk(dest.x, dest.z);
}
@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) {
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)) {
return COST_INF;
}
if (avoidBreaking(context.bsi(), x, y, z, state)) {
if (avoidBreaking(context.bsi, x, y, z, state)) {
return COST_INF;
}
if (block instanceof BlockLiquid) {
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 strVsBlock = context.getToolSet().getStrVsBlock(state);
double strVsBlock = context.toolSet.getStrVsBlock(state);
if (strVsBlock <= 0) {
return COST_INF;
}
double result = m / strVsBlock;
result += context.breakBlockAdditionalCost();
result += context.breakBlockAdditionalCost;
if (includeFalling) {
IBlockState above = context.get(x, y + 1, z);
if (above.getBlock() instanceof BlockFalling) {
@@ -20,7 +20,6 @@ package baritone.pathing.movement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.Rotation;
import baritone.api.utils.input.Input;
import net.minecraft.util.math.Vec3d;
import java.util.HashMap;
import java.util.Map;
@@ -29,7 +28,6 @@ import java.util.Optional;
public class MovementState {
private MovementStatus status;
private MovementTarget goal = new MovementTarget();
private MovementTarget target = new MovementTarget();
private final Map<Input, Boolean> inputState = new HashMap<>();
@@ -42,15 +40,6 @@ public class MovementState {
return status;
}
public MovementTarget getGoal() {
return this.goal;
}
public MovementState setGoal(MovementTarget goal) {
this.goal = goal;
return this;
}
public MovementTarget getTarget() {
return this.target;
}
@@ -65,23 +54,12 @@ public class MovementState {
return this;
}
public boolean getInput(Input input) {
return this.inputState.getOrDefault(input, false);
}
public Map<Input, Boolean> getInputStates() {
return this.inputState;
}
public static class MovementTarget {
/**
* Necessary movement to achieve
* <p>
* TODO: Decide desiredMovement type
*/
public Vec3d position;
/**
* Yaw and pitch angles that must be matched
*/
@@ -95,27 +73,14 @@ public class MovementState {
private boolean forceRotations;
public MovementTarget() {
this(null, null, false);
}
public MovementTarget(Vec3d position) {
this(position, null, false);
this(null, false);
}
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.forceRotations = forceRotations;
}
public final Optional<Vec3d> getPosition() {
return Optional.ofNullable(this.position);
}
public final Optional<Rotation> getRotation() {
return Optional.ofNullable(this.rotation);
}
@@ -52,18 +52,18 @@ public class MovementAscend extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
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) {
IBlockState toPlace = context.get(destX, y, destZ);
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)) {
return COST_INF;
}
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi())) {
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi)) {
return COST_INF;
}
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
continue;
}
if (MovementHelper.canPlaceAgainst(context.bsi(), againstX, againstY, againstZ)) {
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
hasToPlace = true;
break;
}
@@ -83,7 +83,7 @@ public class MovementAscend extends Movement {
}
}
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
// 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
@@ -115,23 +115,23 @@ public class MovementAscend extends Movement {
if (jumpingToBottomSlab) {
if (jumpingFromBottomSlab) {
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST); // we hit space immediately on entering this action
walk += context.jumpPenalty;
} else {
walk = WALK_ONE_BLOCK_COST; // we don't hit space we just walk into the slab
}
} else {
// jumpingFromBottomSlab must be false
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
walk = WALK_ONE_OVER_SOUL_SAND_COST;
} else {
walk = WALK_ONE_BLOCK_COST;
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST);
}
walk += context.jumpPenalty;
}
// cracks knuckles
double totalCost = 0;
totalCost += walk;
double totalCost = walk;
if (hasToPlace) {
totalCost += context.placeBlockCost();
totalCost += context.placeBlockCost;
}
// 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
@@ -52,7 +52,7 @@ public class MovementDescend extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
MutableMoveResult result = new MutableMoveResult();
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
if (result.y != dest.y) {
@@ -93,7 +93,7 @@ public class MovementDescend extends Movement {
//C, D, etc determine the length of the fall
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);
return;
}
@@ -122,7 +122,7 @@ public class MovementDescend extends Movement {
// and potentially replace the water we're going to fall into
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;
}
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) {
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
if (context.assumeWalkOnWater()) {
if (context.assumeWalkOnWater) {
return false; // TODO fix
}
if (MovementHelper.isFlowing(ontoBlock)) {
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
return false;
}
@@ -168,23 +168,23 @@ public class MovementDescend extends Movement {
effectiveStartHeight = newY;
continue;
}
if (MovementHelper.canWalkThrough(context.bsi(), destX, newY, destZ, ontoBlock)) {
if (MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
continue;
}
if (!MovementHelper.canWalkOn(context.bsi(), destX, newY, destZ, ontoBlock)) {
if (!MovementHelper.canWalkOn(context.bsi, destX, newY, destZ, ontoBlock)) {
return false;
}
if (MovementHelper.isBottomSlab(ontoBlock)) {
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.y = newY + 1;// this is the block we're falling onto, so dest is +1
res.z = destZ;
res.cost = tentativeCost + context.placeBlockCost();
res.cost = tentativeCost + context.placeBlockCost;
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
res.x = destX;
res.y = newY + 1;
@@ -54,7 +54,7 @@ public class MovementDiagonal extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
MutableMoveResult result = new MutableMoveResult();
cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
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) {
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;
}
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
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;
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;
}
}
@@ -80,6 +80,8 @@ public class MovementDiagonal extends Movement {
// For either possible soul sand, that affects half of our walking
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
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();
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
@@ -131,7 +133,7 @@ public class MovementDiagonal extends Movement {
// Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
multiplier = context.waterWalkSpeed();
multiplier = context.waterWalkSpeed;
water = true;
}
if (optionA != 0 || optionB != 0) {
@@ -142,7 +144,7 @@ public class MovementDiagonal extends Movement {
}
} else {
// 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
// We can sprint =D
// Don't check for soul sand, since we can sprint on that too
@@ -43,12 +43,12 @@ public class MovementDownward extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
return cost(context, src.x, src.y, src.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;
}
IBlockState down = context.get(x, y - 1, z);
@@ -54,7 +54,7 @@ public class MovementFall extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
MutableMoveResult result = new MutableMoveResult();
MovementDescend.cost(context, src.x, src.y, src.z, dest.x, dest.z, result);
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) {
if (!context.allowParkour()) {
if (!context.allowParkour) {
return;
}
if (y == 256 && !context.allowJumpAt256()) {
if (y == 256 && !context.allowJumpAt256) {
return;
}
@@ -74,7 +74,7 @@ public class MovementParkour extends Movement {
return;
}
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
return;
}
@@ -98,7 +98,7 @@ public class MovementParkour extends Movement {
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
maxJump = 2; // 1 block gap
} else {
if (context.canSprint()) {
if (context.canSprint) {
maxJump = 4;
} else {
maxJump = 3;
@@ -111,18 +111,18 @@ public class MovementParkour extends Movement {
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.y = y;
res.z = z + zDiff * i;
res.cost = costFromJumpDistance(i);
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
return;
}
}
if (maxJump != 4) {
return;
}
if (!context.allowParkourPlace()) {
if (!context.allowParkourPlace) {
return;
}
int destX = x + 4 * xDiff;
@@ -131,7 +131,7 @@ public class MovementParkour extends Movement {
return;
}
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;
}
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
continue;
}
if (MovementHelper.canPlaceAgainst(context.bsi(), againstX, againstY, againstZ)) {
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
res.x = destX;
res.y = y;
res.z = destZ;
res.cost = costFromJumpDistance(4) + context.placeBlockCost();
res.cost = costFromJumpDistance(4) + context.placeBlockCost + context.jumpPenalty;
return;
}
}
@@ -166,7 +166,7 @@ public class MovementParkour extends Movement {
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
MutableMoveResult res = new MutableMoveResult();
cost(context, src.x, src.y, src.z, direction, res);
if (res.x != dest.x || res.z != dest.z) {
@@ -42,7 +42,7 @@ public class MovementPillar extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
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
}
}
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;
}
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
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
// 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
@@ -112,7 +112,7 @@ public class MovementPillar extends Movement {
if (ladder) {
return LADDER_UP_ONE_COST + hardness * 5;
} 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;
}
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
boolean vine = fromDown.getBlock() instanceof BlockVine;
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
boolean vine = fromDown.getBlock() == Blocks.VINE;
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(positionToPlace),
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.MovementState;
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.init.Blocks;
import net.minecraft.util.EnumFacing;
@@ -57,7 +60,7 @@ public class MovementTraverse extends Movement {
}
@Override
protected double calculateCost(CalculationContext context) {
public double calculateCost(CalculationContext context) {
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 destOn = context.get(destX, y - 1, destZ);
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;
boolean water = false;
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
WC = context.waterWalkSpeed();
WC = context.waterWalkSpeed;
water = true;
} else {
if (destOn.getBlock() == Blocks.SOUL_SAND) {
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) {
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
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
// We can sprint =D
// 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) {
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());
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
@@ -117,7 +122,7 @@ public class MovementTraverse extends Movement {
return COST_INF;
}
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++) {
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();
@@ -125,8 +130,8 @@ public class MovementTraverse extends Movement {
if (againstX == x && againstZ == z) { // this would be a backplace
continue;
}
if (MovementHelper.canPlaceAgainst(context.bsi(), againstX, againstY, againstZ)) { // found a side place option
return WC + context.placeBlockCost() + hardness1 + hardness2;
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) { // found a side place option
return WC + context.placeBlockCost + hardness1 + hardness2;
}
}
// 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) {
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
return WC + context.placeBlockCost() + hardness1 + hardness2;
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 COST_INF;
}
@@ -181,7 +186,7 @@ public class MovementTraverse extends Movement {
state.setInput(Input.SNEAK, false);
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 pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
@@ -234,7 +239,7 @@ public class MovementTraverse extends Movement {
state.setInput(Input.SPRINT, true);
}
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
return state;
}
@@ -110,7 +110,6 @@ public class PathExecutor implements IPathExecutor, Helper {
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
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))) {
@@ -374,14 +373,15 @@ public class PathExecutor implements IPathExecutor, Helper {
private void sprintIfRequested() {
// 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);
ctx.player().setSprinting(false);
return;
}
// 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()) {
ctx.player().setSprinting(true);
}
@@ -57,7 +57,6 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
}
private Goal towards(Entity following) {
// lol this is trashy but it works
BlockPos pos;
if (Baritone.settings().followOffsetDistance.get() == 0) {
pos = new BlockPos(following);
@@ -79,7 +78,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
if (entity.equals(ctx.player())) {
return false;
}
return ctx.world().loadedEntityList.contains(entity) || ctx.world().playerEntities.contains(entity);
return ctx.world().loadedEntityList.contains(entity);
}
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;
}
}
}
@@ -39,7 +39,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
import java.util.stream.Collectors;
@@ -210,7 +209,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
//long b = System.currentTimeMillis();
for (Block m : mining) {
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 {
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) {
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world());
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
List<BlockPos> locs = locs2
.stream()
.distinct()
// 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)
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi(), pos))
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi, pos))
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
.collect(Collectors.toList());
@@ -32,6 +32,15 @@ import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
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 static final BaritoneAutoTest INSTANCE = new BaritoneAutoTest();
@@ -23,16 +23,10 @@ import baritone.api.utils.IPlayerContext;
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
public static final double DEFAULT_PRIORITY = 0;
protected final Baritone baritone;
protected final IPlayerContext ctx;
private final double priority;
public BaritoneProcessHelper(Baritone baritone) {
this(baritone, DEFAULT_PRIORITY);
}
public BaritoneProcessHelper(Baritone baritone, double priority) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
@@ -17,8 +17,6 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.utils.IPlayerContext;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
@@ -31,11 +29,6 @@ import net.minecraft.util.math.RayTraceResult;
*/
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 IPlayerContext playerContext;
@@ -45,42 +38,20 @@ public final class BlockBreakHelper implements Helper {
}
public void tryBreakBlock(BlockPos pos, EnumFacing side) {
if (!pos.equals(lastBlock)) {
playerContext.playerController().clickBlock(pos, side);
}
if (playerContext.playerController().onPlayerDamageBlock(pos, side)) {
playerContext.player().swingArm(EnumHand.MAIN_HAND);
}
lastBlock = pos;
}
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();
}
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();
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
@@ -91,6 +62,5 @@ public final class BlockBreakHelper implements Helper {
stopBreakingBlock();
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 static int numBlockStateLookups = 0;
public static int numTimesChunkSucceeded = 0;
private final Long2ObjectMap<Chunk> loadedChunks;
private final WorldData worldData;
private Chunk prev = null;
private CachedRegion prevCached = null;
private final boolean useTheRealWorld;
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
public BlockStateInterface(IPlayerContext ctx) {
@@ -64,6 +67,7 @@ public class BlockStateInterface {
} else {
this.loadedChunks = worldLoaded; // this will only be used on the main thread
}
this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.get();
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
throw new IllegalStateException();
}
@@ -88,13 +92,13 @@ public class BlockStateInterface {
}
public IBlockState get0(int x, int y, int z) { // Mickey resigned
numBlockStateLookups++;
// Invalid vertical position
if (y < 0 || y >= 256) {
return AIR;
}
if (!Baritone.settings().pathThroughCachedOnly.get()) {
if (useTheRealWorld) {
Chunk cached = prev;
// there's great cache locality in block state lookups
// generally it's within each movement
@@ -103,6 +107,7 @@ public class BlockStateInterface {
// which is a Long2ObjectOpenHashMap.get
// see issue #113
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
numTimesChunkSucceeded++;
return cached.getBlockState(x, y, z);
}
Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
@@ -18,12 +18,15 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.input.Input;
import baritone.behavior.Behavior;
import net.minecraft.client.Minecraft;
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.Map;
@@ -57,8 +60,18 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
* @return Whether or not it is being forced down
*/
@Override
public final boolean isInputForcedDown(KeyBinding key) {
return isInputForcedDown(Input.getInputForBind(key));
public final Boolean isInputForcedDown(KeyBinding 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();
}
@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
public final void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
boolean stillClick = blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
setInputForceState(Input.CLICK_LEFT, stillClick);
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
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() {
@@ -29,7 +29,7 @@ import baritone.pathing.path.PathExecutor;
import net.minecraft.util.math.BlockPos;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class PathingControlManager implements IPathingControlManager {
private final Baritone baritone;
@@ -64,8 +64,7 @@ public class PathingControlManager implements IPathingControlManager {
command = null;
for (IBaritoneProcess proc : processes) {
proc.onLostControl();
if (proc.isActive() && !proc.isTemporary()) { // it's okay for a temporary thing (like combat pause) to maintain control even if you say to cancel
// but not for a non temporary thing
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
throw new IllegalStateException(proc.displayName());
}
}
@@ -83,11 +82,12 @@ public class PathingControlManager implements IPathingControlManager {
public void preTick() {
inControlLastTick = inControlThisTick;
command = doTheStuff();
PathingBehavior p = baritone.getPathingBehavior();
command = executeProcesses();
if (command == null) {
p.cancelSegmentIfSafe();
return;
}
PathingBehavior p = baritone.getPathingBehavior();
switch (command.commandType) {
case REQUEST_PAUSE:
p.requestPause();
@@ -170,32 +170,30 @@ public class PathingControlManager implements IPathingControlManager {
}
public PathingCommand doTheStuff() {
List<IBaritoneProcess> inContention = processes.stream().filter(IBaritoneProcess::isActive).sorted(Comparator.comparingDouble(IBaritoneProcess::priority)).collect(Collectors.toList());
boolean found = false;
boolean cancelOthers = false;
PathingCommand exec = null;
for (int i = inContention.size() - 1; i >= 0; i--) { // truly a gamer moment
IBaritoneProcess proc = inContention.get(i);
if (found) {
if (cancelOthers) {
proc.onLostControl();
public PathingCommand executeProcesses() {
Stream<IBaritoneProcess> inContention = processes.stream()
.filter(IBaritoneProcess::isActive)
.sorted(Comparator.comparingDouble(IBaritoneProcess::priority).reversed());
Iterator<IBaritoneProcess> iterator = inContention.iterator();
while (iterator.hasNext()) {
IBaritoneProcess proc = iterator.next();
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 {
exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
if (exec == null) {
if (proc.isActive()) {
throw new IllegalStateException(proc.displayName());
}
proc.onLostControl();
continue;
}
//System.out.println("Executing command " + exec.commandType + " " + exec.goal + " from " + proc.displayName());
inControlThisTick = proc;
found = true;
cancelOthers = !proc.isTemporary();
if (!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;
}
}
}
+6 -7
View File
@@ -103,7 +103,7 @@ public class ToolSet {
IBlockState blockState = b.getDefaultState();
for (byte i = 0; i < 9; i++) {
ItemStack itemStack = player.inventory.getStackInSlot(i);
double v = calculateStrVsBlock(itemStack, blockState);
double v = calculateSpeedVsBlock(itemStack, blockState);
if (v > value) {
value = v;
best = i;
@@ -128,7 +128,7 @@ public class ToolSet {
*/
private double getBestDestructionTime(Block 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
* @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);
if (hardness < 0) {
return -1;
@@ -154,11 +154,10 @@ public class ToolSet {
speed /= hardness;
if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
speed /= 30;
return speed / 30;
} else {
speed /= 100;
return speed / 100;
}
return speed;
}
/**
@@ -180,7 +179,7 @@ public class ToolSet {
speed *= 0.09;
break;
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;
default:
speed *= 0.00081;
@@ -23,16 +23,12 @@ import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IPlayerContext;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
import java.util.List;
public final class Favoring {
private List<Avoidance> avoidances;
private final Long2DoubleOpenHashMap favorings;
public Favoring(IPlayerContext ctx, IPath previous) {
this(previous);
avoidances = Avoidance.create(ctx);
for (Avoidance avoid : avoidances) {
for (Avoidance avoid : Avoidance.create(ctx)) {
avoid.applySpherical(favorings);
}
System.out.println("Favoring size: " + favorings.size());
@@ -26,7 +26,7 @@ import net.minecraft.util.math.BlockPos;
public abstract class PathBase implements IPath {
@Override
public PathBase cutoffAtLoadedChunks(Object bsi0) {
public PathBase cutoffAtLoadedChunks(Object bsi0) { // <-- cursed cursed cursed
BlockStateInterface bsi = (BlockStateInterface) bsi0;
for (int i = 0; i < positions().size(); i++) {
BlockPos pos = positions().get(i);
@@ -20,9 +20,9 @@ package baritone.utils.player;
import baritone.api.BaritoneAPI;
import baritone.api.cache.IWorldData;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.IPlayerController;
import baritone.utils.Helper;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
@@ -42,8 +42,8 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper {
}
@Override
public PlayerControllerMP playerController() {
return mc.playerController;
public IPlayerController playerController() {
return PrimaryPlayerController.INSTANCE;
}
@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
View File
@@ -44,4 +44,4 @@ public class CachedRegionTest {
}
}
}
}
}
@@ -167,4 +167,4 @@ public class OpenSetsTest {
assertTrue(set.isEmpty());
}
}
}
}
@@ -47,4 +47,4 @@ public class GoalGetToBlockTest {
}
assertTrue(acceptableOffsets.toString(), acceptableOffsets.isEmpty());
}
}
}
@@ -48,4 +48,4 @@ public class ActionCostsTest {
return fallDistance;
}
}
}
@@ -136,4 +136,4 @@ public class BetterBlockPosTest {
long after2 = System.nanoTime() / 1000000L;
System.out.println((after1 - before1) + " " + (after2 - before2));
}
}
}
@@ -29,4 +29,4 @@ public class PathingBlockTypeTest {
assertTrue(type == PathingBlockType.fromBits(bits[0], bits[1]));
}
}
}
}