From 9b1dc8e4824404fc40193140f229164a5d6acce2 Mon Sep 17 00:00:00 2001 From: RedCarlos26 <58893097+RedCarlos26@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:26:02 -0400 Subject: [PATCH] Updated to latest Meteor --- build.gradle | 2 +- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../modules/main/HighwayBuilderPlus.java | 389 +++++++++++++----- src/main/resources/fabric.mod.json | 2 +- 5 files changed, 287 insertions(+), 112 deletions(-) diff --git a/build.gradle b/build.gradle index 8ff8887..68929ee 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.5-SNAPSHOT' + id 'fabric-loom' version '1.6-SNAPSHOT' } sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17 diff --git a/gradle.properties b/gradle.properties index 99f05c8..4d2420c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,10 @@ org.gradle.jvmargs=-Xmx2G # Fabric Properties (https://fabricmc.net/develop/) minecraft_version=1.20.4 yarn_mappings=1.20.4+build.3 -loader_version=0.15.6 +loader_version=0.15.9 # Mod Properties -mod_version=2.7.1 +mod_version=2.7.2 maven_group=higtools.package archives_base_name=HIGTools diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index db9a6b8..17655d0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/me/redcarlos/higtools/modules/main/HighwayBuilderPlus.java b/src/main/java/me/redcarlos/higtools/modules/main/HighwayBuilderPlus.java index 674fa5e..613ca7b 100644 --- a/src/main/java/me/redcarlos/higtools/modules/main/HighwayBuilderPlus.java +++ b/src/main/java/me/redcarlos/higtools/modules/main/HighwayBuilderPlus.java @@ -16,6 +16,7 @@ import meteordevelopment.meteorclient.systems.modules.player.AutoEat; import meteordevelopment.meteorclient.systems.modules.player.AutoGap; import meteordevelopment.meteorclient.systems.modules.player.AutoTool; +import meteordevelopment.meteorclient.systems.modules.player.InstaMine; import meteordevelopment.meteorclient.utils.misc.HorizontalDirection; import meteordevelopment.meteorclient.utils.misc.MBlockPos; import meteordevelopment.meteorclient.utils.player.CustomPlayerInput; @@ -26,6 +27,7 @@ import meteordevelopment.meteorclient.utils.render.color.SettingColor; import meteordevelopment.meteorclient.utils.world.BlockUtils; import meteordevelopment.meteorclient.utils.world.Dir; +import meteordevelopment.meteorclient.utils.world.TickRate; import meteordevelopment.orbit.EventHandler; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -35,22 +37,24 @@ import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; +import net.minecraft.item.*; +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Hand; -import net.minecraft.util.math.*; +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 net.minecraft.world.EmptyBlockView; import org.jetbrains.annotations.NotNull; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; +@SuppressWarnings("ConstantConditions") public class HighwayBuilderPlus extends Module { public enum Floor { Replace, @@ -63,7 +67,7 @@ public enum Rotation { Place(false, true), Both(true, true); - public boolean mine, place; + public final boolean mine, place; Rotation(boolean mine, boolean place) { this.mine = mine; @@ -74,8 +78,11 @@ public enum Rotation { private static final BlockPos ZERO = new BlockPos(0, 0, 0); private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final SettingGroup sgRenderMine = settings.createGroup("Render Mine"); - private final SettingGroup sgRenderPlace = settings.createGroup("Render Place"); + private final SettingGroup sgDigging = settings.createGroup("Digging"); + private final SettingGroup sgPaving = settings.createGroup("Paving"); + private final SettingGroup sgInventory = settings.createGroup("Inventory"); + private final SettingGroup sgRenderDigging = settings.createGroup("Render Digging"); + private final SettingGroup sgRenderPaving = settings.createGroup("Render Paving"); // General @@ -83,8 +90,8 @@ public enum Rotation { .name("width") .description("Width of the highway.") .defaultValue(4) - .range(2, 6) - .sliderRange(2, 6) + .range(1, 6) + .sliderRange(1, 6) .build() ); @@ -126,96 +133,179 @@ public enum Rotation { .build() ); - private final Setting> blocksToPlace = sgGeneral.add(new BlockListSetting.Builder() - .name("blocks-to-place") - .description("Blocks it is allowed to place.") - .defaultValue(Blocks.OBSIDIAN) - .filter(block -> Block.isShapeFullCube(block.getDefaultState().getCollisionShape(mc.world, ZERO))) + private final Setting disconnectOnToggle = sgGeneral.add(new BoolSetting.Builder() + .name("disconnect-on-toggle") + .description("Automatically disconnects when the module is turned off, for example for not having enough blocks.") + .defaultValue(false) .build() ); - private final Setting> trashItems = sgGeneral.add(new ItemListSetting.Builder() - .name("trash-items") - .description("Items that are considered trash and can be thrown out.") - .defaultValue(Items.NETHERRACK, Items.QUARTZ, Items.GOLD_NUGGET, Items.GLOWSTONE_DUST, Items.BLACKSTONE, Items.BASALT) + private final Setting pauseOnLag = sgGeneral.add(new BoolSetting.Builder() + .name("pause-on-lag") + .description("Pauses the current process while the server stops responding.") + .defaultValue(true) .build() ); - private final Setting dontBreakTools = sgGeneral.add(new BoolSetting.Builder() + // Digging + + private final Setting dontBreakTools = sgDigging.add(new BoolSetting.Builder() .name("dont-break-tools") .description("Don't break tools.") .defaultValue(false) .build() ); - private final Setting mineEnderChests = sgGeneral.add(new BoolSetting.Builder() + private final Setting savePickaxes = sgDigging.add(new IntSetting.Builder() + .name("save-pickaxes") + .description("How many pickaxes to ensure are saved.") + .defaultValue(0) + .range(0, 36) + .sliderRange(0, 36) + .visible(() -> !dontBreakTools.get()) + .build() + ); + + private final Setting breakDelay = sgDigging.add(new IntSetting.Builder() + .name("break-delay") + .description("The delay between breaking blocks.") + .defaultValue(0) + .min(0) + .build() + ); + + private final Setting blocksPerTick = sgDigging.add(new IntSetting.Builder() + .name("blocks-per-tick") + .description("The maximum amount of blocks that can be mined in a tick. Only applies to blocks instantly breakable.") + .defaultValue(1) + .range(1, 100) + .sliderRange(1, 25) + .build() + ); + + // Paving + + private final Setting> blocksToPlace = sgPaving.add(new BlockListSetting.Builder() + .name("blocks-to-place") + .description("Blocks it is allowed to place.") + .defaultValue(Blocks.OBSIDIAN) + .filter(block -> Block.isShapeFullCube(block.getDefaultState().getCollisionShape(EmptyBlockView.INSTANCE, ZERO))) + .build() + ); + + private final Setting placeDelay = sgPaving.add(new IntSetting.Builder() + .name("place-delay") + .description("The delay between placing blocks.") + .defaultValue(0) + .min(0) + .build() + ); + + private final Setting placementsPerTick = sgPaving.add(new IntSetting.Builder() + .name("placements-per-tick") + .description("The maximum amount of blocks that can be placed in a tick.") + .defaultValue(1) + .min(1) + .build() + ); + + // Inventory + + private final Setting> trashItems = sgInventory.add(new ItemListSetting.Builder() + .name("trash-items") + .description("Items that are considered trash and can be thrown out.") + .defaultValue(Items.NETHERRACK, Items.QUARTZ, Items.GOLD_NUGGET, Items.GOLDEN_SWORD, Items.GLOWSTONE_DUST, Items.GLOWSTONE, Items.BLACKSTONE, Items.BASALT, Items.GHAST_TEAR, Items.SOUL_SAND, Items.SOUL_SOIL) + .build() + ); + + private final Setting mineEnderChests = sgInventory.add(new BoolSetting.Builder() .name("mine-ender-chests") .description("Mines ender chests for obsidian.") .defaultValue(true) .build() ); - private final Setting disconnectOnToggle = sgGeneral.add(new BoolSetting.Builder() - .name("disconnect-on-toggle") - .description("Automatically disconnects when the module is turned off, for example for not having enough blocks.") + private final Setting saveEchests = sgInventory.add(new IntSetting.Builder() + .name("save-ender-chests") + .description("How many ender chests to ensure are saved.") + .defaultValue(1) + .range(0, 64) + .sliderRange(0, 64) + .visible(mineEnderChests::get) + .build() + ); + + private final Setting instaMineEchests = sgInventory.add(new BoolSetting.Builder() + .name("instaMine-echests") + .description("Whether or not to use the instamine exploit to break echests.") .defaultValue(false) + .visible(mineEnderChests::get) + .build() + ); + + private final Setting instaMineDelay = sgInventory.add(new IntSetting.Builder() + .name("instaMine-delay") + .description("Delay between instamine attempts.") + .defaultValue(0) + .sliderMax(20) + .visible(() -> mineEnderChests.get() && instaMineEchests.get()) .build() ); - // Render Mine + // Render Digging - private final Setting renderMine = sgRenderMine.add(new BoolSetting.Builder() + private final Setting renderMine = sgRenderDigging.add(new BoolSetting.Builder() .name("render-blocks-to-mine") .description("Render blocks to be mined.") .defaultValue(true) .build() ); - private final Setting renderMineShape = sgRenderMine.add(new EnumSetting.Builder() + private final Setting renderMineShape = sgRenderDigging.add(new EnumSetting.Builder() .name("blocks-to-mine-shape-mode") .description("How the blocks to be mined are rendered.") .defaultValue(ShapeMode.Both) .build() ); - private final Setting renderMineSideColor = sgRenderMine.add(new ColorSetting.Builder() + private final Setting renderMineSideColor = sgRenderDigging.add(new ColorSetting.Builder() .name("blocks-to-mine-side-color") .description("Color of blocks to be mined.") .defaultValue(new SettingColor(225, 25, 25, 25)) .build() ); - private final Setting renderMineLineColor = sgRenderMine.add(new ColorSetting.Builder() + private final Setting renderMineLineColor = sgRenderDigging.add(new ColorSetting.Builder() .name("blocks-to-mine-line-color") .description("Color of blocks to be mined.") .defaultValue(new SettingColor(225, 25, 25)) .build() ); - // Render Place + // Render Paving - private final Setting renderPlace = sgRenderPlace.add(new BoolSetting.Builder() + private final Setting renderPlace = sgRenderPaving.add(new BoolSetting.Builder() .name("render-blocks-to-place") .description("Render blocks to be placed.") .defaultValue(true) .build() ); - private final Setting renderPlaceShape = sgRenderPlace.add(new EnumSetting.Builder() + private final Setting renderPlaceShape = sgRenderPaving.add(new EnumSetting.Builder() .name("blocks-to-place-shape-mode") .description("How the blocks to be placed are rendered.") .defaultValue(ShapeMode.Both) .build() ); - private final Setting renderPlaceSideColor = sgRenderPlace.add(new ColorSetting.Builder() + private final Setting renderPlaceSideColor = sgRenderPaving.add(new ColorSetting.Builder() .name("blocks-to-place-side-color") .description("Color of blocks to be placed.") .defaultValue(new SettingColor(25, 25, 225, 25)) .build() ); - private final Setting renderPlaceLineColor = sgRenderPlace.add(new ColorSetting.Builder() + private final Setting renderPlaceLineColor = sgRenderPaving.add(new ColorSetting.Builder() .name("blocks-to-place-line-color") .description("Color of blocks to be placed.") .defaultValue(new SettingColor(25, 25, 225)) @@ -234,6 +324,7 @@ public enum Rotation { public int blocksBroken, blocksPlaced; private final MBlockPos lastBreakingPos = new MBlockPos(); private boolean displayInfo; + private int placeTimer, breakTimer, count; private final MBlockPos posRender2 = new MBlockPos(); private final MBlockPos posRender3 = new MBlockPos(); @@ -252,7 +343,6 @@ public void onActivate() { mc.player.input = input = new CustomPlayerInput(); state = State.Forward; - lastState = State.Forward; setState(State.Center); blockPosProvider = dir.diagonal ? new DiagonalBlockPosProvider() : new StraightBlockPosProvider(); @@ -260,6 +350,15 @@ public void onActivate() { blocksBroken = blocksPlaced = 0; lastBreakingPos.set(0, 0, 0); displayInfo = true; + + placeTimer = 0; + breakTimer = 0; + count = 0; + + if (blocksPerTick.get() > 1 && rotation.get().mine) warning("With rotations enabled, you can break at most 1 block per tick."); + if (placementsPerTick.get() > 1 && rotation.get().place) warning("With rotations enabled, you can place at most 1 block per tick."); + + if (Modules.get().get(InstaMine.class).isActive()) warning("It's recommended to disable the InstaMine module and instead use 'instamine-echests' to avoid errors."); } @Override @@ -268,8 +367,8 @@ public void onDeactivate() { mc.player.setYaw(dir.yaw); - if (displayInfo && mc.world != null) { - info("Distance travelled:: (highlight)%.0f", PlayerUtils.distanceTo(start)); + if (displayInfo) { + info("Distance: (highlight)%.0f", PlayerUtils.distanceTo(start)); info("Blocks broken: (highlight)%d", blocksBroken); info("Blocks placed: (highlight)%d", blocksPlaced); } @@ -306,7 +405,14 @@ private void onTick(TickEvent.Pre event) { if (Modules.get().get(AutoGap.class).isEating()) return; if (Modules.get().get(HandManager.class).isEating()) return; + if (pauseOnLag.get() && TickRate.INSTANCE.getTimeSinceLastTick() >= 2.0f) return; + + count = 0; + state.tick(this); + + if (breakTimer > 0) breakTimer--; + if (placeTimer > 0) placeTimer--; } @EventHandler @@ -347,7 +453,7 @@ private void render(Render3DEvent event, MBPIterator it, Predicate pr it.restore(); } - event.renderer.box(posRender2.getMcPos(), sideColor, lineColor, shapeMode, excludeDir); + event.renderer.box(posRender2.getBlockPos(), sideColor, lineColor, shapeMode, excludeDir); } } } @@ -365,7 +471,6 @@ private int getWidthLeft() { default -> 0; case 2, 3 -> 1; case 4, 5 -> 2; - case 6 -> 3; }; } @@ -379,11 +484,11 @@ private int getWidthRight() { private boolean canMine(MBlockPos pos, boolean ignoreBlocksToPlace) { BlockState state = pos.getState(); - return BlockUtils.canBreak(pos.getMcPos(), state) && (ignoreBlocksToPlace || !blocksToPlace.get().contains(state.getBlock())); + return BlockUtils.canBreak(pos.getBlockPos(), state) && (ignoreBlocksToPlace || !blocksToPlace.get().contains(state.getBlock())); } private boolean canPlace(MBlockPos pos, boolean liquids) { - return liquids ? !pos.getState().getFluidState().isEmpty() : pos.getState().isAir(); + return liquids ? !pos.getState().getFluidState().isEmpty() : BlockUtils.canPlace(pos.getBlockPos()); } private void disconnect(String message, Object... args) { @@ -394,9 +499,9 @@ private void disconnect(String message, Object... args) { } public MutableText getStatsText() { - MutableText text = Text.literal("%sDistance: %s%.0f\n".formatted(Formatting.GRAY, Formatting.WHITE, mc.player.getPos().distanceTo(start))); - text.append("%sBlocks broken: %s%d\n".formatted(Formatting.GRAY, Formatting.WHITE, blocksBroken)); - text.append("%sBlocks placed: %s%d".formatted(Formatting.GRAY, Formatting.WHITE, blocksPlaced)); + MutableText text = Text.literal(String.format("%sDistance: %s%.0f\n", Formatting.GRAY, Formatting.WHITE, mc.player == null ? 0.0f : PlayerUtils.distanceTo(start))); + text.append(String.format("%sBlocks broken: %s%d\n", Formatting.GRAY, Formatting.WHITE, blocksBroken)); + text.append(String.format("%sBlocks placed: %s%d", Formatting.GRAY, Formatting.WHITE, blocksPlaced)); return text; } @@ -405,15 +510,6 @@ private enum State { Center { @Override protected void tick(HighwayBuilderPlus b) { - double x = MathHelper.floor(b.mc.player.getX()) + 0.5; - double z = MathHelper.floor(b.mc.player.getZ()) + 0.5; - - b.mc.player.setPosition(x, b.mc.player.getY(), z); - b.mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(b.mc.player.getX(), b.mc.player.getY(), b.mc.player.getZ(), b.mc.player.isOnGround())); - b.setState(b.lastState); - - // Todo : test the above to diagnose the bug - /** double x = Math.abs(b.mc.player.getX() - (int) b.mc.player.getX()) - 0.5; double z = Math.abs(b.mc.player.getZ() - (int) b.mc.player.getZ()) - 0.5; @@ -421,6 +517,8 @@ protected void tick(HighwayBuilderPlus b) { boolean isZ = Math.abs(z) <= 0.1; if (isX && isZ) { + b.input.stop(); + b.mc.player.setVelocity(0, 0, 0); b.mc.player.setPosition((int) b.mc.player.getX() + (b.mc.player.getX() < 0 ? -0.5 : 0.5), b.mc.player.getY(), (int) b.mc.player.getZ() + (b.mc.player.getZ() < 0 ? -0.5 : 0.5)); b.setState(b.lastState); } @@ -451,23 +549,32 @@ protected void tick(HighwayBuilderPlus b) { b.input.sneaking = true; } - **/ } }, Forward { @Override - protected void tick(HighwayBuilderPlus b) { + protected void start(HighwayBuilderPlus b) { b.mc.player.setYaw(b.dir.yaw); + + checkTasks(b); + } + + @Override + protected void tick(HighwayBuilderPlus b) { + checkTasks(b); b.mc.player.setPitch(0); + if (b.state == Forward) b.input.pressingForward = true; // Move + } + + private void checkTasks(HighwayBuilderPlus b) { if (needsToPlace(b, b.blockPosProvider.getLiquids(), true)) b.setState(FillLiquids); // Fill Liquids else if (needsToMine(b, b.blockPosProvider.getFront(), true)) b.setState(MineFront); // Mine Front else if (b.floor.get() == Floor.Replace && needsToMine(b, b.blockPosProvider.getFloor(), false)) b.setState(MineFloor); // Mine Floor else if (b.railings.get() && needsToMine(b, b.blockPosProvider.getRailings(true), false)) b.setState(MineRailings); // Mine Railings else if (b.railings.get() && needsToPlace(b, b.blockPosProvider.getRailings(false), false)) b.setState(PlaceRailings); // Place Railings else if (needsToPlace(b, b.blockPosProvider.getFloor(), false)) b.setState(PlaceFloor); // Place Floor - else b.input.pressingForward = true; // Move } private boolean needsToMine(HighwayBuilderPlus b, MBPIterator it, boolean ignoreBlocksToPlace) { @@ -500,31 +607,31 @@ protected void tick(HighwayBuilderPlus b) { MineFront { @Override protected void tick(HighwayBuilderPlus b) { - mine(b, b.blockPosProvider.getFront(), true); + mine(b, b.blockPosProvider.getFront(), true, MineFloor, this); } }, MineFloor { @Override - protected void tick(HighwayBuilderPlus b) { - mine(b, b.blockPosProvider.getFloor(), false); + protected void start(HighwayBuilderPlus b) { + mine(b, b.blockPosProvider.getFloor(), false, MineRailings, this); } - }, - PlaceFloor { @Override protected void tick(HighwayBuilderPlus b) { - int slot = findBlocksToPlace(b); - if (slot == -1) return; - - place(b, b.blockPosProvider.getFloor(), slot, Forward); + mine(b, b.blockPosProvider.getFloor(), false, MineRailings, this); } }, MineRailings { + @Override + protected void start(HighwayBuilderPlus b) { + mine(b, b.blockPosProvider.getRailings(true), false, PlaceRailings, this); + } + @Override protected void tick(HighwayBuilderPlus b) { - mine(b, b.blockPosProvider.getRailings(true), false); + mine(b, b.blockPosProvider.getRailings(true), false, PlaceRailings, this); } }, @@ -538,6 +645,24 @@ protected void tick(HighwayBuilderPlus b) { } }, + PlaceFloor { + @Override + protected void start(HighwayBuilderPlus b) { + int slot = findBlocksToPlace(b); + if (slot == -1) return; + + place(b, b.blockPosProvider.getFloor(), slot, Forward); + } + + @Override + protected void tick(HighwayBuilderPlus b) { + int slot = findBlocksToPlace(b); + if (slot == -1) return; + + place(b, b.blockPosProvider.getFloor(), slot, Forward); + } + }, + ThrowOutTrash { private int skipSlot; private boolean timerEnabled, firstTick; @@ -580,6 +705,11 @@ protected void tick(HighwayBuilderPlus b) { return; } + if (!b.mc.player.currentScreenHandler.getCursorStack().isEmpty()) { + InvUtils.dropHand(); + return; + } + for (int i = 0; i < b.mc.player.getInventory().main.size(); i++) { if (i == skipSlot) continue; @@ -615,13 +745,10 @@ protected void tick(HighwayBuilderPlus b) { MineEnderChests { private static final MBlockPos pos = new MBlockPos(); - private int minimumObsidian; - private boolean first; - private int moveTimer; - + private boolean first, primed; private boolean stopTimerEnabled; - private int stopTimer; + private int stopTimer, moveTimer, instaMineTimer; @Override protected void start(HighwayBuilderPlus b) { @@ -654,6 +781,7 @@ else if (b.lastState == ThrowOutTrash) { moveTimer = 0; stopTimerEnabled = false; + primed = false; } @Override @@ -697,36 +825,56 @@ protected void tick(HighwayBuilderPlus b) { return; } + BlockPos bp = pos.getBlockPos(); + // Check block state - BlockState blockState = b.mc.world.getBlockState(pos.getMcPos()); + BlockState blockState = b.mc.world.getBlockState(bp); if (blockState.getBlock() == Blocks.ENDER_CHEST) { + if (first) { + moveTimer = 8; + first = false; + return; + } + // Mine ender chest - int slot = findAndMoveBestToolToHotbar(b, blockState, true, false); + int slot = findAndMoveBestToolToHotbar(b, blockState, true); if (slot == -1) { b.error("Cannot find pickaxe without silk touch to mine ender chests."); return; } InvUtils.swap(slot, false); - BlockUtils.breakBlock(pos.getMcPos(), true); + + if (b.instaMineEchests.get() && primed) { + if (instaMineTimer > 0) { + instaMineTimer--; + return; + } + + PlayerActionC2SPacket p = new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, bp, BlockUtils.getDirection(bp)); + instaMineTimer = b.instaMineDelay.get(); + + if (b.rotation.get().mine) Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> b.mc.getNetworkHandler().sendPacket(p)); + else b.mc.getNetworkHandler().sendPacket(p); + } + else { + if (b.rotation.get().mine) Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> BlockUtils.breakBlock(bp, true)); + else BlockUtils.breakBlock(bp, true); + } } else { // Place ender chest int slot = findAndMoveToHotbar(b, itemStack -> itemStack.getItem() == Items.ENDER_CHEST, false); - if (slot == -1) { + if (slot == -1 || countItem(b, stack -> stack.getItem().equals(Items.ENDER_CHEST)) <= b.saveEchests.get()) { stopTimerEnabled = true; stopTimer = 4; return; } - if (first) { - moveTimer = 8; - first = false; - } + if (!first) primed = true; - InvUtils.swap(slot, false); - BlockUtils.place(pos.getMcPos(), Hand.MAIN_HAND, slot, b.rotation.get().place, 0, true, false, false); + BlockUtils.place(bp, Hand.MAIN_HAND, slot, b.rotation.get().place, 0, true, true, false); } } }; @@ -737,54 +885,69 @@ protected void start(HighwayBuilderPlus b) {} protected void mine(HighwayBuilderPlus b, MBPIterator it, boolean ignoreBlocksToPlace, State nextState, State lastState) { boolean breaking = false; + boolean finishedBreaking = false; // If you can multi break this lets you mine blocks between tasks in a single tick for (MBlockPos pos : it) { + if (b.count >= b.blocksPerTick.get()) return; + if (b.breakTimer > 0) return; + BlockState state = pos.getState(); if (state.isAir() || (!ignoreBlocksToPlace && b.blocksToPlace.get().contains(state.getBlock()))) continue; - int slot = findAndMoveBestToolToHotbar(b, state, false, true); + int slot = findAndMoveBestToolToHotbar(b, state, false); if (slot == -1) return; InvUtils.swap(slot, false); - BlockPos mcPos = pos.getMcPos(); + BlockPos mcPos = pos.getBlockPos(); if (BlockUtils.canBreak(mcPos)) { - if (b.rotation.get().mine) Rotations.rotate(Rotations.getYaw(mcPos), Rotations.getPitch(mcPos), () -> BlockUtils.breakBlock(pos.getMcPos(), true)); + if (b.rotation.get().mine) Rotations.rotate(Rotations.getYaw(mcPos), Rotations.getPitch(mcPos), () -> BlockUtils.breakBlock(mcPos, true)); else BlockUtils.breakBlock(mcPos, true); - breaking = true; + b.breakTimer = b.breakDelay.get(); + if (!b.lastBreakingPos.equals(pos)) { b.lastBreakingPos.set(pos); b.blocksBroken++; } - break; + b.count++; + + // Can only multi break if we aren't rotating and the block can be instamined + if (b.blocksPerTick.get() == 1 || !BlockUtils.canInstaBreak(mcPos) || b.rotation.get().mine) break; } + + if (!it.hasNext() && BlockUtils.canInstaBreak(mcPos)) finishedBreaking = true; } - if (!breaking) { + if (finishedBreaking || !breaking) { b.setState(nextState); b.lastState = lastState; } } - protected void mine(HighwayBuilderPlus b, MBPIterator it, boolean ignoreBlocksToPlace) { - mine(b, it, ignoreBlocksToPlace, Forward, b.state); - } - protected void place(HighwayBuilderPlus b, MBPIterator it, int slot, State nextState) { boolean placed = false; + boolean finishedPlacing = false; for (MBlockPos pos : it) { - if (BlockUtils.place(pos.getMcPos(), Hand.MAIN_HAND, slot, b.rotation.get().place, 0, true, true, true)) { + if (b.count >= b.placementsPerTick.get()) return; + if (b.placeTimer > 0) return; + + if (BlockUtils.place(pos.getBlockPos(), Hand.MAIN_HAND, slot, b.rotation.get().place, 0, true, true, true)) { placed = true; b.blocksPlaced++; - break; + b.placeTimer = b.placeDelay.get(); + + b.count++; + if (b.placementsPerTick.get() == 1) break; } + + if (!it.hasNext()) finishedPlacing = true; } - if (!placed) b.setState(nextState); + if (finishedPlacing || !placed) b.setState(nextState); } private int findSlot(HighwayBuilderPlus b, Predicate predicate, boolean hotbar) { @@ -844,6 +1007,16 @@ private boolean hasItem(HighwayBuilderPlus b, Item item) { return false; } + protected int countItem(HighwayBuilderPlus b, Predicate predicate) { + int count = 0; + for (int i = 0; i < b.mc.player.getInventory().main.size(); i++) { + ItemStack stack = b.mc.player.getInventory().getStack(i); + if (predicate.test(stack)) count += stack.getCount(); + } + + return count; + } + protected int findAndMoveToHotbar(HighwayBuilderPlus b, Predicate predicate, boolean required) { // Check hotbar int slot = findSlot(b, predicate, true); @@ -872,7 +1045,7 @@ protected int findAndMoveToHotbar(HighwayBuilderPlus b, Predicate pre return hotbarSlot; } - protected int findAndMoveBestToolToHotbar(HighwayBuilderPlus b, BlockState blockState, boolean noSilkTouch, boolean error) { + protected int findAndMoveBestToolToHotbar(HighwayBuilderPlus b, BlockState blockState, boolean noSilkTouch) { // Check for creative if (b.mc.player.isCreative()) return b.mc.player.getInventory().selectedSlot; @@ -892,9 +1065,12 @@ protected int findAndMoveBestToolToHotbar(HighwayBuilderPlus b, BlockState block } } - // Keep same slot if not found - if (bestSlot == -1) { - bestSlot = b.mc.player.getInventory().selectedSlot; + if (bestSlot == -1) return b.mc.player.getInventory().selectedSlot; + + if (b.mc.player.getInventory().getStack(bestSlot).getItem() instanceof PickaxeItem ){ + int count = countItem(b, stack -> stack.getItem() instanceof PickaxeItem); + + if (count <= b.savePickaxes.get()) b.error("Found less than the selected amount of pickaxes required: " + count + "/" + (b.savePickaxes.get() + 1)); } // Check if the tool is already in hotbar @@ -915,13 +1091,10 @@ protected int findBlocksToPlace(HighwayBuilderPlus b) { int slot = findAndMoveToHotbar(b, itemStack -> itemStack.getItem() instanceof BlockItem blockItem && b.blocksToPlace.get().contains(blockItem.getBlock()), false); if (slot == -1) { - if (!b.mineEnderChests.get()) { + if (!b.mineEnderChests.get() || !hasItem(b, Items.ENDER_CHEST) || countItem(b, stack -> stack.getItem().equals(Items.ENDER_CHEST)) <= b.saveEchests.get()) { b.error("Out of blocks to place."); } - else { - if (hasItem(b, Items.ENDER_CHEST)) b.setState(MineEnderChests); - else b.error("Out of blocks to place."); - } + else b.setState(MineEnderChests); return -1; } @@ -1187,12 +1360,13 @@ private MBlockPos get(int i) { default -> pos.offset(dir.opposite()); case 1 -> pos.offset(leftDir); case 2 -> pos.offset(rightDir); + case 3 -> pos.offset(dir, 2); }; } @Override public boolean hasNext() { - return i < 3 && y < 2; + return i < 4 && y < 2; } @Override @@ -1406,7 +1580,7 @@ private int getWidth() { @Override public boolean hasNext() { - if (m && i == 1 && y == height.get() && w == getWidth() - 1) return false; + if (m && i == 1 && y == height.get() && w == getWidth() - 1) return false; return i < 2 && w < getWidth() && y < height.get() + 1; } @@ -1480,12 +1654,13 @@ private MBlockPos get(int i) { default -> pos.offset(dir2); case 1 -> pos.offset(dir2.rotateLeftSkipOne()); case 2 -> pos.offset(dir2.rotateLeftSkipOne().opposite()); + case 3 -> pos.offset(dir2.opposite(), 2); }; } @Override public boolean hasNext() { - return i < 3 && y < 2; + return i < 4 && y < 2; } @Override diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 66c691f..d9ff95f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "name": "HIGTools", "id": "higtools", - "version": "2.7.1", + "version": "2.7.2", "description": "Highway Tools for Meteor Client.", "authors": [ "RedCarlos26",