diff --git a/src/main/java/cloudburst/rejects/modules/AutoTNT.java b/src/main/java/cloudburst/rejects/modules/AutoTNT.java index 2962b93..0c16ac4 100644 --- a/src/main/java/cloudburst/rejects/modules/AutoTNT.java +++ b/src/main/java/cloudburst/rejects/modules/AutoTNT.java @@ -1,20 +1,23 @@ package cloudburst.rejects.modules; import cloudburst.rejects.MeteorRejectsAddon; -import cloudburst.rejects.utils.WorldUtils; -import meteordevelopment.orbit.EventHandler; +import cloudburst.rejects.utils.TntDamage; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.BoolSetting; import meteordevelopment.meteorclient.settings.IntSetting; import meteordevelopment.meteorclient.settings.Setting; import meteordevelopment.meteorclient.settings.SettingGroup; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.misc.Pool; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; +import meteordevelopment.meteorclient.utils.world.BlockIterator; +import meteordevelopment.meteorclient.utils.world.BlockUtils; +import meteordevelopment.orbit.EventHandler; import net.minecraft.block.Blocks; import net.minecraft.item.FlintAndSteelItem; -import net.minecraft.util.ActionResult; +import net.minecraft.item.Items; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; @@ -30,112 +33,169 @@ public class AutoTNT extends Module { // General - private final Setting delay = sgGeneral.add(new IntSetting.Builder() - .name("delay") - .description("Delay in ticks between ignition") - .defaultValue(1) + private final Setting ignite = sgGeneral.add(new BoolSetting.Builder() + .name("ignite") + .description("Whether to ignite tnt.") + .defaultValue(false) .build() ); - private final Setting range = sgGeneral.add(new IntSetting.Builder() - .name("range") - .description("Range of ignition") + private final Setting place = sgGeneral.add(new BoolSetting.Builder() + .name("place") + .description("Whether to place tnt.") + .defaultValue(true) + .build() + ); + + private final Setting igniteDelay = sgGeneral.add(new IntSetting.Builder() + .name("ignition-delay") + .description("Delay in ticks between ignition") + .defaultValue(1) + .visible(ignite::get) + .build() + ); + + private final Setting placeDelay = sgGeneral.add(new IntSetting.Builder() + .name("place-delay") + .description("Delay in ticks between placement") + .defaultValue(1) + .visible(place::get) + .build() + ); + + private final Setting horizontalRange = sgGeneral.add(new IntSetting.Builder() + .name("horizontal-range") + .description("Horizontal range of ignition and placement") .defaultValue(4) .build() ); - private final Setting turnOff = sgGeneral.add(new BoolSetting.Builder() - .name("turn-off") - .description("Turns of after igniting tnt") - .defaultValue(true) + private final Setting verticalRange = sgGeneral.add(new IntSetting.Builder() + .name("vertical-range") + .description("Vertical range of ignition and placement") + .defaultValue(4) .build() ); private final Setting antiBreak = sgGeneral.add(new BoolSetting.Builder() .name("anti-break") - .description("Whether or not to save flint and steel from breaking.") + .description("Whether to save flint and steel from breaking.") .defaultValue(true) .build() ); - private final ArrayList blocks = new ArrayList<>(); - private boolean ignited; - private int ticks = 0; - private int preSlot; - private FindItemResult findSlot; + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() + .name("rotate") + .description("Whether to rotate towards action.") + .defaultValue(true) + .build() + ); + + private final List blocksToIgnite = new ArrayList<>(); + private final List blocksToPlace = new ArrayList<>(); + private final Pool ignitePool = new Pool<>(BlockPos.Mutable::new); + private final Pool placePool = new Pool<>(BlockPos.Mutable::new); + private int igniteTick = 0; + private int placeTick = 0; + private int prevSlot; public AutoTNT() { super(MeteorRejectsAddon.CATEGORY, "auto-tnt", "Ignites TNT for you"); } - @Override - public void onActivate() { - ignited = false; - } - @Override public void onDeactivate() { - ticks = 0; + igniteTick = 0; + placeTick = 0; } @EventHandler - private void onTick(TickEvent.Post event) { - if (ticks <= 0) { + private void onPreTick(TickEvent.Pre event) { + if (ignite.get() && igniteTick > igniteDelay.get()) { + // Clear blocks + for (BlockPos.Mutable blockPos : blocksToIgnite) ignitePool.free(blockPos); + blocksToIgnite.clear(); - // Clear and get tnt blocks - blocks.clear(); - - List searchBlocks = WorldUtils.getSphere(mc.player.getBlockPos(), range.get(), range.get()); - for (BlockPos blockPos : searchBlocks) { - if (mc.world.getBlockState(blockPos).getBlock() == Blocks.TNT) blocks.add(blockPos); - } - - - // If there isn't any tnt - if (blocks.size() <= 0) { - - // If we should just turn off after igniting - if (turnOff.get() && ignited) { - toggle(); - } - - return; - } - - // Sort based on closest tnt - blocks.sort(Comparator.comparingDouble(PlayerUtils::distanceTo)); - - // Get slot - findSlot = getFlintAndSteelSlot(); + // Item check + FindItemResult findSlot = InvUtils.findInHotbar(item -> item.getItem() instanceof FlintAndSteelItem && (antiBreak.get() && (item.getMaxDamage() - item.getDamage()) > 10)); if (!findSlot.found()) { error("No flint and steel in hotbar"); toggle(); return; } + + // Register + BlockIterator.register(horizontalRange.get(), verticalRange.get(), (blockPos, blockState) -> { + if (blockState.getBlock() == Blocks.TNT) blocksToIgnite.add(ignitePool.get().set(blockPos)); + }); + } + + if (place.get() && placeTick > placeDelay.get()) { + // Clear blocks + for (BlockPos.Mutable blockPos : blocksToPlace) placePool.free(blockPos); + blocksToPlace.clear(); - // Ignition - ignite(blocks.get(0), findSlot); + // Item check + FindItemResult findSlot = InvUtils.findInHotbar(item -> item.getItem() == Items.TNT); + if (!findSlot.found()) { + error("No tnt in hotbar"); + toggle(); + return; + } - // Reset ticks - ticks = delay.get(); - } else ticks--; + // Register + BlockIterator.register(horizontalRange.get(), verticalRange.get(), (blockPos, blockState) -> { + if (BlockUtils.canPlace(blockPos)) blocksToPlace.add(placePool.get().set(blockPos)); + }); + } + } + + @EventHandler + private void onPostTick(TickEvent.Post event) { + // Ignition + if (ignite.get() && blocksToIgnite.size() > 0) { + if (igniteTick > igniteDelay.get()) { + // Sort based on closest tnt + blocksToIgnite.sort(Comparator.comparingDouble(PlayerUtils::distanceTo)); + + // Ignition + ignite(blocksToIgnite.get(0), InvUtils.findInHotbar(item -> item.getItem() instanceof FlintAndSteelItem && (antiBreak.get() && (item.getMaxDamage() - item.getDamage()) > 10))); + + // Reset ticks + igniteTick = 0; + } else igniteTick++; + } + + // Placement + if (place.get() && blocksToPlace.size() > 0) { + if (placeTick > placeDelay.get()) { + // Sort based on closest tnt + blocksToPlace.sort((o1, o2) -> { + int s1 = TntDamage.calculate(o1); + int s2 = TntDamage.calculate(o2); + return Integer.compare(s1, s2); + }); + + // Placement + place(blocksToPlace.get(0), InvUtils.findInHotbar(item -> item.getItem() == Items.TNT)); + + // Reset ticks + placeTick = 0; + } else placeTick++; + } } private void ignite(BlockPos pos, FindItemResult item) { // Set slots - preSlot = mc.player.getInventory().selectedSlot; - mc.player.getInventory().selectedSlot = item.getSlot(); + prevSlot = mc.player.getInventory().selectedSlot; + InvUtils.swap(item.getSlot()); - - ActionResult result = mc.interactionManager.interactBlock(mc.player, mc.world, Hand.MAIN_HAND, new BlockHitResult(new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5), Direction.UP, pos, true)); -// ActionResult result = mc.interactionManager.interactBlock(mc.player, mc.world, Hand.MAIN_HAND, new BlockHitResult(new Vec3d(pos.getX(), pos.getY(), pos.getZ()), Direction.UP, pos, false)); - if (result == ActionResult.CONSUME || result == ActionResult.SUCCESS) ignited = true; - - // Reset slot - mc.player.getInventory().selectedSlot = preSlot; + mc.interactionManager.interactBlock(mc.player, mc.world, Hand.MAIN_HAND, new BlockHitResult(new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5), Direction.UP, pos, true)); + + InvUtils.swap(prevSlot); } - private FindItemResult getFlintAndSteelSlot() { - return InvUtils.findInHotbar(item -> item.getItem() instanceof FlintAndSteelItem && (antiBreak.get() && (item.getMaxDamage() - item.getDamage()) > 10)); + private void place(BlockPos pos, FindItemResult item) { + BlockUtils.place(pos, item, rotate.get(), 10); } } diff --git a/src/main/java/cloudburst/rejects/utils/TntDamage.java b/src/main/java/cloudburst/rejects/utils/TntDamage.java new file mode 100644 index 0000000..5c8d143 --- /dev/null +++ b/src/main/java/cloudburst/rejects/utils/TntDamage.java @@ -0,0 +1,37 @@ +package cloudburst.rejects.utils; + +import meteordevelopment.meteorclient.utils.Utils; +import net.minecraft.block.BlockState; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.math.BlockPos; + +import java.util.Optional; + +public class TntDamage { + public static int calculate(BlockPos bp) { + if (!Utils.canUpdate()) return 0; + int score = 0; + + for(int j = -5; j <= 5; ++j) { + for(int k = -5; k <= 5; ++k) { + for(int l = -5; l <= 5; ++l) { + BlockPos blockPos = new BlockPos(j, k, l); + BlockState blockState = Utils.mc.world.getBlockState(blockPos); + FluidState fluidState = Utils.mc.world.getFluidState(blockPos); + + float h = 2.8F; + Optional optional = blockState.isAir() && fluidState.isEmpty() ? Optional.empty() : Optional.of(Math.max(blockState.getBlock().getBlastResistance(), fluidState.getBlastResistance()));; + if (optional.isPresent()) { + h -= (optional.get() + 0.3F) * 0.3F; + } + + if (h > 0.0F) { + score++; + } + } + } + } + + return score; + } +}