From f5d110e8f341a5bd2ee65e0bf240dd70049076cf Mon Sep 17 00:00:00 2001 From: noramibuu Date: Wed, 1 Oct 2025 11:59:28 +0300 Subject: [PATCH 1/3] implement -prefer silk touch- to Auto Tool --- .../systems/modules/player/AutoTool.java | 63 +++++++++++++++---- .../systems/modules/world/HighwayBuilder.java | 5 +- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java index fdc6774c86..462ef06454 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java @@ -34,6 +34,7 @@ public class AutoTool extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgWhitelist = settings.createGroup("Whitelist"); + private final SettingGroup sgSilk = settings.createGroup("Silk Touch"); // General @@ -44,13 +45,21 @@ public class AutoTool extends Module { .build() ); - private final Setting silkTouchForEnderChest = sgGeneral.add(new BoolSetting.Builder() - .name("silk-touch-for-ender-chest") - .description("Mines Ender Chests only with the Silk Touch enchantment.") + private final Setting silkTouchEnabled = sgSilk.add(new BoolSetting.Builder() + .name("silk Touch Whitelist") + .description("Require Silk Touch for selected blocks.") .defaultValue(true) .build() ); + private final Setting> silkTouchBlocks = sgSilk.add(new BlockListSetting.Builder() + .name("Whitelist Blocks") + .description("Blocks that should be mined with Silk Touch.") + .defaultValue(Blocks.ENDER_CHEST, Blocks.GLOWSTONE, Blocks.SEA_LANTERN, Blocks.GLASS, Blocks.TURTLE_EGG, Blocks.ICE, Blocks.BLUE_ICE, Blocks.PACKED_ICE) + .visible(silkTouchEnabled::get) + .build() + ); + private final Setting fortuneForOresCrops = sgGeneral.add(new BoolSetting.Builder() .name("fortune-for-ores-and-crops") .description("Mines Ores and crops only with the Fortune enchantment.") @@ -158,13 +167,15 @@ private void onStartBreakingBlock(StartBreakingBlockEvent event) { double bestScore = -1; bestSlot = -1; + boolean enforceSilk = silkTouchEnabled.get() && silkTouchBlocks.get().contains(blockState.getBlock()); + for (int i = 0; i < 9; i++) { ItemStack itemStack = mc.player.getInventory().getStack(i); if (listMode.get() == ListMode.Whitelist && !whitelist.get().contains(itemStack.getItem())) continue; if (listMode.get() == ListMode.Blacklist && blacklist.get().contains(itemStack.getItem())) continue; - double score = getScore(itemStack, blockState, silkTouchForEnderChest.get(), fortuneForOresCrops.get(), prefer.get(), itemStack2 -> !shouldStopUsing(itemStack2)); + double score = getScore(itemStack, blockState, fortuneForOresCrops.get(), prefer.get(), itemStack2 -> !shouldStopUsing(itemStack2), enforceSilk, silkTouchBlocks.get()); if (score < 0) continue; if (score > bestScore) { @@ -173,7 +184,26 @@ private void onStartBreakingBlock(StartBreakingBlockEvent event) { } } - if ((bestSlot != -1 && (bestScore > getScore(currentStack, blockState, silkTouchForEnderChest.get(), fortuneForOresCrops.get(), prefer.get(), itemStack -> !shouldStopUsing(itemStack))) || shouldStopUsing(currentStack) || !isTool(currentStack))) { + // if this is a silk touch target but no silk touch tool exists, + // rerun selection without enforcing silk touch so we still choose a suitable tool + if (bestSlot == -1 && enforceSilk) { + for (int i = 0; i < 9; i++) { + ItemStack itemStack = mc.player.getInventory().getStack(i); + + if (listMode.get() == ListMode.Whitelist && !whitelist.get().contains(itemStack.getItem())) continue; + if (listMode.get() == ListMode.Blacklist && blacklist.get().contains(itemStack.getItem())) continue; + + double score = getScore(itemStack, blockState, fortuneForOresCrops.get(), prefer.get(), itemStack2 -> !shouldStopUsing(itemStack2), false, silkTouchBlocks.get()); + if (score < 0) continue; + + if (score > bestScore) { + bestScore = score; + bestSlot = i; + } + } + } + + if ((bestSlot != -1 && (bestScore > getScore(currentStack, blockState, fortuneForOresCrops.get(), prefer.get(), itemStack -> !shouldStopUsing(itemStack), silkTouchEnabled.get(), silkTouchBlocks.get())) || shouldStopUsing(currentStack) || !isTool(currentStack))) { ticks = switchDelay.get(); if (ticks == 0) InvUtils.swap(bestSlot, true); @@ -193,20 +223,25 @@ private boolean shouldStopUsing(ItemStack itemStack) { return antiBreak.get() && (itemStack.getMaxDamage() - itemStack.getDamage()) < (itemStack.getMaxDamage() * breakDurability.get() / 100); } - public static double getScore(ItemStack itemStack, BlockState state, boolean silkTouchEnderChest, boolean fortuneOre, EnchantPreference enchantPreference, Predicate good) { + public static double getScore(ItemStack itemStack, BlockState state, boolean fortuneOre, EnchantPreference enchantPreference, Predicate good, boolean silkTouchEnabled, List silkBlocks) { if (!good.test(itemStack) || !isTool(itemStack)) return -1; + + boolean isSilkTarget = silkTouchEnabled && silkBlocks.contains(state.getBlock()); + + // for ender chest, only pickaxes are valid tool (silk touch axes will drop ec but extremely slow, so we pass it) + if (state.getBlock() == Blocks.ENDER_CHEST && !itemStack.isIn(ItemTags.PICKAXES)) return -1; + boolean bypassSuitability = isSilkTarget && allowSilkBypass(state); if (!itemStack.isSuitableFor(state) && + !bypassSuitability && !(itemStack.isIn(ItemTags.SWORDS) && (state.getBlock() instanceof BambooBlock || state.getBlock() instanceof BambooShootBlock)) && !(itemStack.getItem() instanceof ShearsItem && state.getBlock() instanceof LeavesBlock || state.isIn(BlockTags.WOOL))) return -1; - if (silkTouchEnderChest - && state.getBlock() == Blocks.ENDER_CHEST - && !Utils.hasEnchantments(itemStack, Enchantments.SILK_TOUCH)) { - return -1; - } + // force usage of silk touch on configured block list + if (isSilkTarget && !Utils.hasEnchantments(itemStack, Enchantments.SILK_TOUCH)) return -1; if (fortuneOre + && !isSilkTarget && isFortunable(state.getBlock()) && !Utils.hasEnchantments(itemStack, Enchantments.FORTUNE)) { return -1; @@ -228,6 +263,12 @@ && isFortunable(state.getBlock()) return score; } + private static boolean allowSilkBypass(BlockState state) { + if (state.isToolRequired()) return false; + if (state.isIn(BlockTags.NEEDS_DIAMOND_TOOL) || state.isIn(BlockTags.NEEDS_IRON_TOOL) || state.isIn(BlockTags.NEEDS_STONE_TOOL)) return false; + return true; + } + public static boolean isTool(Item item) { return isTool(item.getDefaultStack()); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java index fb1b42267d..f8557b61fe 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java @@ -70,6 +70,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; @@ -2092,10 +2093,10 @@ protected int findAndMoveBestToolToHotbar(HighwayBuilder b, BlockState blockStat int bestSlot = -1; for (int i = 0; i < b.mc.player.getInventory().getMainStacks().size(); i++) { - double score = AutoTool.getScore(b.mc.player.getInventory().getStack(i), blockState, false, false, AutoTool.EnchantPreference.None, itemStack -> { + double score = AutoTool.getScore(b.mc.player.getInventory().getStack(i), blockState, false, AutoTool.EnchantPreference.None, itemStack -> { if (noSilkTouch && Utils.hasEnchantment(itemStack, Enchantments.SILK_TOUCH)) return false; return !b.dontBreakTools.get() || itemStack.getMaxDamage() - itemStack.getDamage() > (itemStack.getMaxDamage() * (b.breakDurability.get() / 100)); - }); + }, false, Collections.emptyList()); if (score > bestScore) { bestScore = score; From 9a4a8b49fead71388d7c2e330664b0d0ef31bd8b Mon Sep 17 00:00:00 2001 From: Nora Date: Wed, 1 Oct 2025 21:19:05 +0300 Subject: [PATCH 2/3] Rename settings --- .../meteorclient/systems/modules/player/AutoTool.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java index 462ef06454..f67ebb8d29 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java @@ -46,14 +46,14 @@ public class AutoTool extends Module { ); private final Setting silkTouchEnabled = sgSilk.add(new BoolSetting.Builder() - .name("silk Touch Whitelist") + .name("silk-touch-whitelist") .description("Require Silk Touch for selected blocks.") .defaultValue(true) .build() ); private final Setting> silkTouchBlocks = sgSilk.add(new BlockListSetting.Builder() - .name("Whitelist Blocks") + .name("whitelist-blocks") .description("Blocks that should be mined with Silk Touch.") .defaultValue(Blocks.ENDER_CHEST, Blocks.GLOWSTONE, Blocks.SEA_LANTERN, Blocks.GLASS, Blocks.TURTLE_EGG, Blocks.ICE, Blocks.BLUE_ICE, Blocks.PACKED_ICE) .visible(silkTouchEnabled::get) From 2b9cf7d69b3e251705905fd81210b365fe1e6529 Mon Sep 17 00:00:00 2001 From: noramibuu Date: Wed, 1 Oct 2025 21:48:12 +0300 Subject: [PATCH 3/3] make fortuneForOresCrops actually work for crops --- .../meteorclient/systems/modules/player/AutoTool.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java index 462ef06454..fcd4a4da66 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java @@ -231,6 +231,10 @@ public static double getScore(ItemStack itemStack, BlockState state, boolean for // for ender chest, only pickaxes are valid tool (silk touch axes will drop ec but extremely slow, so we pass it) if (state.getBlock() == Blocks.ENDER_CHEST && !itemStack.isIn(ItemTags.PICKAXES)) return -1; boolean bypassSuitability = isSilkTarget && allowSilkBypass(state); + + // When fortuneForOresCrops is enabled, allow crops to bypass suitability so fortune tools can be considered for crops + if (!bypassSuitability && fortuneOre && (state.getBlock() instanceof CropBlock || state.getBlock() instanceof NetherWartBlock)) bypassSuitability = true; + if (!itemStack.isSuitableFor(state) && !bypassSuitability && !(itemStack.isIn(ItemTags.SWORDS) && (state.getBlock() instanceof BambooBlock || state.getBlock() instanceof BambooShootBlock)) && @@ -260,6 +264,9 @@ && isFortunable(state.getBlock()) if (itemStack.isIn(ItemTags.SWORDS) && (state.getBlock() instanceof BambooBlock || state.getBlock() instanceof BambooShootBlock)) score += 9000 + (itemStack.get(DataComponentTypes.TOOL).getSpeed(state) * 1000); + // Prefer hoes slightly for crops when fortune is enabled and the block is a crop. + if (fortuneOre && (state.getBlock() instanceof CropBlock || state.getBlock() instanceof NetherWartBlock) && itemStack.isIn(ItemTags.HOES)) score += 10; + return score; }