Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5184d3d13 | |||
| 8fc798ee94 |
@@ -35,6 +35,8 @@ public class AutoFarm extends Module {
|
|||||||
private final SettingGroup sgBonemeal = settings.createGroup("Bonemeal");
|
private final SettingGroup sgBonemeal = settings.createGroup("Bonemeal");
|
||||||
|
|
||||||
private final Map<BlockPos, Item> replantMap = new HashMap<>();
|
private final Map<BlockPos, Item> replantMap = new HashMap<>();
|
||||||
|
private final Map<BlockPos, Integer> miningProgress = new HashMap<>();
|
||||||
|
private static final int MINING_HITS = 6;
|
||||||
|
|
||||||
private final Setting<Integer> range = sgGeneral.add(new IntSetting.Builder()
|
private final Setting<Integer> range = sgGeneral.add(new IntSetting.Builder()
|
||||||
.name("range")
|
.name("range")
|
||||||
@@ -138,6 +140,7 @@ public class AutoFarm extends Module {
|
|||||||
@Override
|
@Override
|
||||||
public void onDeactivate() {
|
public void onDeactivate() {
|
||||||
replantMap.clear();
|
replantMap.clear();
|
||||||
|
miningProgress.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -152,7 +155,13 @@ public class AutoFarm extends Module {
|
|||||||
else if (block == Blocks.BEETROOTS) item = Items.BEETROOT_SEEDS;
|
else if (block == Blocks.BEETROOTS) item = Items.BEETROOT_SEEDS;
|
||||||
else if (block == Blocks.NETHER_WART) item = Items.NETHER_WART;
|
else if (block == Blocks.NETHER_WART) item = Items.NETHER_WART;
|
||||||
else if (block == Blocks.PITCHER_CROP) item = Items.PITCHER_POD;
|
else if (block == Blocks.PITCHER_CROP) item = Items.PITCHER_POD;
|
||||||
else if (block == Blocks.TORCHFLOWER) item = Items.TORCHFLOWER_SEEDS;
|
else if (block == Blocks.TORCHFLOWER_CROP) item = Items.TORCHFLOWER_SEEDS;
|
||||||
|
else if (block == Blocks.SUGAR_CANE) item = Items.SUGAR_CANE;
|
||||||
|
else if (block == Blocks.BAMBOO) item = Items.BAMBOO;
|
||||||
|
else if (block == Blocks.CACTUS) item = Items.CACTUS;
|
||||||
|
else if (block == Blocks.KELP || block == Blocks.KELP_PLANT) item = Items.KELP;
|
||||||
|
else if (block == Blocks.CHORUS_FLOWER) item = Items.CHORUS_FLOWER;
|
||||||
|
else if (block == Blocks.CAVE_VINES || block == Blocks.CAVE_VINES_PLANT) item = Items.GLOW_BERRIES;
|
||||||
if (item != null) replantMap.put(event.blockPos, item);
|
if (item != null) replantMap.put(event.blockPos, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,8 +169,13 @@ public class AutoFarm extends Module {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
private void onTick(TickEvent.Pre event) {
|
private void onTick(TickEvent.Pre event) {
|
||||||
actions = 0;
|
actions = 0;
|
||||||
BlockIterator.register(range.get(), range.get(), (pos, state) -> {
|
|
||||||
if (mc.player.getEyePos().distanceTo(Vec3d.ofCenter(pos)) <= range.get())
|
// Scan blocks including vertical range for tall crops
|
||||||
|
int horizontalRange = range.get();
|
||||||
|
int verticalRange = range.get() + 2; // Extra vertical range for tall crops
|
||||||
|
|
||||||
|
BlockIterator.register(horizontalRange, verticalRange, (pos, state) -> {
|
||||||
|
if (mc.player.getEyePos().distanceTo(Vec3d.ofCenter(pos)) <= range.get() + 2)
|
||||||
blocks.add(blockPosPool.get().set(pos));
|
blocks.add(blockPosPool.get().set(pos));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -200,19 +214,103 @@ public class AutoFarm extends Module {
|
|||||||
private boolean harvest(BlockPos pos, BlockState state, Block block) {
|
private boolean harvest(BlockPos pos, BlockState state, Block block) {
|
||||||
if (!harvest.get()) return false;
|
if (!harvest.get()) return false;
|
||||||
if (!harvestBlocks.get().contains(block)) return false;
|
if (!harvestBlocks.get().contains(block)) return false;
|
||||||
if (!isMature(state, block)) return false;
|
|
||||||
if (block instanceof SweetBerryBushBlock)
|
// Special handling for Sweet Berry Bush (interact instead of breaking)
|
||||||
|
if (block instanceof SweetBerryBushBlock) {
|
||||||
|
if (!isMature(pos, state, block)) return false; // Only interact if mature
|
||||||
mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Utils.vec3d(pos), Direction.UP, pos, false));
|
mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Utils.vec3d(pos), Direction.UP, pos, false));
|
||||||
else {
|
return true;
|
||||||
mc.interactionManager.updateBlockBreakingProgress(pos, Direction.UP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For tall crops (including glow berries, bamboo, sugar cane, kelp, cactus)
|
||||||
|
if (block == Blocks.CAVE_VINES || block == Blocks.CAVE_VINES_PLANT ||
|
||||||
|
block == Blocks.BAMBOO || block == Blocks.SUGAR_CANE || block == Blocks.KELP || block == Blocks.CACTUS) {
|
||||||
|
if (!shouldHarvestTallCrop(pos, block)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For other crops, check maturity
|
||||||
|
else {
|
||||||
|
if (!isMature(pos, state, block)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all checks pass, mine the block
|
||||||
|
return mineBlock(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean mineBlock(BlockPos pos) {
|
||||||
|
// Check if block still exists
|
||||||
|
if (mc.world.getBlockState(pos).isAir()) {
|
||||||
|
miningProgress.remove(pos);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hits = miningProgress.getOrDefault(pos, 0);
|
||||||
|
|
||||||
|
// Rotate towards block
|
||||||
|
if (rotate.get()) {
|
||||||
|
meteordevelopment.meteorclient.utils.player.Rotations.rotate(
|
||||||
|
meteordevelopment.meteorclient.utils.player.Rotations.getYaw(pos),
|
||||||
|
meteordevelopment.meteorclient.utils.player.Rotations.getPitch(pos)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hits < MINING_HITS - 1) {
|
||||||
|
// Hit the block (not breaking yet)
|
||||||
|
mc.interactionManager.attackBlock(pos, Direction.UP);
|
||||||
|
miningProgress.put(pos, hits + 1);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Final hit - break the block
|
||||||
|
mc.interactionManager.attackBlock(pos, Direction.UP);
|
||||||
|
mc.player.swingHand(Hand.MAIN_HAND);
|
||||||
|
miningProgress.remove(pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldHarvestTallCrop(BlockPos pos, Block block) {
|
||||||
|
BlockPos below = pos.down();
|
||||||
|
Block blockBelow = mc.world.getBlockState(below).getBlock();
|
||||||
|
|
||||||
|
// For bamboo, only harvest if it's tall enough (3+ blocks)
|
||||||
|
if (block == Blocks.BAMBOO) {
|
||||||
|
if (blockBelow != Blocks.BAMBOO) return false;
|
||||||
|
BlockPos below2 = below.down();
|
||||||
|
return mc.world.getBlockState(below2).getBlock() == Blocks.BAMBOO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For cactus and sugar cane, harvest top blocks only (leave at least one block on sand/dirt)
|
||||||
|
if (block == Blocks.CACTUS || block == Blocks.SUGAR_CANE) {
|
||||||
|
// Harvest if there is a crop block below, leaving the base.
|
||||||
|
return blockBelow == block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For glow berries (cave vines), harvest from bottom up but leave the top attached
|
||||||
|
if (block == Blocks.CAVE_VINES || block == Blocks.CAVE_VINES_PLANT) {
|
||||||
|
BlockPos above = pos.up();
|
||||||
|
Block blockAbove = mc.world.getBlockState(above).getBlock();
|
||||||
|
|
||||||
|
// Must have a vine or solid block above (so we're not breaking the attachment point)
|
||||||
|
if (blockAbove != Blocks.CAVE_VINES && blockAbove != Blocks.CAVE_VINES_PLANT &&
|
||||||
|
!mc.world.getBlockState(above).isSolidBlock(mc.world, above)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only harvest if there's at least 2 blocks above (leave at least one vine attached)
|
||||||
|
BlockPos above2 = above.up();
|
||||||
|
Block blockAbove2 = mc.world.getBlockState(above2).getBlock();
|
||||||
|
return blockAbove2 == Blocks.CAVE_VINES || blockAbove2 == Blocks.CAVE_VINES_PLANT ||
|
||||||
|
mc.world.getBlockState(above2).isSolidBlock(mc.world, above2);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean plant(BlockPos pos, Block block) {
|
private boolean plant(BlockPos pos, Block block) {
|
||||||
if (!plant.get()) return false;
|
if (!plant.get()) return false;
|
||||||
if (!mc.world.isAir(pos.up())) return false;
|
|
||||||
FindItemResult findItemResult = null;
|
FindItemResult findItemResult = null;
|
||||||
|
|
||||||
if (onlyReplant.get()) {
|
if (onlyReplant.get()) {
|
||||||
for (BlockPos replantPos : replantMap.keySet()) {
|
for (BlockPos replantPos : replantMap.keySet()) {
|
||||||
if (replantPos.equals(pos.up())) {
|
if (replantPos.equals(pos.up())) {
|
||||||
@@ -221,17 +319,112 @@ public class AutoFarm extends Module {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (block instanceof FarmlandBlock) {
|
} else {
|
||||||
findItemResult = InvUtils.find(itemStack -> {
|
// Cave vines for glow berries - ONLY extend existing vines by ONE block
|
||||||
Item item = itemStack.getItem();
|
if (block == Blocks.CAVE_VINES || block == Blocks.CAVE_VINES_PLANT) {
|
||||||
return item != Items.NETHER_WART && plantItems.get().contains(item);
|
// Check if the block directly below is air (to extend by one)
|
||||||
});
|
if (mc.world.isAir(pos.down())) {
|
||||||
} else if (block instanceof SoulSandBlock) {
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
findItemResult = InvUtils.find(itemStack -> {
|
Item item = itemStack.getItem();
|
||||||
Item item = itemStack.getItem();
|
return item == Items.GLOW_BERRIES && plantItems.get().contains(Items.GLOW_BERRIES);
|
||||||
return item == Items.NETHER_WART && plantItems.get().contains(Items.NETHER_WART);
|
});
|
||||||
});
|
if (findItemResult != null && findItemResult.found()) {
|
||||||
|
BlockUtils.place(pos.down(), findItemResult, rotate.get(), -100, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check if we can start a new glow berry vine below a solid block (ONE block only)
|
||||||
|
else if (!mc.world.isAir(pos) && mc.world.getBlockState(pos).isSolidBlock(mc.world, pos)) {
|
||||||
|
BlockPos below = pos.down();
|
||||||
|
// Only plant if directly below is air AND it's not already a cave vine
|
||||||
|
if (mc.world.isAir(below) &&
|
||||||
|
mc.world.getBlockState(below).getBlock() != Blocks.CAVE_VINES &&
|
||||||
|
mc.world.getBlockState(below).getBlock() != Blocks.CAVE_VINES_PLANT) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item == Items.GLOW_BERRIES && plantItems.get().contains(Items.GLOW_BERRIES);
|
||||||
|
});
|
||||||
|
if (findItemResult != null && findItemResult.found()) {
|
||||||
|
BlockUtils.place(below, findItemResult, rotate.get(), -100, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mc.world.isAir(pos.up())) return false;
|
||||||
|
|
||||||
|
// Farmland crops
|
||||||
|
if (block instanceof FarmlandBlock) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item != Items.NETHER_WART && plantItems.get().contains(item) &&
|
||||||
|
(item == Items.WHEAT_SEEDS || item == Items.CARROT || item == Items.POTATO ||
|
||||||
|
item == Items.BEETROOT_SEEDS || item == Items.PUMPKIN_SEEDS ||
|
||||||
|
item == Items.MELON_SEEDS || item == Items.PITCHER_POD ||
|
||||||
|
item == Items.TORCHFLOWER_SEEDS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Soul sand crops (nether wart)
|
||||||
|
else if (block instanceof SoulSandBlock) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item == Items.NETHER_WART && plantItems.get().contains(Items.NETHER_WART);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Dirt/Grass for sugar cane, bamboo
|
||||||
|
else if (block == Blocks.DIRT || block == Blocks.GRASS_BLOCK || block == Blocks.PODZOL ||
|
||||||
|
block == Blocks.COARSE_DIRT || block == Blocks.ROOTED_DIRT || block == Blocks.MOSS_BLOCK) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return plantItems.get().contains(item) &&
|
||||||
|
(item == Items.SUGAR_CANE || item == Items.BAMBOO);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Sand for cactus and sugar cane
|
||||||
|
else if (block == Blocks.SAND || block == Blocks.RED_SAND) {
|
||||||
|
// Check if there's space around for cactus (no adjacent blocks)
|
||||||
|
BlockPos plantPos = pos.up();
|
||||||
|
boolean hasSpaceForCactus = mc.world.isAir(plantPos.north()) &&
|
||||||
|
mc.world.isAir(plantPos.south()) &&
|
||||||
|
mc.world.isAir(plantPos.east()) &&
|
||||||
|
mc.world.isAir(plantPos.west());
|
||||||
|
|
||||||
|
if (hasSpaceForCactus) {
|
||||||
|
// Can plant cactus
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return plantItems.get().contains(item) &&
|
||||||
|
(item == Items.CACTUS || item == Items.SUGAR_CANE);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Only sugar cane (doesn't need space)
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item == Items.SUGAR_CANE && plantItems.get().contains(Items.SUGAR_CANE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Water/kelp for kelp
|
||||||
|
else if (block == Blocks.WATER || block == Blocks.KELP || block == Blocks.KELP_PLANT) {
|
||||||
|
if (mc.world.getFluidState(pos.up()).isIn(FluidTags.WATER)) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item == Items.KELP && plantItems.get().contains(Items.KELP);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// End stone for chorus
|
||||||
|
else if (block == Blocks.END_STONE) {
|
||||||
|
findItemResult = InvUtils.find(itemStack -> {
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
return item == Items.CHORUS_FLOWER && plantItems.get().contains(Items.CHORUS_FLOWER);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (findItemResult != null && findItemResult.found()) {
|
if (findItemResult != null && findItemResult.found()) {
|
||||||
BlockUtils.place(pos.up(), findItemResult, rotate.get(), -100, false);
|
BlockUtils.place(pos.up(), findItemResult, rotate.get(), -100, false);
|
||||||
return true;
|
return true;
|
||||||
@@ -242,10 +435,41 @@ public class AutoFarm extends Module {
|
|||||||
private boolean bonemeal(BlockPos pos, BlockState state, Block block) {
|
private boolean bonemeal(BlockPos pos, BlockState state, Block block) {
|
||||||
if (!bonemeal.get()) return false;
|
if (!bonemeal.get()) return false;
|
||||||
if (!bonemealBlocks.get().contains(block)) return false;
|
if (!bonemealBlocks.get().contains(block)) return false;
|
||||||
if (isMature(state, block)) return false;
|
|
||||||
|
|
||||||
FindItemResult bonemeal = InvUtils.findInHotbar(Items.BONE_MEAL);
|
// If crop is already mature, harvest it instead
|
||||||
return WorldUtils.interact(pos, bonemeal, rotate.get());
|
if (isMature(pos, state, block)) {
|
||||||
|
return harvest(pos, state, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
FindItemResult bonemealResult = InvUtils.find(Items.BONE_MEAL);
|
||||||
|
|
||||||
|
// If no bonemeal available, harvest mature crops instead
|
||||||
|
if (!bonemealResult.found()) {
|
||||||
|
if (isMature(pos, state, block)) {
|
||||||
|
return harvest(pos, state, block);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to hotbar if not already there
|
||||||
|
if (!bonemealResult.isHotbar()) {
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if (mc.player.getInventory().getStack(i).isEmpty()) {
|
||||||
|
InvUtils.move().from(bonemealResult.slot()).to(i);
|
||||||
|
bonemealResult = InvUtils.findInHotbar(Items.BONE_MEAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If still not in hotbar after trying to move, harvest if mature
|
||||||
|
if (!bonemealResult.found() || !bonemealResult.isHotbar()) {
|
||||||
|
if (isMature(pos, state, block)) {
|
||||||
|
return harvest(pos, state, block);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WorldUtils.interact(pos, bonemealResult, rotate.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWaterNearby(WorldView world, BlockPos pos) {
|
private boolean isWaterNearby(WorldView world, BlockPos pos) {
|
||||||
@@ -255,7 +479,7 @@ public class AutoFarm extends Module {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMature(BlockState state, Block block) {
|
private boolean isMature(BlockPos pos, BlockState state, Block block) {
|
||||||
if (block instanceof CropBlock cropBlock) {
|
if (block instanceof CropBlock cropBlock) {
|
||||||
return cropBlock.isMature(state);
|
return cropBlock.isMature(state);
|
||||||
} else if (block instanceof CocoaBlock cocoaBlock) {
|
} else if (block instanceof CocoaBlock cocoaBlock) {
|
||||||
@@ -268,6 +492,36 @@ public class AutoFarm extends Module {
|
|||||||
return state.get(netherWartBlock.AGE) >= 3;
|
return state.get(netherWartBlock.AGE) >= 3;
|
||||||
} else if (block instanceof PitcherCropBlock pitcherCropBlock) {
|
} else if (block instanceof PitcherCropBlock pitcherCropBlock) {
|
||||||
return state.get(pitcherCropBlock.AGE) >= 4;
|
return state.get(pitcherCropBlock.AGE) >= 4;
|
||||||
|
} else if (block == Blocks.CAVE_VINES || block == Blocks.CAVE_VINES_PLANT) {
|
||||||
|
// For glow berries: mature means there are berries (triggers harvest of entire vine section)
|
||||||
|
// During harvest, ALL vine blocks are broken regardless of berries
|
||||||
|
return state.get(CaveVines.BERRIES);
|
||||||
|
}
|
||||||
|
// Bamboo is mature if it's more than 2 blocks tall (ready to harvest)
|
||||||
|
// For bonemeal check, we consider single bamboo as not mature
|
||||||
|
else if (block == Blocks.BAMBOO) {
|
||||||
|
Block below = mc.world.getBlockState(pos.down()).getBlock();
|
||||||
|
Block below2 = mc.world.getBlockState(pos.down(2)).getBlock();
|
||||||
|
// If checking for harvest, needs 3 blocks tall
|
||||||
|
// If checking for bonemeal, single bamboo is not mature
|
||||||
|
return below == Blocks.BAMBOO && below2 == Blocks.BAMBOO;
|
||||||
|
}
|
||||||
|
// Sugar cane is mature if it's more than 2 blocks tall
|
||||||
|
else if (block == Blocks.SUGAR_CANE) {
|
||||||
|
return mc.world.getBlockState(pos.down()).getBlock() == Blocks.SUGAR_CANE &&
|
||||||
|
mc.world.getBlockState(pos.down(2)).getBlock() == Blocks.SUGAR_CANE;
|
||||||
|
}
|
||||||
|
// Cactus is mature if it's more than 2 blocks tall
|
||||||
|
else if (block == Blocks.CACTUS) {
|
||||||
|
return mc.world.getBlockState(pos.down()).getBlock() == Blocks.CACTUS &&
|
||||||
|
mc.world.getBlockState(pos.down(2)).getBlock() == Blocks.CACTUS;
|
||||||
|
}
|
||||||
|
// Kelp is mature if it's more than 2 blocks tall
|
||||||
|
else if (block == Blocks.KELP || block == Blocks.KELP_PLANT) {
|
||||||
|
Block below = mc.world.getBlockState(pos.down()).getBlock();
|
||||||
|
Block below2 = mc.world.getBlockState(pos.down(2)).getBlock();
|
||||||
|
return (below == Blocks.KELP || below == Blocks.KELP_PLANT) &&
|
||||||
|
(below2 == Blocks.KELP || below2 == Blocks.KELP_PLANT);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -281,7 +535,14 @@ public class AutoFarm extends Module {
|
|||||||
block == Blocks.COCOA ||
|
block == Blocks.COCOA ||
|
||||||
block == Blocks.SWEET_BERRY_BUSH ||
|
block == Blocks.SWEET_BERRY_BUSH ||
|
||||||
block == Blocks.PITCHER_CROP ||
|
block == Blocks.PITCHER_CROP ||
|
||||||
block == Blocks.TORCHFLOWER;
|
block == Blocks.TORCHFLOWER_CROP ||
|
||||||
|
block == Blocks.BAMBOO ||
|
||||||
|
// Cactus and sugar cane removed from bonemeal filter
|
||||||
|
block == Blocks.KELP ||
|
||||||
|
block == Blocks.KELP_PLANT ||
|
||||||
|
block == Blocks.CHORUS_FLOWER ||
|
||||||
|
block == Blocks.CAVE_VINES ||
|
||||||
|
block == Blocks.CAVE_VINES_PLANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean harvestFilter(Block block) {
|
private boolean harvestFilter(Block block) {
|
||||||
@@ -292,7 +553,15 @@ public class AutoFarm extends Module {
|
|||||||
block == Blocks.SWEET_BERRY_BUSH ||
|
block == Blocks.SWEET_BERRY_BUSH ||
|
||||||
block == Blocks.COCOA ||
|
block == Blocks.COCOA ||
|
||||||
block == Blocks.PITCHER_CROP ||
|
block == Blocks.PITCHER_CROP ||
|
||||||
block == Blocks.TORCHFLOWER;
|
block == Blocks.TORCHFLOWER_CROP ||
|
||||||
|
block == Blocks.BAMBOO ||
|
||||||
|
block == Blocks.SUGAR_CANE ||
|
||||||
|
block == Blocks.CACTUS ||
|
||||||
|
block == Blocks.KELP ||
|
||||||
|
block == Blocks.KELP_PLANT ||
|
||||||
|
block == Blocks.CHORUS_FLOWER ||
|
||||||
|
block == Blocks.CAVE_VINES ||
|
||||||
|
block == Blocks.CAVE_VINES_PLANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean plantFilter(Item item) {
|
private boolean plantFilter(Item item) {
|
||||||
@@ -304,6 +573,12 @@ public class AutoFarm extends Module {
|
|||||||
item == Items.MELON_SEEDS ||
|
item == Items.MELON_SEEDS ||
|
||||||
item == Items.NETHER_WART ||
|
item == Items.NETHER_WART ||
|
||||||
item == Items.PITCHER_POD ||
|
item == Items.PITCHER_POD ||
|
||||||
item == Items.TORCHFLOWER_SEEDS;
|
item == Items.TORCHFLOWER_SEEDS ||
|
||||||
|
item == Items.BAMBOO ||
|
||||||
|
item == Items.SUGAR_CANE ||
|
||||||
|
item == Items.CACTUS ||
|
||||||
|
item == Items.KELP ||
|
||||||
|
item == Items.CHORUS_FLOWER ||
|
||||||
|
item == Items.GLOW_BERRIES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,9 @@ import meteordevelopment.meteorclient.systems.modules.Module;
|
|||||||
import meteordevelopment.meteorclient.utils.Utils;
|
import meteordevelopment.meteorclient.utils.Utils;
|
||||||
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
|
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
|
||||||
import meteordevelopment.orbit.EventHandler;
|
import meteordevelopment.orbit.EventHandler;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.random.ChunkRandom;
|
import net.minecraft.util.math.random.ChunkRandom;
|
||||||
@@ -62,6 +64,13 @@ public class OreSim extends Module {
|
|||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private final Setting<Boolean> verifyOreBlocks = sgGeneral.add(new BoolSetting.Builder()
|
||||||
|
.name("verify-ore-blocks")
|
||||||
|
.description("Only show positions where actual ore blocks exist (recommended for accuracy).")
|
||||||
|
.defaultValue(true)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
private final Setting<Boolean> baritone = sgGeneral.add(new BoolSetting.Builder()
|
private final Setting<Boolean> baritone = sgGeneral.add(new BoolSetting.Builder()
|
||||||
.name("baritone")
|
.name("baritone")
|
||||||
.description("Set baritone ore positions to the simulated ones.")
|
.description("Set baritone ore positions to the simulated ones.")
|
||||||
@@ -270,9 +279,9 @@ public class OreSim extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ore.scattered) {
|
if (ore.scattered) {
|
||||||
ores.addAll(generateHidden(world, random, origin, ore.size));
|
ores.addAll(generateHidden(world, random, origin, ore.size, ore));
|
||||||
} else {
|
} else {
|
||||||
ores.addAll(generateNormal(world, random, origin, ore.size, ore.discardOnAirChance));
|
ores.addAll(generateNormal(world, random, origin, ore.size, ore.discardOnAirChance, ore));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ores.isEmpty()) {
|
if (!ores.isEmpty()) {
|
||||||
@@ -290,11 +299,28 @@ public class OreSim extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to check if a block state is an ore
|
||||||
|
private boolean isOreBlock(BlockState state, Ore ore) {
|
||||||
|
if (!verifyOreBlocks.get()) {
|
||||||
|
return true; // Skip verification if disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
String blockId = Registries.BLOCK.getId(state.getBlock()).toString();
|
||||||
|
|
||||||
|
// Check for any ore block or ancient debris
|
||||||
|
// This includes: coal_ore, deepslate_coal_ore, iron_ore, deepslate_iron_ore,
|
||||||
|
// gold_ore, deepslate_gold_ore, diamond_ore, deepslate_diamond_ore,
|
||||||
|
// emerald_ore, deepslate_emerald_ore, lapis_ore, deepslate_lapis_ore,
|
||||||
|
// redstone_ore, deepslate_redstone_ore, copper_ore, deepslate_copper_ore,
|
||||||
|
// nether_gold_ore, nether_quartz_ore, ancient_debris
|
||||||
|
return blockId.endsWith("_ore") || blockId.equals("minecraft:ancient_debris");
|
||||||
|
}
|
||||||
|
|
||||||
// ====================================
|
// ====================================
|
||||||
// Mojang code
|
// Mojang code (modified)
|
||||||
// ====================================
|
// ====================================
|
||||||
|
|
||||||
private ArrayList<Vec3d> generateNormal(ClientWorld world, ChunkRandom random, BlockPos blockPos, int veinSize, float discardOnAir) {
|
private ArrayList<Vec3d> generateNormal(ClientWorld world, ChunkRandom random, BlockPos blockPos, int veinSize, float discardOnAir, Ore ore) {
|
||||||
float f = random.nextFloat() * 3.1415927F;
|
float f = random.nextFloat() * 3.1415927F;
|
||||||
float g = (float) veinSize / 8.0F;
|
float g = (float) veinSize / 8.0F;
|
||||||
int i = MathHelper.ceil(((float) veinSize / 16.0F * 2.0F + 1.0F) / 2.0F);
|
int i = MathHelper.ceil(((float) veinSize / 16.0F * 2.0F + 1.0F) / 2.0F);
|
||||||
@@ -313,7 +339,7 @@ public class OreSim extends Module {
|
|||||||
for (int s = n; s <= n + q; ++s) {
|
for (int s = n; s <= n + q; ++s) {
|
||||||
for (int t = p; t <= p + q; ++t) {
|
for (int t = p; t <= p + q; ++t) {
|
||||||
if (o <= world.getTopY(Heightmap.Type.MOTION_BLOCKING, s, t)) {
|
if (o <= world.getTopY(Heightmap.Type.MOTION_BLOCKING, s, t)) {
|
||||||
return this.generateVeinPart(world, random, veinSize, d, e, h, j, l, m, n, o, p, q, r, discardOnAir);
|
return this.generateVeinPart(world, random, veinSize, d, e, h, j, l, m, n, o, p, q, r, discardOnAir, ore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,7 +347,7 @@ public class OreSim extends Module {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Vec3d> generateVeinPart(ClientWorld world, ChunkRandom random, int veinSize, double startX, double endX, double startZ, double endZ, double startY, double endY, int x, int y, int z, int size, int i, float discardOnAir) {
|
private ArrayList<Vec3d> generateVeinPart(ClientWorld world, ChunkRandom random, int veinSize, double startX, double endX, double startZ, double endZ, double startY, double endY, int x, int y, int z, int size, int i, float discardOnAir, Ore ore) {
|
||||||
|
|
||||||
BitSet bitSet = new BitSet(size * i * size);
|
BitSet bitSet = new BitSet(size * i * size);
|
||||||
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
||||||
@@ -393,9 +419,15 @@ public class OreSim extends Module {
|
|||||||
if (!bitSet.get(an)) {
|
if (!bitSet.get(an)) {
|
||||||
bitSet.set(an);
|
bitSet.set(an);
|
||||||
mutable.set(ah, aj, al);
|
mutable.set(ah, aj, al);
|
||||||
if (aj >= -64 && aj < 320 && (airCheck.get() == AirCheck.OFF || world.getBlockState(mutable).isOpaque())) {
|
if (aj >= -64 && aj < 320) {
|
||||||
if (shouldPlace(world, mutable, discardOnAir, random)) {
|
BlockState state = world.getBlockState(mutable);
|
||||||
poses.add(new Vec3d(ah, aj, al));
|
boolean passesAirCheck = airCheck.get() == AirCheck.OFF || state.isOpaque();
|
||||||
|
boolean passesOreCheck = isOreBlock(state, ore);
|
||||||
|
|
||||||
|
if (passesAirCheck && passesOreCheck) {
|
||||||
|
if (shouldPlace(world, mutable, discardOnAir, random)) {
|
||||||
|
poses.add(new Vec3d(ah, aj, al));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +456,7 @@ public class OreSim extends Module {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Vec3d> generateHidden(ClientWorld world, ChunkRandom random, BlockPos blockPos, int size) {
|
private ArrayList<Vec3d> generateHidden(ClientWorld world, ChunkRandom random, BlockPos blockPos, int size, Ore ore) {
|
||||||
|
|
||||||
ArrayList<Vec3d> poses = new ArrayList<>();
|
ArrayList<Vec3d> poses = new ArrayList<>();
|
||||||
|
|
||||||
@@ -435,8 +467,14 @@ public class OreSim extends Module {
|
|||||||
int x = this.randomCoord(random, size) + blockPos.getX();
|
int x = this.randomCoord(random, size) + blockPos.getX();
|
||||||
int y = this.randomCoord(random, size) + blockPos.getY();
|
int y = this.randomCoord(random, size) + blockPos.getY();
|
||||||
int z = this.randomCoord(random, size) + blockPos.getZ();
|
int z = this.randomCoord(random, size) + blockPos.getZ();
|
||||||
if (airCheck.get() == AirCheck.OFF || world.getBlockState(new BlockPos(x, y, z)).isOpaque()) {
|
BlockPos pos = new BlockPos(x, y, z);
|
||||||
if (shouldPlace(world, new BlockPos(x, y, z), 1F, random)) {
|
BlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
|
boolean passesAirCheck = airCheck.get() == AirCheck.OFF || state.isOpaque();
|
||||||
|
boolean passesOreCheck = isOreBlock(state, ore);
|
||||||
|
|
||||||
|
if (passesAirCheck && passesOreCheck) {
|
||||||
|
if (shouldPlace(world, pos, 1F, random)) {
|
||||||
poses.add(new Vec3d(x, y, z));
|
poses.add(new Vec3d(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,4 +486,4 @@ public class OreSim extends Module {
|
|||||||
private int randomCoord(ChunkRandom random, int size) {
|
private int randomCoord(ChunkRandom random, int size) {
|
||||||
return Math.round((random.nextFloat() - random.nextFloat()) * (float) size);
|
return Math.round((random.nextFloat() - random.nextFloat()) * (float) size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
"description": "An addon to Meteor Client that adds modules and commands that were too useless to be added to Meteor directly.",
|
"description": "An addon to Meteor Client that adds modules and commands that were too useless to be added to Meteor directly.",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Cloudburst",
|
"Cloudburst",
|
||||||
"StormyBytes"
|
"StormyBytes",
|
||||||
|
"Morpheus Nox"
|
||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"issues": "https://github.com/AntiCope/meteor-rejects/issues",
|
"issues": "https://github.com/AntiCope/meteor-rejects/issues",
|
||||||
|
|||||||
Reference in New Issue
Block a user