diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore index de408ec06..0834b1e85 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ classes/ # Copyright Files !/.idea/copyright/Baritone.xml -!/.idea/copyright/profiles_settings.xml \ No newline at end of file +!/.idea/copyright/profiles_settings.xml diff --git a/README.md b/README.md index 93b114743..71e60aa49 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone) [![Code of Conduct](https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat)](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md) [![Known Vulnerabilities](https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle) -[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues) +[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues) [![Issues](https://img.shields.io/github/issues/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues/) [![GitHub issues-closed](https://img.shields.io/github/issues-closed/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed) [![Pull Requests](https://img.shields.io/github/issues-pr/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/pulls/) @@ -51,7 +51,7 @@ Here are some links to help to get started: # API -The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com/). +The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com). Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release jar. diff --git a/USAGE.md b/USAGE.md index 085f49c20..ce8924a74 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2,24 +2,17 @@ # Prefix -Baritone commands can by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of goal it goes into public chat, which is bad. - -Therefore you can use a prefix before your messages. - -On Baritone v1.1.0 and newer: The prefix is `#` by default. Anything beginning with `#` isn't sent, and is only interpreted by Baritone. -For older than v1.1.0, `#` must be enabled by toggling on the `prefix` setting. - -**Only** in Impact is `.b` also a valid prefix. In 4.4, `#` does **not** work, neither does saying the commands directly in chat. `#` works by default in 4.5 (not 4.4). - -Other clients like Kami and Asuna have their own custom things (like `-path`), and can disable direct chat control entirely. +Baritone's chat control prefix is `#` by default. In Impact, you can also use `.b` as a prefix. (for example, `.b click` instead of `#click`) +Baritone commands can also by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of "goal" it goes into public chat, which is bad, so using `#` is suggested. +To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching). # Commands **All** of these commands may need a prefix before them, as above ^. -`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java#L53). +`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47). To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`. @@ -34,17 +27,20 @@ Some common examples: - `cancel` or `stop` to stop everything - `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part) - `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.) -- `click` to click your destination on the screen. left click to path into it, right click to path on top of it. left click and drag to clear an area. +- `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to clear all blocks from an area. - `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time). - `save waypointName` to save a waypoint. `goto waypointName` to go to it. +- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420). +- `tunnel` to dig just straight ahead and make a tunnel +- `farm` to automatically harvest, replant, or bone meal crops - `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120). +- `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load. - `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start. -- `render` to rerender the world in case `renderCachedChunks` is being glitchy - `version` to get the version of Baritone you're running - `damn` daniel -- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420). -For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java). + +For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java). All the settings and documentation are here. If you find HTML easier to read than Javadoc, you can look here. @@ -54,10 +50,18 @@ There are about a hundred settings, but here are some fun / interesting / import - `allowPlace` - `allowParkour` - `allowParkourPlace` +- `blockPlacementPenalty` - `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer -- `avoidance` +- `avoidance` (avoidance of mobs / mob spawners) - `legitMine` - `followRadius` +- `backfill` (fill in tunnels behind you) +- `buildInLayers` +- `buildRepeatDistance` and `buildRepeatDirection` +- `worldExploringChunkOffset` +- `acceptableThrowawayItems` +- `blocksToAvoidBreaking` + diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index afd6a0db7..031443f4f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -23,7 +23,7 @@ import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.item.Item; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3i; import net.minecraft.util.text.ITextComponent; import java.awt.*; @@ -84,7 +84,7 @@ public final class Settings { /** * Walking on water uses up hunger really quick, so penalize it */ - public final Setting walkOnWaterOnePenalty = new Setting<>(5D); + public final Setting walkOnWaterOnePenalty = new Setting<>(3D); /** * Allow Baritone to fall arbitrary distances and place a water bucket beneath it. @@ -160,9 +160,20 @@ public final class Settings { /** * Blocks that Baritone is not allowed to break */ - public final Setting> blocksToAvoidBreaking = new Setting<>(new ArrayList<>( - // e.g. crafting table, beds - )); + public final Setting> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet? + Blocks.CRAFTING_TABLE, + Blocks.FURNACE, + Blocks.LIT_FURNACE, + Blocks.CHEST, + Blocks.TRAPPED_CHEST + ))); + + /** + * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. + *

+ * I.E. it will never trigger cascading sand / gravel falls + */ + public final Setting avoidUpdatingFallingBlocks = new Setting<>(true); /** * Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real @@ -204,6 +215,13 @@ public final class Settings { */ public final Setting sprintAscends = new Setting<>(true); + /** + * If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway. + *

+ * This helps with speed at >=20m/s + */ + public final Setting overshootTraverse = new Setting<>(true); + /** * When breaking blocks for a movement, wait until all falling blocks have settled before continuing */ @@ -527,6 +545,8 @@ public final class Settings { /** * Exclusively use cached chunks for pathing + *

+ * Never turn this on */ public final Setting pathThroughCachedOnly = new Setting<>(false); @@ -557,7 +577,7 @@ public final class Settings { public final Setting renderCachedChunks = new Setting<>(false); /** - * 0.0f = not visible, fully transparent + * 0.0f = not visible, fully transparent (instead of setting this to 0, turn off renderCachedChunks) * 1.0f = fully opaque */ public final Setting cachedChunksOpacity = new Setting<>(0.5f); @@ -572,6 +592,16 @@ public final class Settings { */ public final Setting walkWhileBreaking = new Setting<>(true); + /** + * When a new segment is calculated that doesn't overlap with the current one, but simply begins where the current segment ends, + * splice it on and make a longer combined path. If this setting is off, any planned segment will not be spliced and will instead + * be the "next path" in PathingBehavior, and will only start after this one ends. Turning this off hurts planning ahead, + * because the next segment will exist even if it's very short. + * + * @see #planningTickLookahead + */ + public final Setting splicePath = new Setting<>(true); + /** * If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful */ @@ -618,7 +648,7 @@ public final class Settings { public final Setting exploreMaintainY = new Setting<>(64); /** - * Replant nether wart + * Replant nether wart while farming */ public final Setting replantNetherWart = new Setting<>(false); @@ -635,14 +665,30 @@ public final class Settings { public final Setting buildInLayers = new Setting<>(false); /** - * How far to move before repeating the build. -1 for the size of the build in that axis. 0 to disable + * false = build from bottom to top + *

+ * true = build from top to bottom */ - public final Setting buildRepeatDistance = new Setting<>(0); + public final Setting layerOrder = new Setting<>(false); /** - * What direction to repeat the build in + * How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely */ - public final Setting buildRepeatDirection = new Setting<>(EnumFacing.NORTH); + public final Setting buildRepeat = new Setting<>(new Vec3i(0, 0, 0)); + + /** + * Allow standing above a block while mining it, in BuilderProcess + *

+ * Experimental + */ + public final Setting breakFromAbove = new Setting<>(false); + + /** + * As well as breaking from above, set a goal to up and to the side of all blocks to break. + *

+ * Never turn this on without also turning on breakFromAbove. + */ + public final Setting goalBreakFromAbove = new Setting<>(false); /** * While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)? @@ -764,6 +810,11 @@ public final class Settings { */ public final Setting> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage); + /** + * The size of the box that is rendered when the current goal is a GoalYLevel + */ + public final Setting yLevelBoxSize = new Setting<>(15D); + /** * The color of the current path */ diff --git a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java index ce54eebb7..9add7176a 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java +++ b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java @@ -29,7 +29,7 @@ public class GoalYLevel implements Goal, ActionCosts { /** * The target Y level */ - private final int level; + public final int level; public GoalYLevel(int level) { this.level = level; diff --git a/src/api/java/baritone/api/utils/BetterBlockPos.java b/src/api/java/baritone/api/utils/BetterBlockPos.java index a1a3cb320..3b94a8339 100644 --- a/src/api/java/baritone/api/utils/BetterBlockPos.java +++ b/src/api/java/baritone/api/utils/BetterBlockPos.java @@ -61,6 +61,8 @@ public final class BetterBlockPos extends BlockPos { } public static long longHash(int x, int y, int z) { + // TODO use the same thing as BlockPos.fromLong(); + // invertibility would be incredibly useful /* * This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name) * diff --git a/src/api/java/baritone/api/utils/ExampleBaritoneControl.java b/src/api/java/baritone/api/utils/ExampleBaritoneControl.java index 715d8edba..295472815 100644 --- a/src/api/java/baritone/api/utils/ExampleBaritoneControl.java +++ b/src/api/java/baritone/api/utils/ExampleBaritoneControl.java @@ -332,7 +332,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener if (suffix.isEmpty()) { // clear the area from the current goal to here Goal goal = baritone.getPathingBehavior().getGoal(); - if (goal == null || !(goal instanceof GoalBlock)) { + if (!(goal instanceof GoalBlock)) { logDirect("Need to specify goal of opposite corner"); return true; } @@ -385,17 +385,6 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener logDirect("farming"); return true; } - // this literally doesn't work, memory is disabled lol - /*if (msg.equals("echest")) { - Optional> contents = baritone.getMemoryBehavior().echest(); - if (contents.isPresent()) { - logDirect("echest contents:"); - log(contents.get()); - } else { - logDirect("echest contents unknown"); - } - return true; - }*/ if (msg.equals("chests")) { for (Map.Entry entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) { logDirect(entry.getKey() + ""); @@ -649,24 +638,6 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener } return true; } - // this is completely impossible from api - /*if (msg.equals("costs")) { - List moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new)); - while (moves.contains(null)) { - moves.remove(null); - } - moves.sort(Comparator.comparingDouble(move -> move.getCost(new CalculationContext(baritone)))); - for (Movement move : moves) { - String[] parts = move.getClass().toString().split("\\."); - double cost = move.getCost(); - String strCost = cost + ""; - if (cost >= ActionCosts.COST_INF) { - strCost = "IMPOSSIBLE"; - } - logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost); - } - return true; - }*/ if (msg.equals("damn")) { logDirect("daniel"); } @@ -688,18 +659,20 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener private Goal parseGoal(String[] params) { Goal goal; try { + BetterBlockPos playerFeet = ctx.playerFeet(); switch (params.length) { case 0: - goal = new GoalBlock(ctx.playerFeet()); + goal = new GoalBlock(playerFeet); break; case 1: - goal = new GoalYLevel(Integer.parseInt(params[0])); + + goal = new GoalYLevel(parseOrDefault(params[0], playerFeet.y)); break; case 2: - goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1])); + goal = new GoalXZ(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.z)); break; case 3: - goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2]))); + goal = new GoalBlock(new BlockPos(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.y), parseOrDefault(params[2], playerFeet.z))); break; default: logDirect("unable to understand lol"); diff --git a/src/api/java/baritone/api/utils/MyChunkPos.java b/src/api/java/baritone/api/utils/MyChunkPos.java index 5748a13dc..1df7481db 100644 --- a/src/api/java/baritone/api/utils/MyChunkPos.java +++ b/src/api/java/baritone/api/utils/MyChunkPos.java @@ -17,11 +17,17 @@ package baritone.api.utils; +import com.google.gson.annotations.SerializedName; + /** * Need a non obfed chunkpos that we can load using GSON */ public class MyChunkPos { + + @SerializedName("x") public int x; + + @SerializedName("y") public int z; @Override diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 8667f554e..5dee6e884 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -21,6 +21,7 @@ import baritone.api.Settings; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3i; import java.awt.*; import java.io.BufferedReader; @@ -29,10 +30,12 @@ import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; import java.util.regex.Matcher; @@ -80,6 +83,8 @@ public class SettingsUtil { ex.printStackTrace(); } }); + } catch (NoSuchFileException ignored) { + System.out.println("Baritone settings file not found, resetting."); } catch (Exception ex) { System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!"); ex.printStackTrace(); @@ -175,6 +180,11 @@ public class SettingsUtil { str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue() ), + VEC3I( + Vec3i.class, + str -> new Vec3i(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), + vec -> vec.getX() + "," + vec.getY() + "," + vec.getZ() + ), BLOCK( Block.class, str -> BlockUtils.stringToBlockRequired(str.trim()), @@ -234,7 +244,9 @@ public class SettingsUtil { @Override public Object parse(ParserContext context, String raw) { - return this.parser.apply(raw); + Object parsed = this.parser.apply(raw); + Objects.requireNonNull(parsed); + return parsed; } @Override diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 03878ee52..684613af1 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -33,7 +33,7 @@ import java.util.OptionalInt; import java.util.Random; import java.util.function.Predicate; -public class InventoryBehavior extends Behavior { +public final class InventoryBehavior extends Behavior { public InventoryBehavior(Baritone baritone) { super(baritone); } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index e0031c8ce..fbe48ad80 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -195,7 +195,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, current.onTick(); return; } - current = current.trySplice(next); + if (Baritone.settings().splicePath.value) { + current = current.trySplice(next); + } if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) { next = null; } diff --git a/src/main/java/baritone/cache/ContainerMemory.java b/src/main/java/baritone/cache/ContainerMemory.java index c1cb7b34d..e79435e3a 100644 --- a/src/main/java/baritone/cache/ContainerMemory.java +++ b/src/main/java/baritone/cache/ContainerMemory.java @@ -29,6 +29,7 @@ import net.minecraft.util.math.BlockPos; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.*; @@ -45,6 +46,8 @@ public class ContainerMemory implements IContainerMemory { this.saveTo = saveTo; try { read(Files.readAllBytes(saveTo)); + } catch (NoSuchFileException ignored) { + inventories.clear(); } catch (Exception ex) { ex.printStackTrace(); inventories.clear(); diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java index c9849caba..be29b988a 100644 --- a/src/main/java/baritone/pathing/movement/Movement.java +++ b/src/main/java/baritone/pathing/movement/Movement.java @@ -32,7 +32,6 @@ import net.minecraft.util.math.BlockPos; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; public abstract class Movement implements IMovement, MovementHelper { diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index c0683d470..d8f6a2f72 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -51,12 +51,27 @@ public interface MovementHelper extends ActionCosts, Helper { return b == Blocks.ICE // ice becomes water, and water can mess up the path || b instanceof BlockSilverfish // obvious reasons // call context.get directly with x,y,z. no need to make 5 new BlockPos for no reason - || bsi.get0(x, y + 1, z).getBlock() instanceof BlockLiquid//don't break anything touching liquid on any side - || bsi.get0(x + 1, y, z).getBlock() instanceof BlockLiquid - || bsi.get0(x - 1, y, z).getBlock() instanceof BlockLiquid - || bsi.get0(x, y, z + 1).getBlock() instanceof BlockLiquid - || bsi.get0(x, y, z - 1).getBlock() instanceof BlockLiquid - || Baritone.settings().blocksToAvoidBreaking.value.contains(b); + || avoidAdjacentBreaking(bsi, x, y + 1, z, true) + || avoidAdjacentBreaking(bsi, x + 1, y, z, false) + || avoidAdjacentBreaking(bsi, x - 1, y, z, false) + || avoidAdjacentBreaking(bsi, x, y, z + 1, false) + || avoidAdjacentBreaking(bsi, x, y, z - 1, false); + } + + static boolean avoidAdjacentBreaking(BlockStateInterface bsi, int x, int y, int z, boolean directlyAbove) { + // returns true if you should avoid breaking a block that's adjacent to this one (e.g. lava that will start flowing if you give it a path) + // this is only called for north, south, east, west, and up. this is NOT called for down. + // we assume that it's ALWAYS okay to break the block thats ABOVE liquid + IBlockState state = bsi.get0(x, y, z); + Block block = state.getBlock(); + if (!directlyAbove // it is fine to mine a block that has a falling block directly above, this (the cost of breaking the stacked fallings) is included in cost calculations + // therefore if directlyAbove is true, we will actually ignore if this is falling + && block instanceof BlockFalling // obviously, this check is only valid for falling blocks + && Baritone.settings().avoidUpdatingFallingBlocks.value // and if the setting is enabled + && BlockFalling.canFallThrough(bsi.get0(x, y - 1, z))) { // and if it would fall (i.e. it's unsupported) + return true; // dont break a block that is adjacent to unsupported gravel because it can cause really weird stuff + } + return block instanceof BlockLiquid; } static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) { @@ -353,6 +368,9 @@ 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 (block instanceof BlockLiquid) { + return COST_INF; + } double mult = context.breakCostMultiplierAt(x, y, z); if (mult >= COST_INF) { return COST_INF; @@ -360,16 +378,11 @@ public interface MovementHelper extends ActionCosts, Helper { 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.toolSet.getStrVsBlock(state); if (strVsBlock <= 0) { return COST_INF; } - - double result = m / strVsBlock; + double result = 1 / strVsBlock; result += context.breakBlockAdditionalCost; result *= mult; if (includeFalling) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 4f7ae7134..a9266f14c 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -36,8 +36,6 @@ import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import java.util.Objects; - public class MovementTraverse extends Movement { /** @@ -230,7 +228,11 @@ public class MovementTraverse extends Movement { } if (isTheBridgeBlockThere) { - if (ctx.playerFeet().equals(dest)) { + BetterBlockPos feet = ctx.playerFeet(); + if (feet.equals(dest)) { + return state.setStatus(MovementStatus.SUCCESS); + } + if (Baritone.settings().overshootTraverse.value && (feet.equals(dest.add(getDirection())) || feet.equals(dest.add(getDirection()).add(getDirection())))) { return state.setStatus(MovementStatus.SUCCESS); } Block low = BlockStateInterface.get(ctx, src).getBlock(); diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index c848f42bd..852ac44ee 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -610,7 +610,7 @@ public class PathExecutor implements IPathExecutor, Helper { ret.costEstimateIndex = costEstimateIndex; ret.ticksOnCurrent = ticksOnCurrent; return ret; - }).orElse(cutIfTooLong()); + }).orElseGet(this::cutIfTooLong); // dont actually call cutIfTooLong every tick if we won't actually use it, use a method reference } private PathExecutor cutIfTooLong() { diff --git a/src/main/java/baritone/process/BackfillProcess.java b/src/main/java/baritone/process/BackfillProcess.java index 8567a049b..65e5692eb 100644 --- a/src/main/java/baritone/process/BackfillProcess.java +++ b/src/main/java/baritone/process/BackfillProcess.java @@ -35,7 +35,7 @@ import net.minecraft.world.chunk.EmptyChunk; import java.util.*; import java.util.stream.Collectors; -public class BackfillProcess extends BaritoneProcessHelper { +public final class BackfillProcess extends BaritoneProcessHelper { public HashMap blocksToReplace = new HashMap<>(); diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 6185b300f..27c1f8856 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -35,6 +35,9 @@ import baritone.utils.BlockStateInterface; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.AirSchematic; import baritone.utils.schematic.Schematic; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import net.minecraft.block.BlockAir; +import net.minecraft.block.BlockLiquid; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemBlock; @@ -49,13 +52,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; import static baritone.api.pathing.movement.ActionCosts.COST_INF; -public class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess { +public final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess { private HashSet incorrectPositions; + private LongOpenHashSet observedCompleted; // positions that are completed even if they're out of render distance and we can't make sure right now private String name; private ISchematic realSchematic; private ISchematic schematic; @@ -76,6 +79,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro this.origin = origin; this.paused = false; this.layer = 0; + this.observedCompleted = new LongOpenHashSet(); } public void resume() { @@ -133,15 +137,18 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return state; } - - public Optional> toBreakNearPlayer(BuilderCalculationContext bcc) { + private Optional> toBreakNearPlayer(BuilderCalculationContext bcc) { BetterBlockPos center = ctx.playerFeet(); + BetterBlockPos pathStart = baritone.getPathingBehavior().pathStart(); for (int dx = -5; dx <= 5; dx++) { - for (int dy = 0; dy <= 5; dy++) { + for (int dy = Baritone.settings().breakFromAbove.value ? -1 : 0; dy <= 5; dy++) { for (int dz = -5; dz <= 5; dz++) { int x = center.x + dx; int y = center.y + dy; int z = center.z + dz; + if (dy == -1 && x == pathStart.x && z == pathStart.z) { + continue; // dont mine what we're supported by, but not directly standing on + } IBlockState desired = bcc.getSchematic(x, y, z); if (desired == null) { continue; // irrelevant @@ -174,7 +181,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } } - public Optional searchForPlacables(BuilderCalculationContext bcc, List desirableOnHotbar) { + private Optional searchForPlacables(BuilderCalculationContext bcc, List desirableOnHotbar) { BetterBlockPos center = ctx.playerFeet(); for (int dx = -5; dx <= 5; dx++) { for (int dy = -5; dy <= 1; dy++) { @@ -203,7 +210,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return Optional.empty(); } - public Optional possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) { + private Optional possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) { for (EnumFacing against : EnumFacing.values()) { BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against); IBlockState placeAgainstState = bsi.get0(placeAgainstPos); @@ -231,8 +238,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return Optional.empty(); } - - public OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) { + private OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) { for (int i = 0; i < 9; i++) { ItemStack stack = ctx.player().inventory.mainInventory.get(i); if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) { @@ -295,12 +301,29 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro if (realSchematic == null) { realSchematic = schematic; } + ISchematic realSchematic = this.realSchematic; // wrap this properly, dont just have the inner class refer to the builderprocess.this + int minYInclusive; + int maxYInclusive; + // layer = 0 should be nothing + // layer = realSchematic.heightY() should be everything + if (Baritone.settings().layerOrder.value) { // top to bottom + maxYInclusive = realSchematic.heightY() - 1; + minYInclusive = realSchematic.heightY() - layer; + } else { + maxYInclusive = layer - 1; + minYInclusive = 0; + } schematic = new ISchematic() { @Override public IBlockState desiredState(int x, int y, int z) { return realSchematic.desiredState(x, y, z); } + @Override + public boolean inSchematic(int x, int y, int z) { + return ISchematic.super.inSchematic(x, y, z) && y >= minYInclusive && y <= maxYInclusive; + } + @Override public int widthX() { return realSchematic.widthX(); @@ -308,7 +331,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro @Override public int heightY() { - return layer; + return realSchematic.heightY(); } @Override @@ -324,20 +347,16 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro layer++; return onTick(calcFailed, isSafeToCancel); } - int distance = Baritone.settings().buildRepeatDistance.value; - EnumFacing direction = Baritone.settings().buildRepeatDirection.value; - if (distance == 0) { + Vec3i repeat = Baritone.settings().buildRepeat.value; + if (repeat.equals(new Vec3i(0, 0, 0))) { logDirect("Done building"); onLostControl(); return null; } // build repeat time - if (distance == -1) { - distance = schematic.size(direction.getAxis()); - } layer = 0; - origin = new BlockPos(origin).offset(direction, distance); - logDirect("Repeating build " + distance + " blocks to the " + direction + ", new origin is " + origin); + origin = new BlockPos(origin).add(repeat); + logDirect("Repeating build in vector " + repeat + ", new origin is " + origin); return onTick(calcFailed, isSafeToCancel); } trim(bcc); @@ -413,7 +432,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc); } - public boolean recalc(BuilderCalculationContext bcc) { + private boolean recalc(BuilderCalculationContext bcc) { if (incorrectPositions == null) { incorrectPositions = new HashSet<>(); fullRecalc(bcc); @@ -428,7 +447,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return !incorrectPositions.isEmpty(); } - public void trim(BuilderCalculationContext bcc) { + private void trim(BuilderCalculationContext bcc) { HashSet copy = new HashSet<>(incorrectPositions); copy.removeIf(pos -> pos.distanceSq(ctx.player().posX, ctx.player().posY, ctx.player().posZ) > 200); if (!copy.isEmpty()) { @@ -436,7 +455,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } } - public void recalcNearby(BuilderCalculationContext bcc) { + private void recalcNearby(BuilderCalculationContext bcc) { BetterBlockPos center = ctx.playerFeet(); for (int dx = -5; dx <= 5; dx++) { for (int dy = -5; dy <= 5; dy++) { @@ -447,10 +466,13 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro IBlockState desired = bcc.getSchematic(x, y, z); if (desired != null) { // we care about this position + BetterBlockPos pos = new BetterBlockPos(x, y, z); if (valid(bcc.bsi.get0(x, y, z), desired)) { - incorrectPositions.remove(new BetterBlockPos(x, y, z)); + incorrectPositions.remove(pos); + observedCompleted.add(BetterBlockPos.longHash(pos)); } else { - incorrectPositions.add(new BetterBlockPos(x, y, z)); + incorrectPositions.add(pos); + observedCompleted.remove(BetterBlockPos.longHash(pos)); } } } @@ -458,13 +480,32 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } } - public void fullRecalc(BuilderCalculationContext bcc) { + private void fullRecalc(BuilderCalculationContext bcc) { incorrectPositions = new HashSet<>(); for (int y = 0; y < schematic.heightY(); y++) { for (int z = 0; z < schematic.lengthZ(); z++) { for (int x = 0; x < schematic.widthX(); x++) { - if (schematic.inSchematic(x, y, z) && !valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) { - incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ())); + if (!schematic.inSchematic(x, y, z)) { + continue; + } + int blockX = x + origin.getX(); + int blockY = y + origin.getY(); + int blockZ = z + origin.getZ(); + if (bcc.bsi.worldContainsLoadedChunk(blockX, blockZ)) { // check if its in render distance, not if its in cache + // we can directly observe this block, it is in render distance + if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z))) { + observedCompleted.add(BetterBlockPos.longHash(blockX, blockY, blockZ)); + } else { + incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ)); + observedCompleted.remove(BetterBlockPos.longHash(blockX, blockY, blockZ)); + } + continue; + } + // this is not in render distance + if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) { + // and we've never seen this position be correct + // therefore mark as incorrect + incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ)); } } } @@ -472,17 +513,45 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } private Goal assemble(BuilderCalculationContext bcc, List approxPlacable) { - List placable = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() == Blocks.AIR && approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))).collect(Collectors.toList()); - Goal[] toBreak = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() != Blocks.AIR).map(GoalBreak::new).toArray(Goal[]::new); - Goal[] toPlace = placable.stream().filter(pos -> !placable.contains(pos.down()) && !placable.contains(pos.down(2))).map(pos -> placementgoal(pos, bcc)).toArray(Goal[]::new); + List placable = new ArrayList<>(); + List breakable = new ArrayList<>(); + List sourceLiquids = new ArrayList<>(); + incorrectPositions.forEach(pos -> { + IBlockState state = bcc.bsi.get0(pos); + if (state.getBlock() instanceof BlockAir) { + if (approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))) { + placable.add(pos); + } + } else { + if (state.getBlock() instanceof BlockLiquid) { + // if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it + // TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks + if (!MovementHelper.possiblyFlowing(state)) { + // if it's a source block then we want to replace it with a throwaway + sourceLiquids.add(pos); + } + } else { + breakable.add(pos); + } + } + }); + List toBreak = new ArrayList<>(); + breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc))); + List toPlace = new ArrayList<>(); + placable.forEach(pos -> { + if (!placable.contains(pos.down()) && !placable.contains(pos.down(2))) { + toPlace.add(placementGoal(pos, bcc)); + } + }); + sourceLiquids.forEach(pos -> toPlace.add(new GoalBlock(pos.up()))); - if (toPlace.length != 0) { - return new JankyGoalComposite(new GoalComposite(toPlace), new GoalComposite(toBreak)); + if (!toPlace.isEmpty()) { + return new JankyGoalComposite(new GoalComposite(toPlace.toArray(new Goal[0])), new GoalComposite(toBreak.toArray(new Goal[0]))); } - if (toBreak.length == 0) { + if (toBreak.isEmpty()) { return null; } - return new GoalComposite(toBreak); + return new GoalComposite(toBreak.toArray(new Goal[0])); } public static class JankyGoalComposite implements Goal { @@ -528,8 +597,8 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } } - public Goal placementgoal(BlockPos pos, BuilderCalculationContext bcc) { - if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) { + private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) { + if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) { // TODO can this even happen? return new GoalPlace(pos); } boolean allowSameLevel = ctx.world().getBlockState(pos.up()).getBlock() != Blocks.AIR; @@ -541,6 +610,21 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return new GoalPlace(pos); } + private Goal breakGoal(BlockPos pos, BuilderCalculationContext bcc) { + if (Baritone.settings().goalBreakFromAbove.value && bcc.bsi.get0(pos.up()).getBlock() instanceof BlockAir && bcc.bsi.get0(pos.up(2)).getBlock() instanceof BlockAir) { // TODO maybe possible without the up(2) check? + return new JankyGoalComposite(new GoalBreak(pos), new GoalGetToBlock(pos.up()) { + @Override + public boolean isInGoal(int x, int y, int z) { + if (y > this.y || (x == this.x && y == this.y && z == this.z)) { + return false; + } + return super.isInGoal(x, y, z); + } + }); + } + return new GoalBreak(pos); + } + public static class GoalAdjacent extends GoalGetToBlock { private boolean allowSameLevel; @@ -587,6 +671,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro realSchematic = null; layer = 0; paused = false; + observedCompleted = null; } @Override @@ -594,7 +679,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return paused ? "Builder Paused" : "Building " + name; } - public List placable(int size) { + private List placable(int size) { List result = new ArrayList<>(); for (int i = 0; i < size; i++) { ItemStack stack = ctx.player().inventory.mainInventory.get(i); @@ -609,7 +694,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro return result; } - public boolean valid(IBlockState current, IBlockState desired) { + private boolean valid(IBlockState current, IBlockState desired) { // TODO more complicated comparison logic I guess return desired == null || current.equals(desired); } diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index 4003b7a7a..b45c7d6f9 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -29,7 +29,7 @@ import baritone.utils.BaritoneProcessHelper; * * @author leijurv */ -public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess { +public final class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess { /** * The current goal diff --git a/src/main/java/baritone/process/ExploreProcess.java b/src/main/java/baritone/process/ExploreProcess.java index 35ddcb841..aa7e2c2a6 100644 --- a/src/main/java/baritone/process/ExploreProcess.java +++ b/src/main/java/baritone/process/ExploreProcess.java @@ -41,7 +41,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -public class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess { +public final class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess { private BlockPos explorationOrigin; diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index ac6d488fa..9593a192b 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -50,7 +50,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Predicate; -public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess { +public final class FarmProcess extends BaritoneProcessHelper implements IFarmProcess { private boolean active; diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 0116df831..4fb4d540e 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -34,7 +34,7 @@ import net.minecraft.util.math.BlockPos; import java.util.*; -public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess { +public final class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess { private Block gettingTo; private List knownLocations; @@ -42,6 +42,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl private BlockPos start; private int tickCount = 0; + private int arrivalTickCount = 0; public GetToBlockProcess(Baritone baritone) { super(baritone); @@ -53,6 +54,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl gettingTo = block; start = ctx.playerFeet(); blacklist = new ArrayList<>(); + arrivalTickCount = 0; rescan(new ArrayList<>(), new CalculationContext(baritone)); } @@ -196,6 +198,10 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl return true; } } + if (arrivalTickCount++ > 20) { + logDirect("Right click timed out"); + return true; + } return false; // trying to right click, will do it next tick or so } } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 6051fe4ae..ca1b3490a 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -88,17 +88,16 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return null; } } - boolean shouldCancel = calcFailed; - if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) { - logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance..."); - knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add); - knownOreLocations.removeIf(blacklist::contains); - shouldCancel = false; // 😎 - } - if (shouldCancel) { - logDirect("Unable to find any path to " + mining + ", canceling Mine"); - cancel(); - return null; + if (calcFailed) { + if (!knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) { + logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance..."); + knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add); + knownOreLocations.removeIf(blacklist::contains); + } else { + logDirect("Unable to find any path to " + mining + ", canceling Mine"); + cancel(); + return null; + } } int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; List curr = new ArrayList<>(knownOreLocations); @@ -111,7 +110,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } Optional shaft = curr.stream() .filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ()) - .filter(pos -> pos.getY() > ctx.playerFeet().getY()) + .filter(pos -> pos.getY() >= ctx.playerFeet().getY()) .filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof BlockAir)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =( .min(Comparator.comparingDouble(ctx.player()::getDistanceSq)); baritone.getInputOverrideHandler().clearAllKeys(); @@ -206,9 +205,16 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro knownOreLocations = locs; } - private static boolean internalMiningGoal(BlockPos pos, IPlayerContext ctx, List locs) { + private boolean internalMiningGoal(BlockPos pos, IPlayerContext ctx, List locs) { // Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of) - return locs.contains(pos) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, pos) instanceof BlockAir); + if (locs.contains(pos)) { + return true; + } + Block block = BlockStateInterface.getBlock(ctx, pos); + if (Baritone.settings().internalMiningAirException.value && block instanceof BlockAir) { + return true; + } + return mining.contains(block); } private Goal coalesce(BlockPos loc, List locs) { @@ -363,7 +369,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro .filter(pos -> !blacklist.contains(pos)) - .sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq)) + .sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().player()::getDistanceSq)) .collect(Collectors.toList()); if (locs.size() > max) { diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index d1afe34d6..88a181470 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -276,13 +276,13 @@ public final class PathRenderer implements Helper { double maxY; double y1; double y2; + double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2)); if (goal instanceof IGoalRenderPos) { BlockPos goalPos = ((IGoalRenderPos) goal).getGoalPos(); minX = goalPos.getX() + 0.002 - renderPosX; maxX = goalPos.getX() + 1 - 0.002 - renderPosX; minZ = goalPos.getZ() + 0.002 - renderPosZ; maxZ = goalPos.getZ() + 1 - 0.002 - renderPosZ; - double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2)); if (goal instanceof GoalGetToBlock || goal instanceof GoalTwoBlocks) { y /= 2; } @@ -341,6 +341,16 @@ public final class PathRenderer implements Helper { drawDankLitGoalBox(player, g, partialTicks, color); } return; + } else if (goal instanceof GoalYLevel) { + GoalYLevel goalpos = (GoalYLevel) goal; + minX = player.posX - Baritone.settings().yLevelBoxSize.value - renderPosX; + minZ = player.posZ - Baritone.settings().yLevelBoxSize.value - renderPosZ; + maxX = player.posX + Baritone.settings().yLevelBoxSize.value - renderPosX; + maxZ = player.posZ + Baritone.settings().yLevelBoxSize.value - renderPosZ; + minY = ((GoalYLevel) goal).level - renderPosY; + maxY = minY + 2; + y1 = 1 + y + goalpos.level - renderPosY; + y2 = 1 - y + goalpos.level - renderPosY; } else { return; } diff --git a/src/main/java/baritone/utils/ToolSet.java b/src/main/java/baritone/utils/ToolSet.java index 31f23f209..69a5ae9a2 100644 --- a/src/main/java/baritone/utils/ToolSet.java +++ b/src/main/java/baritone/utils/ToolSet.java @@ -65,10 +65,10 @@ public class ToolSet { } /** - * Using the best tool on the hotbar, how long would it take to mine this block + * Using the best tool on the hotbar, how fast we can mine this block * * @param state the blockstate to be mined - * @return how long it would take in ticks + * @return the speed of how fast we'll mine it. 1/(time in ticks) */ public double getStrVsBlock(IBlockState state) { return breakStrengthCache.computeIfAbsent(state.getBlock(), backendCalculation); @@ -128,7 +128,11 @@ public class ToolSet { */ private double getBestDestructionTime(Block b) { ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b)); - return calculateSpeedVsBlock(stack, b.getDefaultState()); + return calculateSpeedVsBlock(stack, b.getDefaultState()) * avoidanceMultiplier(b); + } + + private double avoidanceMultiplier(Block b) { + return Baritone.settings().blocksToAvoidBreaking.value.contains(b) ? 0.1 : 1; } /**