diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerAccessor.java b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerAccessor.java index 7df6e86e59..5fa0a26f4a 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerAccessor.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerAccessor.java @@ -15,6 +15,9 @@ public interface ClientPlayerInteractionManagerAccessor { @Accessor("currentBreakingProgress") float getBreakingProgress(); + @Accessor("currentBreakingProgress") + void setCurrentBreakingProgress(float progress); + @Accessor("currentBreakingPos") BlockPos getCurrentBreakingBlockPos(); } diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerMixin.java index 3f316accf5..582f8d62a2 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayerInteractionManagerMixin.java @@ -13,14 +13,17 @@ import meteordevelopment.meteorclient.systems.modules.misc.InventoryTweaks; import meteordevelopment.meteorclient.systems.modules.player.BreakDelay; import meteordevelopment.meteorclient.systems.modules.player.Reach; +import meteordevelopment.meteorclient.systems.modules.player.SpeedMine; import meteordevelopment.meteorclient.utils.player.Rotations; import meteordevelopment.meteorclient.utils.world.BlockUtils; import net.minecraft.block.BlockState; +import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.SlotActionType; @@ -31,6 +34,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -41,6 +45,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; +import static meteordevelopment.meteorclient.MeteorClient.mc; + @Mixin(ClientPlayerInteractionManager.class) public abstract class ClientPlayerInteractionManagerMixin implements IClientPlayerInteractionManager { @Shadow private int blockBreakingCooldown; @@ -50,6 +56,10 @@ public abstract class ClientPlayerInteractionManagerMixin implements IClientPlay @Shadow public abstract void clickSlot(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player); + @Shadow + @Final + private ClientPlayNetworkHandler networkHandler; + @Inject(method = "clickSlot", at = @At("HEAD"), cancellable = true) private void onClickSlot(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo info) { if (actionType == SlotActionType.THROW && slotId >= 0 && slotId < player.currentScreenHandler.slots.size()) { @@ -91,6 +101,19 @@ public void onClickArmorSlot(int syncId, int slotId, int button, SlotActionType @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) private void onAttackBlock(BlockPos blockPos, Direction direction, CallbackInfoReturnable info) { if (MeteorClient.EVENT_BUS.post(StartBreakingBlockEvent.get(blockPos, direction)).isCancelled()) info.cancel(); + else { + SpeedMine sm = Modules.get().get(SpeedMine.class); + BlockState state = mc.world.getBlockState(blockPos); + + if (!sm.instamine() || !sm.filter(state.getBlock())) return; + + if (state.calcBlockBreakingDelta(mc.player, mc.world, blockPos) > 0.5f) { + mc.world.breakBlock(blockPos, true, mc.player); + networkHandler.sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, blockPos, direction)); + networkHandler.sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, blockPos, direction)); + info.setReturnValue(true); + } + } } @Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java index a200916203..fe5ae7271f 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java @@ -6,6 +6,7 @@ package meteordevelopment.meteorclient.systems.modules.player; import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.mixin.ClientPlayerInteractionManagerAccessor; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -13,6 +14,7 @@ import meteordevelopment.orbit.EventHandler; import net.minecraft.block.Block; import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.util.math.BlockPos; import java.util.List; @@ -32,7 +34,7 @@ public class SpeedMine extends Module { .name("blocks") .description("Selected blocks.") .filter(block -> block.getHardness() > 0) - .visible(() -> mode.get() == Mode.Normal) + .visible(() -> mode.get() != Mode.Haste) .build() ); @@ -40,7 +42,7 @@ public class SpeedMine extends Module { .name("blocks-filter") .description("How to use the blocks setting.") .defaultValue(ListMode.Blacklist) - .visible(() -> mode.get() == Mode.Normal) + .visible(() -> mode.get() != Mode.Haste) .build() ); @@ -53,6 +55,24 @@ public class SpeedMine extends Module { .build() ); + private final Setting hasteAmplifier = sgGeneral.add(new IntSetting.Builder() + .name("haste-amplifier") + .description("What value of haste to give you. Above 2 not recommended.") + .defaultValue(2) + .min(1) + .visible(() -> mode.get() == Mode.Haste) + .onChanged(i -> removeHaste()) + .build() + ); + + private final Setting instamine = sgGeneral.add(new BoolSetting.Builder() + .name("instamine") + .description("Whether or not to instantly mine blocks under certain conditions.") + .defaultValue(true) + .visible(() -> mode.get() == Mode.Damage) + .build() + ); + public SpeedMine() { super(Categories.Player, "speed-mine", "Allows you to quickly mine blocks."); } @@ -65,14 +85,22 @@ public void onDeactivate() { @EventHandler private void onTick(TickEvent.Pre event) { if (!Utils.canUpdate()) return; - if (mode.get() == Mode.Normal) return; - - int amplifier = mode.get() == Mode.Haste2 ? 1 : 0; - StatusEffectInstance haste = mc.player.getStatusEffect(HASTE); + if (mode.get() == Mode.Haste) { + StatusEffectInstance haste = mc.player.getStatusEffect(HASTE); - if (haste == null || haste.getAmplifier() <= amplifier) { - mc.player.setStatusEffect(new StatusEffectInstance(HASTE, -1, amplifier, false, false, false), null); + if (haste == null || haste.getAmplifier() <= hasteAmplifier.get() - 1) { + mc.player.setStatusEffect(new StatusEffectInstance(HASTE, -1, hasteAmplifier.get() - 1, false, false, false), null); + } + } + else if (mode.get() == Mode.Damage) { + ClientPlayerInteractionManagerAccessor im = (ClientPlayerInteractionManagerAccessor) mc.interactionManager; + float progress = im.getBreakingProgress(); + BlockPos pos = im.getCurrentBreakingBlockPos(); + + if (pos == null || progress <= 0) return; + if (progress + mc.world.getBlockState(pos).calcBlockBreakingDelta(mc.player, mc.world, pos) >= 0.7f) + im.setCurrentBreakingProgress(1f); } } @@ -88,10 +116,14 @@ public boolean filter(Block block) { return blocksFilter.get() == ListMode.Whitelist && blocks.get().contains(block); } + public boolean instamine() { + return isActive() && mode.get() == Mode.Damage && instamine.get(); + } + public enum Mode { Normal, - Haste1, - Haste2 + Haste, + Damage } public enum ListMode {