diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java index 1dc5674676..effcf624a7 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java @@ -211,7 +211,7 @@ public void mine(boolean done) { InvUtils.swap(pick.slot(), switchMode.get() == SwitchMode.Silent); if (rotate.get()) Rotations.rotate(Rotations.getYaw(targetPos), Rotations.getPitch(targetPos)); - Direction direction = (mc.player.getY() > targetPos.getY()) ? Direction.UP : Direction.DOWN; + Direction direction = BlockUtils.getDirection(targetPos); if (!done) mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, targetPos, direction)); mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, targetPos, direction)); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java index ca691ea6cd..71dd4fd48e 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java @@ -14,6 +14,7 @@ import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.misc.Pool; +import meteordevelopment.meteorclient.utils.player.Rotations; import meteordevelopment.meteorclient.utils.render.RenderUtils; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import meteordevelopment.meteorclient.utils.world.BlockIterator; @@ -25,7 +26,6 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import java.util.ArrayList; @@ -40,201 +40,208 @@ public class Nuker extends Module { // General private final Setting shape = sgGeneral.add(new EnumSetting.Builder() - .name("shape") - .description("The shape of nuking algorithm.") - .defaultValue(Shape.Sphere) - .build() + .name("shape") + .description("The shape of nuking algorithm.") + .defaultValue(Shape.Sphere) + .build() ); private final Setting mode = sgGeneral.add(new EnumSetting.Builder() - .name("mode") - .description("The way the blocks are broken.") - .defaultValue(Nuker.Mode.Flatten) - .build() + .name("mode") + .description("The way the blocks are broken.") + .defaultValue(Nuker.Mode.Flatten) + .build() ); private final Setting range = sgGeneral.add(new DoubleSetting.Builder() - .name("range") - .description("The break range.") - .defaultValue(4) - .min(0) - .visible(() -> shape.get() != Shape.Cube) - .build() + .name("range") + .description("The break range.") + .defaultValue(4) + .min(0) + .visible(() -> shape.get() != Shape.Cube) + .build() ); private final Setting range_up = sgGeneral.add(new IntSetting.Builder() - .name("up") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("up") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting range_down = sgGeneral.add(new IntSetting.Builder() - .name("down") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("down") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting range_left = sgGeneral.add(new IntSetting.Builder() - .name("left") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("left") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting range_right = sgGeneral.add(new IntSetting.Builder() - .name("right") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("right") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting range_forward = sgGeneral.add(new IntSetting.Builder() - .name("forward") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("forward") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting range_back = sgGeneral.add(new IntSetting.Builder() - .name("back") - .description("The break range.") - .defaultValue(1) - .min(0) - .visible(() -> shape.get() == Shape.Cube) - .build() + .name("back") + .description("The break range.") + .defaultValue(1) + .min(0) + .visible(() -> shape.get() == Shape.Cube) + .build() ); private final Setting delay = sgGeneral.add(new IntSetting.Builder() - .name("delay") - .description("Delay in ticks between breaking blocks.") - .defaultValue(0) - .build() + .name("delay") + .description("Delay in ticks between breaking blocks.") + .defaultValue(0) + .build() ); private final Setting maxBlocksPerTick = sgGeneral.add(new IntSetting.Builder() - .name("max-blocks-per-tick") - .description("Maximum blocks to try to break per tick. Useful when insta mining.") - .defaultValue(1) - .min(1) - .sliderRange(1, 6) - .build() + .name("max-blocks-per-tick") + .description("Maximum blocks to try to break per tick. Useful when insta mining.") + .defaultValue(1) + .min(1) + .sliderRange(1, 6) + .build() ); private final Setting sortMode = sgGeneral.add(new EnumSetting.Builder() - .name("sort-mode") - .description("The blocks you want to mine first.") - .defaultValue(Nuker.SortMode.Closest) - .build() + .name("sort-mode") + .description("The blocks you want to mine first.") + .defaultValue(Nuker.SortMode.Closest) + .build() ); private final Setting swingHand = sgGeneral.add(new BoolSetting.Builder() - .name("swing-hand") - .description("Swing hand client side.") - .defaultValue(true) - .build() + .name("swing-hand") + .description("Swing hand client side.") + .defaultValue(true) + .build() ); private final Setting packetMine = sgGeneral.add(new BoolSetting.Builder() - .name("packet-mine") - .description("Attempt to instamine everything at once.") - .defaultValue(false) - .build() + .name("packet-mine") + .description("Attempt to instamine everything at once.") + .defaultValue(false) + .build() + ); + + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() + .name("rotate") + .description("Rotates server-side to the block being mined.") + .defaultValue(true) + .build() ); // Whitelist and blacklist private final Setting listMode = sgWhitelist.add(new EnumSetting.Builder() - .name("list-mode") - .description("Selection mode.") - .defaultValue(ListMode.Whitelist) - .build() + .name("list-mode") + .description("Selection mode.") + .defaultValue(ListMode.Whitelist) + .build() ); private final Setting> blacklist = sgWhitelist.add(new BlockListSetting.Builder() - .name("blacklist") - .description("The blocks you don't want to mine.") - .visible(() -> listMode.get() == ListMode.Blacklist) - .build() + .name("blacklist") + .description("The blocks you don't want to mine.") + .visible(() -> listMode.get() == ListMode.Blacklist) + .build() ); private final Setting> whitelist = sgWhitelist.add(new BlockListSetting.Builder() - .name("whitelist") - .description("The blocks you want to mine.") - .visible(() -> listMode.get() == ListMode.Whitelist) - .build() + .name("whitelist") + .description("The blocks you want to mine.") + .visible(() -> listMode.get() == ListMode.Whitelist) + .build() ); // Rendering private final Setting enableRenderBounding = sgRender.add(new BoolSetting.Builder() - .name("bounding-box") - .description("Enable rendering bounding box for Cube and Uniform Cube.") - .defaultValue(true) - .build() + .name("bounding-box") + .description("Enable rendering bounding box for Cube and Uniform Cube.") + .defaultValue(true) + .build() ); private final Setting shapeModeBox = sgRender.add(new EnumSetting.Builder() - .name("nuke-box-mode") - .description("How the shape for the bounding box is rendered.") - .defaultValue(ShapeMode.Both) - .build() + .name("nuke-box-mode") + .description("How the shape for the bounding box is rendered.") + .defaultValue(ShapeMode.Both) + .build() ); private final Setting sideColorBox = sgRender.add(new ColorSetting.Builder() - .name("side-color") - .description("The side color of the bounding box.") - .defaultValue(new SettingColor(16,106,144, 100)) - .build() + .name("side-color") + .description("The side color of the bounding box.") + .defaultValue(new SettingColor(16,106,144, 100)) + .build() ); private final Setting lineColorBox = sgRender.add(new ColorSetting.Builder() - .name("line-color") - .description("The line color of the bounding box.") - .defaultValue(new SettingColor(16,106,144, 255)) - .build() + .name("line-color") + .description("The line color of the bounding box.") + .defaultValue(new SettingColor(16,106,144, 255)) + .build() ); private final Setting enableRenderBreaking = sgRender.add(new BoolSetting.Builder() - .name("broken-blocks") - .description("Enable rendering bounding box for Cube and Uniform Cube.") - .defaultValue(true) - .build() + .name("broken-blocks") + .description("Enable rendering bounding box for Cube and Uniform Cube.") + .defaultValue(true) + .build() ); private final Setting shapeModeBreak = sgRender.add(new EnumSetting.Builder() - .name("nuke-block-mode") - .description("How the shapes for broken blocks are rendered.") - .defaultValue(ShapeMode.Both) - .visible(enableRenderBreaking::get) - .build() + .name("nuke-block-mode") + .description("How the shapes for broken blocks are rendered.") + .defaultValue(ShapeMode.Both) + .visible(enableRenderBreaking::get) + .build() ); private final Setting sideColor = sgRender.add(new ColorSetting.Builder() - .name("side-color") - .description("The side color of the target block rendering.") - .defaultValue(new SettingColor(255, 0, 0, 80)) - .visible(enableRenderBreaking::get) - .build() + .name("side-color") + .description("The side color of the target block rendering.") + .defaultValue(new SettingColor(255, 0, 0, 80)) + .visible(enableRenderBreaking::get) + .build() ); private final Setting lineColor = sgRender.add(new ColorSetting.Builder() - .name("line-color") - .description("The line color of the target block rendering.") - .defaultValue(new SettingColor(255, 0, 0, 255)) - .visible(enableRenderBreaking::get) - .build() + .name("line-color") + .description("The line color of the target block rendering.") + .defaultValue(new SettingColor(255, 0, 0, 255)) + .visible(enableRenderBreaking::get) + .build() ); private final Pool blockPosPool = new Pool<>(BlockPos.Mutable::new); @@ -344,9 +351,9 @@ private void onTickPre(TickEvent.Pre event) { boolean toofarCube = !box.contains(Vec3d.ofCenter(blockPos)); if (!BlockUtils.canBreak(blockPos, blockState) - || (toofarSphere && shape.get() == Shape.Sphere) - || (toofarUniformCube && shape.get() == Shape.UniformCube) - || (toofarCube && shape.get() == Shape.Cube)) + || (toofarSphere && shape.get() == Shape.Sphere) + || (toofarUniformCube && shape.get() == Shape.UniformCube) + || (toofarCube && shape.get() == Shape.Cube)) return; // Flatten @@ -366,7 +373,7 @@ private void onTickPre(TickEvent.Pre event) { // Break block if found BlockIterator.after(() -> { // Sort blocks - if (sortMode.get() == SortMode.TopDown) + if (sortMode.get() == SortMode.TopDown) blocks.sort(Comparator.comparingDouble(value -> -1*value.getY())); else if (sortMode.get() != SortMode.None) blocks.sort(Comparator.comparingDouble(value -> Utils.squaredDistance(pX, pY, pZ, value.getX() + 0.5, value.getY() + 0.5, value.getZ() + 0.5) * (sortMode.get() == SortMode.Closest ? 1 : -1))); @@ -399,13 +406,8 @@ else if (sortMode.get() != SortMode.None) boolean canInstaMine = BlockUtils.canInstaBreak(block); - if (packetMine.get()) { - mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, block, Direction.UP)); - mc.player.swingHand(Hand.MAIN_HAND); - mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, block, Direction.UP)); - } else { - BlockUtils.breakBlock(block, swingHand.get()); - } + if (rotate.get()) Rotations.rotate(Rotations.getYaw(block), Rotations.getPitch(block), () -> breakBlock(block)); + else breakBlock(block); if (enableRenderBreaking.get()) RenderUtils.renderTickingBlock(block.toImmutable(), sideColor.get(), lineColor.get(), shapeModeBreak.get(), 0, 8, true, false); lastBlockPos.set(block); @@ -421,7 +423,17 @@ else if (sortMode.get() != SortMode.None) blocks.clear(); }); } - + + private void breakBlock(BlockPos blockPos) { + if (packetMine.get()) { + mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, blockPos, BlockUtils.getDirection(blockPos))); + mc.player.swingHand(Hand.MAIN_HAND); + mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, blockPos, BlockUtils.getDirection(blockPos))); + } else { + BlockUtils.breakBlock(blockPos, swingHand.get()); + } + } + @EventHandler(priority = EventPriority.HIGHEST) private void onBlockBreakingCooldown(BlockBreakingCooldownEvent event) { event.cooldown = 0; diff --git a/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java index 0185036d73..ab6e3c2d89 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java @@ -187,8 +187,8 @@ public static boolean breakBlock(BlockPos blockPos, boolean swing) { BlockPos pos = blockPos instanceof BlockPos.Mutable ? new BlockPos(blockPos) : blockPos; if (mc.interactionManager.isBreakingBlock()) - mc.interactionManager.updateBlockBreakingProgress(pos, Direction.UP); - else mc.interactionManager.attackBlock(pos, Direction.UP); + mc.interactionManager.updateBlockBreakingProgress(pos, getDirection(blockPos)); + else mc.interactionManager.attackBlock(pos, getDirection(blockPos)); if (swing) mc.player.swingHand(Hand.MAIN_HAND); else mc.getNetworkHandler().sendPacket(new HandSwingC2SPacket(Hand.MAIN_HAND)); @@ -265,6 +265,29 @@ public static boolean topSurface(BlockState blockState) { else return blockState.getBlock() instanceof StairsBlock && blockState.get(StairsBlock.HALF) == BlockHalf.TOP; } + // Finds the best block direction to get when interacting with the block. + public static Direction getDirection(BlockPos pos) { + Vec3d eyesPos = new Vec3d(mc.player.getX(), mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()), mc.player.getZ()); + if ((double) pos.getY() > eyesPos.y) { + if (mc.world.getBlockState(pos.add(0, -1, 0)).isReplaceable()) return Direction.DOWN; + else return getOppositeDirection(); + } + if (!mc.world.getBlockState(pos.add(0, 1, 0)).isReplaceable()) return getOppositeDirection(); + return Direction.UP; + } + + // Example: If the player is facing east, then that means they would click the west side of a block. + private static Direction getOppositeDirection() { + return switch (mc.player.getHorizontalFacing()) { + case DOWN -> Direction.UP; + case UP -> Direction.DOWN; + case NORTH -> Direction.SOUTH; + case SOUTH -> Direction.NORTH; + case WEST -> Direction.EAST; + case EAST -> Direction.WEST; + }; + } + public enum MobSpawn { Never, Potential,