From befe3c3bfa1611feda3971a37a5ad4bf7d20e0fa Mon Sep 17 00:00:00 2001 From: Soda <62250232+ThebestkillerTBK@users.noreply.github.com> Date: Sat, 7 Jan 2023 16:30:27 +0800 Subject: [PATCH] Farm stuff (#204) * farm stuff * farm stuff * tech farming * add switches --- README.md | 4 +- .../anticope/rejects/MeteorRejectsAddon.java | 4 +- .../anticope/rejects/modules/AutoFarm.java | 289 ++++++++++++++++++ .../rejects/modules/BonemealAura.java | 109 ------- .../anticope/rejects/modules/MossBot.java | 91 ++++++ .../anticope/rejects/modules/TillAura.java | 209 ------------- .../anticope/rejects/utils/WorldUtils.java | 46 +-- 7 files changed, 410 insertions(+), 342 deletions(-) create mode 100644 src/main/java/anticope/rejects/modules/AutoFarm.java delete mode 100644 src/main/java/anticope/rejects/modules/BonemealAura.java create mode 100644 src/main/java/anticope/rejects/modules/MossBot.java delete mode 100644 src/main/java/anticope/rejects/modules/TillAura.java diff --git a/README.md b/README.md index 0f04c71..1f9f756 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ - AutoBedTrap (Ported from [BleachHack-CupEdition](https://github.com/CUPZYY/BleachHack-CupEdition/blob/master/CupEdition-1.17/src/main/java/bleach/hack/module/mods/AutoBedtrap.java)) - AutoCraft (More generalized version of [AutoBedCraft](https://github.com/Anticope/orion/blob/main/src/main/java/me/ghosttypes/orion/modules/main/AutoBedCraft.java) from orion) - AutoExtinguish +- AutoFarm - AutoGrind - AutoLogin - AutoPot (Taken from an [unmerged PR](https://github.com/MeteorDevelopment/meteor-client/pull/274)) @@ -45,7 +46,6 @@ - AutoTNT - AutoWither (Taken from an [unmerged PR](https://github.com/MeteorDevelopment/meteor-client/pull/1070)) - BlockIn -- BonemealAura (Ported from [JexClient](https://github.com/DustinRepo/JexClient/blob/main/src/main/java/me/dustin/jex/feature/mod/impl/world/BonemealAura.java)) - BoatGlitch & BoatPhase (Taken from an [unmerged PR](https://github.com/MeteorDevelopment/meteor-client/pull/814)) - Boost (Ported from [Cornos](https://github.com/cornos/Cornos/blob/master/src/main/java/me/zeroX150/cornos/features/module/impl/movement/Boost.java)) - ChatBot @@ -62,6 +62,7 @@ - Item generator (Ported from [Wurst](https://github.com/Wurst-Imperium/Wurst7/tree)) - InteractionMenu (Ported from [BleachHack](https://github.com/BleachDrinker420/BleachHack/pull/211)) - Lavacast +- MossBot (Ported from [BleachHack](https://github.com/BleachDrinker420/BleachHack/pull/211)) - NewChunks (Ported from [BleackHack](https://github.com/BleachDrinker420/BleachHack/blob/master/BleachHack-Fabric-1.17/src/main/java/bleach/hack/module/mods/NewChunks.java)) - ObsidianFarm (Taken from [Meteor ObsidianFarm Addon](https://github.com/VoidCyborg/meteor-obsidian-farm)) - Oresim (Ported from [Atomic](https://gitlab.com/0x151/atomic)) @@ -72,7 +73,6 @@ - SkeletonESP (Ported from [JexClient](https://github.com/DustinRepo/JexClient-main/blob/main/src/main/java/me/dustin/jex/feature/mod/impl/render/Skeletons.java)) - SoundLocator - Server Finder (Ported from [MeteorAdditions](https://github.com/JFronny/MeteorAdditions)) -- TillAura (Ported from [Wurst](https://github.com/Wurst-Imperium/Wurst7/tree)) - TreeAura (Taken from an [unmerged PR](https://github.com/MeteorDevelopment/meteor-client/pull/2138)) ### Modifications diff --git a/src/main/java/anticope/rejects/MeteorRejectsAddon.java b/src/main/java/anticope/rejects/MeteorRejectsAddon.java index 6f8791e..2a8c3a9 100644 --- a/src/main/java/anticope/rejects/MeteorRejectsAddon.java +++ b/src/main/java/anticope/rejects/MeteorRejectsAddon.java @@ -39,6 +39,7 @@ public class MeteorRejectsAddon extends MeteorAddon { modules.add(new AutoBedTrap()); modules.add(new AutoCraft()); modules.add(new AutoExtinguish()); + modules.add(new AutoFarm()); modules.add(new AutoGrind()); modules.add(new AutoLogin()); modules.add(new AutoPot()); @@ -48,7 +49,6 @@ public class MeteorRejectsAddon extends MeteorAddon { modules.add(new BoatGlitch()); modules.add(new BlockIn()); modules.add(new BoatPhase()); - modules.add(new BonemealAura()); modules.add(new Boost()); modules.add(new ChatBot()); modules.add(new ChestAura()); @@ -64,6 +64,7 @@ public class MeteorRejectsAddon extends MeteorAddon { modules.add(new ItemGenerator()); modules.add(new InteractionMenu()); modules.add(new Lavacast()); + modules.add(new MossBot()); modules.add(new NewChunks()); modules.add(new ObsidianFarm()); modules.add(new OreSim()); @@ -73,7 +74,6 @@ public class MeteorRejectsAddon extends MeteorAddon { modules.add(new SilentDisconnect()); modules.add(new SkeletonESP()); modules.add(new SoundLocator()); - modules.add(new TillAura()); modules.add(new TreeAura()); // Module modifications diff --git a/src/main/java/anticope/rejects/modules/AutoFarm.java b/src/main/java/anticope/rejects/modules/AutoFarm.java new file mode 100644 index 0000000..9ddf317 --- /dev/null +++ b/src/main/java/anticope/rejects/modules/AutoFarm.java @@ -0,0 +1,289 @@ +package anticope.rejects.modules; + +import anticope.rejects.MeteorRejectsAddon; +import anticope.rejects.utils.WorldUtils; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.meteorclient.utils.misc.Pool; +import meteordevelopment.meteorclient.utils.player.FindItemResult; +import meteordevelopment.meteorclient.utils.player.InvUtils; +import meteordevelopment.meteorclient.utils.world.BlockIterator; +import meteordevelopment.meteorclient.utils.world.BlockUtils; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.block.*; +import net.minecraft.item.HoeItem; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.registry.tag.FluidTags; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.WorldView; + +import java.util.*; + +public class AutoFarm extends Module { + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgTill = settings.createGroup("Till"); + private final SettingGroup sgHarvest = settings.createGroup("Harvest"); + private final SettingGroup sgPlant = settings.createGroup("Plant"); + private final SettingGroup sgBonemeal = settings.createGroup("Bonemeal"); + + private final Map replantMap = new HashMap<>(); + + private final Setting range = sgGeneral.add(new IntSetting.Builder() + .name("range") + .description("Auto farm range.") + .defaultValue(4) + .min(1) + .build() + ); + + private final Setting bpt = sgGeneral.add(new IntSetting.Builder() + .name("blocks-per-tick") + .description("Amount of operations that can be applied in one tick.") + .min(1) + .defaultValue(1) + .build() + ); + + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() + .name("rotate") + .description("Whether or not to rotate towards block.") + .defaultValue(true) + .build() + ); + + private final Setting till = sgTill.add(new BoolSetting.Builder() + .name("till") + .description("Turn nearby dirt into farmland.") + .defaultValue(true) + .build() + ); + + private final Setting moist = sgTill.add(new BoolSetting.Builder() + .name("moist") + .description("Only till moist blocks.") + .defaultValue(true) + .build() + ); + + private final Setting harvest = sgHarvest.add(new BoolSetting.Builder() + .name("harvest") + .description("Harvest crops.") + .defaultValue(true) + .build() + ); + + private final Setting> harvestBlocks = sgHarvest.add(new BlockListSetting.Builder() + .name("harvest-blocks") + .description("Which crops to harvest.") + .defaultValue() + .filter(this::harvestFilter) + .build() + ); + + private final Setting plant = sgPlant.add(new BoolSetting.Builder() + .name("plant") + .description("Plant crops.") + .defaultValue(true) + .build() + ); + + private final Setting> plantItems = sgPlant.add(new ItemListSetting.Builder() + .name("plant-items") + .description("Which crops to plant.") + .defaultValue() + .filter(this::plantFilter) + .build() + ); + + private final Setting onlyReplant = sgPlant.add(new BoolSetting.Builder() + .name("only-replant") + .description("Only replant planted crops.") + .defaultValue(true) + .onChanged(b -> replantMap.clear()) + .build() + ); + + private final Setting bonemeal = sgBonemeal.add(new BoolSetting.Builder() + .name("bonemeal") + .description("Bonemeal crops.") + .defaultValue(true) + .build() + ); + + private final Setting> bonemealBlocks = sgBonemeal.add(new BlockListSetting.Builder() + .name("bonemeal-blocks") + .description("Which crops to bonemeal.") + .defaultValue() + .filter(this::bonemealFilter) + .build() + ); + + private final Pool blockPosPool = new Pool<>(BlockPos.Mutable::new); + private final List blocks = new ArrayList<>(); + + int actions = 0; + + public AutoFarm() { + super(MeteorRejectsAddon.CATEGORY, "auto-farm", "All-in-one farm utility."); + } + + @Override + public void onDeactivate() { + replantMap.clear(); + } + + @EventHandler + private void onTick(TickEvent.Pre event) { + actions = 0; + BlockIterator.register(range.get(), range.get(), (pos, state) -> { + if (mc.player.getEyePos().distanceTo(Vec3d.ofCenter(pos)) <= range.get()) + blocks.add(blockPosPool.get().set(pos)); + }); + + BlockIterator.after(() -> { + blocks.sort(Comparator.comparingDouble(value -> mc.player.getEyePos().distanceTo(Vec3d.ofCenter(value)))); + + for (BlockPos pos : blocks) { + BlockState state = mc.world.getBlockState(pos); + Block block = state.getBlock(); + if (till(pos, block) || harvest(pos, block) || plant(pos, block) || bonemeal(pos, state, block)) + actions++; + if (actions >= bpt.get()) break; + } + + for (BlockPos.Mutable blockPos : blocks) blockPosPool.free(blockPos); + blocks.clear(); + + }); + } + + private boolean till(BlockPos pos, Block block) { + if (!till.get()) return false; + boolean moist = !this.moist.get() || isWaterNearby(mc.world, pos); + boolean tillable = block == Blocks.GRASS_BLOCK || + block == Blocks.DIRT_PATH || + block == Blocks.DIRT || + block == Blocks.COARSE_DIRT || + block == Blocks.ROOTED_DIRT; + if (moist && tillable && mc.world.getBlockState(pos.up()).isAir()) { + FindItemResult hoe = InvUtils.findInHotbar(itemStack -> itemStack.getItem() instanceof HoeItem); + return WorldUtils.interact(pos, hoe, rotate.get()); + } + return false; + } + + private boolean harvest(BlockPos pos, Block block) { + if (!harvest.get()) return false; + if (!harvestBlocks.get().contains(block)) return false; + if (block instanceof SweetBerryBushBlock) + mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Utils.vec3d(pos), Direction.UP, pos, false)); + else { + mc.interactionManager.updateBlockBreakingProgress(pos, Direction.UP); + if (onlyReplant.get()) { + Item item = null; + if (block == Blocks.WHEAT) item = Items.WHEAT_SEEDS; + else if (block == Blocks.CARROTS) item = Items.CARROT; + else if (block == Blocks.POTATOES) item = Items.POTATO; + else if (block == Blocks.BEETROOTS) item = Items.BEETROOT_SEEDS; + else if (block == Blocks.NETHER_WART) item = Items.NETHER_WART; + if (item != null) replantMap.put(pos, item); + } + } + return true; + } + + private boolean plant(BlockPos pos, Block block) { + if (!plant.get()) return false; + if (!mc.world.isAir(pos.up())) return false; + FindItemResult findItemResult = null; + if (onlyReplant.get()) { + for (BlockPos replantPos : replantMap.keySet()) { + if (replantPos.equals(pos.up())) { + findItemResult = InvUtils.find(replantMap.get(replantPos)); + replantMap.remove(replantPos); + break; + } + } + } else if (block instanceof FarmlandBlock) { + findItemResult = InvUtils.find(itemStack -> { + Item item = itemStack.getItem(); + return item != Items.NETHER_WART && plantItems.get().contains(item); + }); + } else if (block instanceof SoulSandBlock) { + findItemResult = InvUtils.find(itemStack -> { + Item item = itemStack.getItem(); + return item == Items.NETHER_WART && plantItems.get().contains(Items.NETHER_WART); + }); + } + if (findItemResult != null && findItemResult.found()) { + BlockUtils.place(pos.up(), findItemResult, rotate.get(), -100, false); + return true; + } + return false; + } + + private boolean bonemeal(BlockPos pos, BlockState state, Block block) { + if (!bonemeal.get()) return false; + if (!bonemealBlocks.get().contains(block)) return false; + if (isMature(state, block)) return false; + + FindItemResult bonemeal = InvUtils.findInHotbar(Items.BONE_MEAL); + return WorldUtils.interact(pos, bonemeal, rotate.get()); + } + + private boolean isWaterNearby(WorldView world, BlockPos pos) { + for (BlockPos blockPos : BlockPos.iterate(pos.add(-4, 0, -4), pos.add(4, 1, 4))) { + if (world.getFluidState(blockPos).isIn(FluidTags.WATER)) return true; + } + return false; + } + + private boolean isMature(BlockState state, Block block) { + if (block instanceof CropBlock cropBlock) { + return cropBlock.isMature(state); + } else if (block instanceof CocoaBlock cocoaBlock) { + return !cocoaBlock.hasRandomTicks(state); + } else if (block instanceof StemBlock) { + return state.get(StemBlock.AGE) == StemBlock.MAX_AGE; + } else if (block instanceof SweetBerryBushBlock sweetBerryBushBlock) { + return !sweetBerryBushBlock.hasRandomTicks(state); + } else if (block instanceof NetherWartBlock netherWartBlock) { + return !netherWartBlock.hasRandomTicks(state); + } + return true; + } + + private boolean bonemealFilter(Block block) { + return block instanceof CropBlock || + block instanceof CocoaBlock || + block instanceof StemBlock || + block instanceof MushroomPlantBlock || + block instanceof SweetBerryBushBlock || + block instanceof AzaleaBlock || + block instanceof SaplingBlock; + } + + private boolean harvestFilter(Block block) { + return block instanceof CropBlock || + block instanceof GourdBlock || + block instanceof NetherWartBlock || + block instanceof SweetBerryBushBlock; + } + + private boolean plantFilter(Item item) { + return item == Items.WHEAT_SEEDS || + item == Items.CARROT || + item == Items.POTATO || + item == Items.BEETROOT_SEEDS || + item == Items.PUMPKIN_SEEDS || + item == Items.MELON_SEEDS || + item == Items.NETHER_WART; + } +} diff --git a/src/main/java/anticope/rejects/modules/BonemealAura.java b/src/main/java/anticope/rejects/modules/BonemealAura.java deleted file mode 100644 index 5a01bd6..0000000 --- a/src/main/java/anticope/rejects/modules/BonemealAura.java +++ /dev/null @@ -1,109 +0,0 @@ -package anticope.rejects.modules; - -import net.minecraft.block.AzaleaBlock; -import net.minecraft.block.Block; -import net.minecraft.block.CocoaBlock; -import net.minecraft.block.CropBlock; -import net.minecraft.block.MushroomPlantBlock; -import net.minecraft.block.SaplingBlock; -import net.minecraft.block.StemBlock; -import net.minecraft.block.SweetBerryBushBlock; -import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; - -import anticope.rejects.MeteorRejectsAddon; -import meteordevelopment.meteorclient.events.render.Render3DEvent; -import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.renderer.ShapeMode; -import meteordevelopment.meteorclient.systems.modules.Module; -import meteordevelopment.meteorclient.utils.Utils; -import meteordevelopment.meteorclient.utils.player.FindItemResult; -import meteordevelopment.meteorclient.utils.player.InvUtils; -import meteordevelopment.meteorclient.utils.player.Rotations; -import meteordevelopment.meteorclient.utils.render.color.Color; -import meteordevelopment.orbit.EventHandler; - -public class BonemealAura extends Module { - public BonemealAura() { - super(MeteorRejectsAddon.CATEGORY, "bonemeal-aura", "Automatically bonemeal crops around the player"); - } - - public boolean isBonemealing; - - @EventHandler - private void onTick(TickEvent.Pre event) { - BlockPos crop = getCrop(); - if (crop == null) { - isBonemealing = false; - return; - } - - FindItemResult bonemeal = InvUtils.findInHotbar(Items.BONE_MEAL); - if (!bonemeal.found()) { - isBonemealing = false; - return; - } - - - isBonemealing = true; - Rotations.rotate(Rotations.getYaw(crop), Rotations.getPitch(crop), () -> { - InvUtils.swap(bonemeal.slot(), false); - mc.player.networkHandler.sendPacket(new PlayerInteractBlockC2SPacket(Hand.MAIN_HAND, new BlockHitResult(Utils.vec3d(crop), Direction.UP, crop, false), 0)); - mc.player.swingHand(Hand.MAIN_HAND); - }); - } - - private BlockPos getCrop() { - for (int x = -4; x < 4; x++) { - for (int y = -2; y < 2; y++) { - for (int z = -4; z < 4; z++) { - BlockPos blockPos = mc.player.getBlockPos().add(x, y, z); - Block block = mc.world.getBlockState(blockPos).getBlock(); - if (block instanceof CropBlock cropBlock) { - int age = mc.world.getBlockState(blockPos).get(cropBlock.getAgeProperty()); - if (age < cropBlock.getMaxAge()) - return blockPos; - } - if (block instanceof CocoaBlock) { - int age = mc.world.getBlockState(blockPos).get(CocoaBlock.AGE); - if (age < 2) - return blockPos; - } - if (block instanceof StemBlock) { - int age = mc.world.getBlockState(blockPos).get(StemBlock.AGE); - if (age < StemBlock.MAX_AGE) - return blockPos; - } - if (block instanceof MushroomPlantBlock) { - return blockPos; - } - if (block instanceof SweetBerryBushBlock) { - int age = mc.world.getBlockState(blockPos).get(SweetBerryBushBlock.AGE); - if (age < 3) - return blockPos; - } - if (block instanceof SaplingBlock || block instanceof AzaleaBlock){ - return blockPos; - } - } - } - } - return null; - } - - @EventHandler - private void onRender(Render3DEvent event) { - BlockPos crop = getCrop(); - if (crop == null || !InvUtils.findInHotbar(Items.BONE_MEAL).found()) return; - event.renderer.box(crop, Color.WHITE, Color.WHITE, ShapeMode.Lines, 0); - } - - @Override - public String getInfoString() { - return isBonemealing?"Busy":""; - } -} diff --git a/src/main/java/anticope/rejects/modules/MossBot.java b/src/main/java/anticope/rejects/modules/MossBot.java new file mode 100644 index 0000000..db5e187 --- /dev/null +++ b/src/main/java/anticope/rejects/modules/MossBot.java @@ -0,0 +1,91 @@ +package anticope.rejects.modules; + +import anticope.rejects.MeteorRejectsAddon; +import anticope.rejects.utils.WorldUtils; +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.player.FindItemResult; +import meteordevelopment.meteorclient.utils.player.InvUtils; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.item.Items; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public class MossBot extends Module { + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + + private final Setting range = sgGeneral.add(new IntSetting.Builder() + .name("range") + .description("The bonemeal range.") + .defaultValue(4) + .min(0) + .build() + ); + + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() + .name("rotate") + .description("Whether or not to rotate towards block while bonemealing.") + .defaultValue(true) + .build() + ); + + private final Map mossMap = new HashMap<>(); + + public MossBot() { + super(MeteorRejectsAddon.CATEGORY, "moss-bot", "Use bonemeal on moss blocks with maximized efficiency."); + } + + @EventHandler + private void onTick(TickEvent.Pre event) { + mossMap.entrySet().removeIf(e -> e.setValue(e.getValue() - 1) == 0); + FindItemResult findItemResult = InvUtils.findInHotbar(Items.BONE_MEAL); + if (!findItemResult.found()) { + return; + } + + BlockPos bestBlock = BlockPos.streamOutwards(new BlockPos(mc.player.getEyePos()), range.get(), range.get(), range.get()) + .filter(b -> mc.player.getEyePos().distanceTo(Vec3d.ofCenter(b)) <= range.get() && !mossMap.containsKey(b)) + .map(b -> Pair.of(b.toImmutable(), getMossSpots(b))) + .filter(p -> p.getRight() > 10) + .map(Pair::getLeft) + .max(Comparator.naturalOrder()).orElse(null); + + if (bestBlock != null) { + if (!mc.world.isAir(bestBlock.up())) { + mc.interactionManager.updateBlockBreakingProgress(bestBlock.up(), Direction.UP); + } + + WorldUtils.interact(bestBlock, findItemResult, rotate.get()); + mossMap.put(bestBlock, 100); + } + } + + private int getMossSpots(BlockPos pos) { + if (mc.world.getBlockState(pos).getBlock() != Blocks.MOSS_BLOCK + || mc.world.getBlockState(pos.up()).getHardness(mc.world, pos) != 0f) { + return 0; + } + + return (int) BlockPos.streamOutwards(pos, 3, 4, 3) + .filter(b -> isMossGrowableOn(mc.world.getBlockState(b).getBlock()) && mc.world.isAir(b.up())) + .count(); + } + + private boolean isMossGrowableOn(Block block) { + return block == Blocks.STONE || block == Blocks.GRANITE || block == Blocks.ANDESITE || block == Blocks.DIORITE + || block == Blocks.DIRT || block == Blocks.COARSE_DIRT || block == Blocks.MYCELIUM || block == Blocks.GRASS_BLOCK + || block == Blocks.PODZOL || block == Blocks.ROOTED_DIRT; + } +} \ No newline at end of file diff --git a/src/main/java/anticope/rejects/modules/TillAura.java b/src/main/java/anticope/rejects/modules/TillAura.java deleted file mode 100644 index 8e9bc78..0000000 --- a/src/main/java/anticope/rejects/modules/TillAura.java +++ /dev/null @@ -1,209 +0,0 @@ -package anticope.rejects.modules; - -import anticope.rejects.MeteorRejectsAddon; -import anticope.rejects.utils.WorldUtils; -import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.mixin.MinecraftClientAccessor; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.DoubleSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; -import meteordevelopment.meteorclient.systems.modules.Module; -import meteordevelopment.meteorclient.utils.player.Rotations; -import meteordevelopment.orbit.EventHandler; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.item.HoeItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.RaycastContext; -import net.minecraft.world.RaycastContext.FluidHandling; -import net.minecraft.world.RaycastContext.ShapeType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -public class TillAura extends Module { - private final SettingGroup sgGeneral = settings.getDefaultGroup(); - - private final Setting range = sgGeneral.add(new DoubleSetting.Builder() - .name("range") - .description("How far Tillaura will reach to till blocks.") - .defaultValue(5) - .min(0) - .build() - ); - - private final Setting multiTill = sgGeneral.add(new BoolSetting.Builder(). - name("multi-till") - .description("Tills multiple blocks at once. Faster, but can't bypass NoCheat+.") - .defaultValue(false) - .build() - ); - private final Setting checkLOS = sgGeneral.add(new BoolSetting.Builder(). - name("check-line-of-sight") - .description("Prevents Tillaura from reaching through blocks. Good for NoCheat+ servers, but unnecessary in vanilla.") - .defaultValue(true) - .build() - ); - - private final List tillableBlocks = Arrays.asList(Blocks.GRASS_BLOCK, - Blocks.DIRT_PATH, Blocks.DIRT, Blocks.COARSE_DIRT); - - public TillAura() { - super(MeteorRejectsAddon.CATEGORY, "till-aura", "Automatically turns dirt, grass, etc. into farmland."); - } - - @EventHandler - private void onTick(TickEvent.Post event) { - // wait for right click timer - if (((MinecraftClientAccessor) mc).getItemUseCooldown() > 0) - return; - - // check held item - ItemStack stack = mc.player.getInventory().getMainHandStack(); - if (stack.isEmpty() || !(stack.getItem() instanceof HoeItem)) - return; - - // get valid blocks - ArrayList validBlocks = getValidBlocks(range.get(), this::isCorrectBlock); - - if (multiTill.get()) { - boolean shouldSwing = false; - - // till all valid blocks - for (BlockPos pos : validBlocks) - if (rightClickBlockSimple(pos)) - shouldSwing = true; - - // swing arm - if (shouldSwing) - mc.player.swingHand(Hand.MAIN_HAND); - } else - // till next valid block - for (BlockPos pos : validBlocks) - if (rightClickBlockLegit(pos)) - break; - } - - private Vec3d getEyesPos() { - ClientPlayerEntity player = mc.player; - - return new Vec3d(player.getX(), - player.getY() + player.getEyeHeight(player.getPose()), - player.getZ()); - } - - private ArrayList getValidBlocks(double range, - Predicate validator) { - Vec3d eyesVec = getEyesPos().subtract(0.5, 0.5, 0.5); - double rangeSq = Math.pow(range + 0.5, 2); - int rangeI = (int) Math.ceil(range); - - BlockPos center = new BlockPos(getEyesPos()); - BlockPos min = center.add(-rangeI, -rangeI, -rangeI); - BlockPos max = center.add(rangeI, rangeI, rangeI); - - return WorldUtils.getAllInBox(min, max).stream() - .filter(pos -> eyesVec.squaredDistanceTo(Vec3d.of(pos)) <= rangeSq) - .filter(validator) - .sorted(Comparator.comparingDouble( - pos -> eyesVec.squaredDistanceTo(Vec3d.of(pos)))) - .collect(Collectors.toCollection(ArrayList::new)); - } - - private boolean isCorrectBlock(BlockPos pos) { - if (!tillableBlocks.contains(mc.world.getBlockState(pos).getBlock())) - return false; - - return mc.world.getBlockState(pos.up()).isAir(); - } - - private boolean rightClickBlockLegit(BlockPos pos) { - Vec3d eyesPos = getEyesPos(); - Vec3d posVec = Vec3d.ofCenter(pos); - double distanceSqPosVec = eyesPos.squaredDistanceTo(posVec); - double rangeSq = Math.pow(range.get(), 2); - - for (Direction side : Direction.values()) { - Vec3d hitVec = posVec.add(Vec3d.of(side.getVector()).multiply(0.5)); - double distanceSqHitVec = eyesPos.squaredDistanceTo(hitVec); - - // check if hitVec is within range - if (distanceSqHitVec > rangeSq) - continue; - - // check if side is facing towards player - if (distanceSqHitVec >= distanceSqPosVec) - continue; - - if (checkLOS.get() && !hasLineOfSight(eyesPos, hitVec)) - continue; - - // face block - Rotations.rotate(Rotations.getYaw(hitVec), Rotations.getPitch(hitVec)); - - // right click block - rightClickBlock(pos, side, hitVec); - mc.player.swingHand(Hand.MAIN_HAND); - ((MinecraftClientAccessor) mc).setItemUseCooldown(4); - return true; - } - - return false; - } - - private void rightClickBlock(BlockPos pos, Direction side, Vec3d hitVec) { - mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, - new BlockHitResult(hitVec, side, pos, false)); - mc.interactionManager.interactItem(mc.player, Hand.MAIN_HAND); - } - - private boolean rightClickBlockSimple(BlockPos pos) { - Vec3d eyesPos = getEyesPos(); - Vec3d posVec = Vec3d.ofCenter(pos); - double distanceSqPosVec = eyesPos.squaredDistanceTo(posVec); - double rangeSq = Math.pow(range.get(), 2); - - for (Direction side : Direction.values()) { - Vec3d hitVec = posVec.add(Vec3d.of(side.getVector()).multiply(0.5)); - double distanceSqHitVec = eyesPos.squaredDistanceTo(hitVec); - - // check if hitVec is within range - if (distanceSqHitVec > rangeSq) - continue; - - // check if side is facing towards player - if (distanceSqHitVec >= distanceSqPosVec) - continue; - - if (checkLOS.get() && !hasLineOfSight(eyesPos, hitVec)) - continue; - - rightClickBlock(pos, side, hitVec); - return true; - } - - return false; - } - - private boolean hasLineOfSight(Vec3d from, Vec3d to) { - ShapeType type = RaycastContext.ShapeType.COLLIDER; - FluidHandling fluid = RaycastContext.FluidHandling.NONE; - - RaycastContext context = - new RaycastContext(from, to, type, fluid, mc.player); - - return mc.world.raycast(context).getType() == HitResult.Type.MISS; - } -} diff --git a/src/main/java/anticope/rejects/utils/WorldUtils.java b/src/main/java/anticope/rejects/utils/WorldUtils.java index 44d916c..7d01c8f 100644 --- a/src/main/java/anticope/rejects/utils/WorldUtils.java +++ b/src/main/java/anticope/rejects/utils/WorldUtils.java @@ -1,16 +1,23 @@ package anticope.rejects.utils; +import meteordevelopment.meteorclient.utils.player.FindItemResult; +import meteordevelopment.meteorclient.utils.player.InvUtils; +import meteordevelopment.meteorclient.utils.player.Rotations; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import java.util.ArrayList; import java.util.List; -public class WorldUtils { - private static final ArrayList blocks = new ArrayList<>(); +import static meteordevelopment.meteorclient.MeteorClient.mc; +public class WorldUtils { public static List getSphere(BlockPos centerPos, int radius, int height) { - blocks.clear(); + ArrayList blocks = new ArrayList<>(); for (int i = centerPos.getX() - radius; i < centerPos.getX() + radius; i++) { for (int j = centerPos.getY() - height; j < centerPos.getY() + height; j++) { @@ -24,27 +31,26 @@ public class WorldUtils { return blocks; } - public static List getAllInBox(BlockPos from, BlockPos to) { - blocks.clear(); - - BlockPos min = new BlockPos(Math.min(from.getX(), to.getX()), - Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ())); - BlockPos max = new BlockPos(Math.max(from.getX(), to.getX()), - Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ())); - - for (int x = min.getX(); x <= max.getX(); x++) - for (int y = min.getY(); y <= max.getY(); y++) - for (int z = min.getZ(); z <= max.getZ(); z++) - blocks.add(new BlockPos(x, y, z)); - - return blocks; - } - - public static double distanceBetween(BlockPos pos1, BlockPos pos2) { double d = pos1.getX() - pos2.getX(); double e = pos1.getY() - pos2.getY(); double f = pos1.getZ() - pos2.getZ(); return MathHelper.sqrt((float) (d * d + e * e + f * f)); } + + public static boolean interact(BlockPos pos, FindItemResult findItemResult, boolean rotate) { + if (!findItemResult.found()) return false; + Runnable action = () -> { + boolean wasSneaking = mc.player.input.sneaking; + mc.player.input.sneaking = false; + InvUtils.swap(findItemResult.slot(), true); + mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Vec3d.ofCenter(pos), Direction.UP, pos, false)); + mc.player.swingHand(Hand.MAIN_HAND); + InvUtils.swapBack(); + mc.player.input.sneaking = wasSneaking; + }; + if (rotate) Rotations.rotate(Rotations.getYaw(pos), Rotations.getPitch(pos), -100, action); + else action.run(); + return true; + } }