diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 316d6e47..ebebc4d4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -626,6 +626,12 @@ public final class Settings { */ public final Setting censorRanCommands = new Setting<>(false); + /** + * Always prefer silk touch tools over regular tools. This will not sacrifice speed, but it will always prefer silk + * touch tools over other tools of the same speed. This includes always choosing ANY silk touch tool over your hand. + */ + public final Setting preferSilkTouch = new Setting<>(false); + /** * Don't stop walking forward when you need to break blocks in your way */ diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index b7dd442d..5bd19bc2 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -18,6 +18,7 @@ package baritone.pathing.movement; import baritone.Baritone; +import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.pathing.movement.ActionCosts; import baritone.api.pathing.movement.MovementStatus; @@ -408,7 +409,7 @@ public interface MovementHelper extends ActionCosts, Helper { * @param b the blockstate to mine */ static void switchToBestToolFor(IPlayerContext ctx, IBlockState b) { - switchToBestToolFor(ctx, b, new ToolSet(ctx.player())); + switchToBestToolFor(ctx, b, new ToolSet(ctx.player()), BaritoneAPI.getSettings().preferSilkTouch.value); } /** @@ -418,8 +419,8 @@ public interface MovementHelper extends ActionCosts, Helper { * @param b the blockstate to mine * @param ts previously calculated ToolSet */ - static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts) { - ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock()); + static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts, boolean preferSilkTouch) { + ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock(), preferSilkTouch); } static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) { diff --git a/src/main/java/baritone/utils/ToolSet.java b/src/main/java/baritone/utils/ToolSet.java index 69a5ae9a..353474b2 100644 --- a/src/main/java/baritone/utils/ToolSet.java +++ b/src/main/java/baritone/utils/ToolSet.java @@ -90,30 +90,38 @@ public class ToolSet { } } + public boolean hasSilkTouch(ItemStack stack) { + return EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0; + } + /** * Calculate which tool on the hotbar is best for mining * * @param b the blockstate to be mined * @return A byte containing the index in the tools array that worked best */ - public byte getBestSlot(Block b) { + public byte getBestSlot(Block b, boolean preferSilkTouch) { byte best = 0; - double value = Double.NEGATIVE_INFINITY; - int materialCost = Integer.MIN_VALUE; + double highestSpeed = Double.NEGATIVE_INFINITY; + int lowestCost = Integer.MIN_VALUE; + boolean bestSilkTouch = false; IBlockState blockState = b.getDefaultState(); for (byte i = 0; i < 9; i++) { ItemStack itemStack = player.inventory.getStackInSlot(i); - double v = calculateSpeedVsBlock(itemStack, blockState); - if (v > value) { - value = v; + double speed = calculateSpeedVsBlock(itemStack, blockState); + boolean silkTouch = hasSilkTouch(itemStack); + if (speed > highestSpeed) { + highestSpeed = speed; best = i; - materialCost = getMaterialCost(itemStack); - } else if (v == value) { - int c = getMaterialCost(itemStack); - if (c < materialCost) { - value = v; + lowestCost = getMaterialCost(itemStack); + bestSilkTouch = silkTouch; + } else if (speed == highestSpeed) { + int cost = getMaterialCost(itemStack); + if ((cost < lowestCost && (!preferSilkTouch || (!bestSilkTouch && silkTouch)))) { + highestSpeed = speed; best = i; - materialCost = c; + lowestCost = cost; + bestSilkTouch = silkTouch; } } } @@ -127,7 +135,7 @@ public class ToolSet { * @return A double containing the destruction ticks with the best tool */ private double getBestDestructionTime(Block b) { - ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b)); + ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b, false)); return calculateSpeedVsBlock(stack, b.getDefaultState()) * avoidanceMultiplier(b); }