Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Часть функционала AppleFarmer 3.1exp // all base

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
6 Янв 2025
Сообщения
154
Реакции
0
Выберите загрузчик игры
  1. Vanilla
  2. Forge
  3. Fabric
короче эпл фармер покупает сам оопыт и сам чинит при выборе мотыги он ломает листву мотыгоой типо там удача и т.д есть рабоота с баритоном(из-за него багается) убрать моожно на изи и доработать короче ИИ в поомощь думаю вы поймете все P.S тут 600+ строк есчо

Пожалуйста, авторизуйтесь для просмотра ссылки.



AppleFarmer:
Expand Collapse Copy
package fun.danq.constructor.modules.impl.player;

import fun.danq.constructor.api.events.orbit.EventHandler;
import fun.danq.constructor.events.other.TickEvent;
import fun.danq.constructor.mods.baritone.api.BaritoneAPI;
import fun.danq.constructor.mods.baritone.api.pathing.goals.GoalBlock;
import fun.danq.constructor.modules.Category;
import fun.danq.constructor.modules.Module;
import fun.danq.constructor.modules.ModuleInfo;
import fun.danq.constructor.modules.settings.impl.ModeSetting;
import fun.danq.utils.chat.ChatUtil;
import fun.danq.utils.math.StopWatch;
import fun.danq.utils.player.InventoryUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.item.*;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;

import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Items;
import net.minecraft.util.math.AxisAlignedBB;
import java.util.ArrayList;
import java.util.List;

import fun.danq.constructor.modules.settings.impl.BooleanSetting;
import fun.danq.constructor.modules.settings.impl.SliderSetting;

@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "AutoAppleFarm", description = "Автоматически выращивает и рубит деревья для фарма яблок", category = Category.PLAYER)
public class AutoAppleFarm extends Module {

    private enum FarmState {
        IDLE, PLANT_SAPLING, GROW_TREE, MINE_LEAVES, MINE_LOG, RETURN_TO_POS, COLLECT_DROPS, REPAIR_HOE, BUY_XP
    }

    private final ModeSetting growMode = new ModeSetting(this, "Режим роста", "Костная мука", "Мотыга");
    private final BooleanSetting autoRepair = new BooleanSetting(this, "Автопочинка мотыги", true);
    private final SliderSetting buyXpAmount = new SliderSetting(this, "Ск. стаков покупать", 3, 1, 10, 1);

    private int xpBought = 0;

    private FarmState currentState = FarmState.IDLE;
    private BlockPos farmPos = null;
    private BlockPos standPos = null;
    private final StopWatch delayTimer = new StopWatch();
    private final StopWatch warnTimer = new StopWatch();

    private float targetYaw, targetPitch;
    private boolean rotationReached = false;
    private static final float ROTATION_SPEED = 30.0F;

    private boolean oldAllowPlace;
    private boolean oldAllowBreak;

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player != null) {
            Direction facing = mc.player.getHorizontalFacing();
            farmPos = mc.player.getPosition().offset(facing, 2);
            standPos = mc.player.getPosition();
            currentState = FarmState.IDLE;
            delayTimer.reset();
            warnTimer.reset();
            rotationReached = false;
            
            ChatUtil.draw("§a[AutoAppleFarm] §fСаженец будет на: " + farmPos.getX() + ", " + farmPos.getY() + ", " + farmPos.getZ());
        }
    }

    @Override
    public void onDisable() {
        super.onDisable();
        currentState = FarmState.IDLE;
        cancelBaritone();
    }

    private void cancelBaritone() {
        try {
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().cancel();
            }
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoal(null);
            }
            fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything();
        } catch (Exception ignored) {}
    }

    @EventHandler
    public void onTick(TickEvent event) {
        if (mc.player == null || mc.world == null || farmPos == null) return;

        boolean requiresStand = currentState == FarmState.IDLE || currentState == FarmState.PLANT_SAPLING ||
                                currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES ||
                                currentState == FarmState.MINE_LOG;

        if (requiresStand) {
            double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
            if (mc.player.getPosY() < farmPos.getY() + 1 || distToStand > 1.5) {
                if (warnTimer.hasTimeElapsed(3000, true)) {
                    ChatUtil.draw("§e[AutoAppleFarm] §fСпустился с блока. Возвращаюсь назад...");
                }
                currentState = FarmState.RETURN_TO_POS;
                delayTimer.reset();
                return;
            }
        }

        if (currentState == FarmState.PLANT_SAPLING || currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES || currentState == FarmState.MINE_LOG) {
            updateSmoothRotation();
        }

        BlockState stateAtPos = mc.world.getBlockState(farmPos);
        BlockState stateBelow = mc.world.getBlockState(farmPos.down());

        switch (currentState) {
            case IDLE:
                if (isLog(stateAtPos)) {
                    currentState = FarmState.MINE_LOG;
                    delayTimer.reset();
                } else if (isSaplingBlock(stateAtPos)) {
                    currentState = FarmState.GROW_TREE;
                    delayTimer.reset();
                } else if (stateAtPos.getBlock() == Blocks.AIR && isDirtLike(stateBelow)) {
                    currentState = FarmState.PLANT_SAPLING;
                    delayTimer.reset();
                }
                break;

            case PLANT_SAPLING:
                handlePlantSapling();
                break;

            case GROW_TREE:
                handleGrowTree(stateAtPos);
                break;

            case MINE_LEAVES:
                handleMineLeaves();
                break;

            case MINE_LOG:
                handleMineLog();
                break;

            case RETURN_TO_POS:
                handleReturnToPos();
                break;

            case COLLECT_DROPS:
                handleCollectDrops();
                break;

            case REPAIR_HOE:
                handleRepairHoe();
                break;

            case BUY_XP:
                handleBuyXp();
                break;
        }
    }

    private void handlePlantSapling() {
        if (!delayTimer.hasTimeElapsed(400, false)) return;

        int saplingSlot = findHotbarSlot(true, false, false);
        if (saplingSlot == -1) {
            ChatUtil.draw("§c[AutoAppleFarm] §fСаженцы не найдены в хотбаре!");
            toggle();
            return;
        }

        switchSlot(saplingSlot);
        setTargetRotation(farmPos.down());

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY(), farmPos.getZ() + 0.5),
                Direction.UP, farmPos.down(), false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        currentState = FarmState.IDLE;
        delayTimer.reset();
    }

    private void handleGrowTree(BlockState stateAtPos) {
        if (isLog(stateAtPos)) {
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        boolean useHoe = growMode.is("Мотыга");
        int toolSlot;

        if (useHoe) {
            toolSlot = findHotbarSlot(false, false, true);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fМотыга не найдена в хотбаре!");
                toggle();
                return;
            }
        } else {
            toolSlot = findHotbarSlot(false, true, false);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fКостная мука не найдена в хотбаре!");
                toggle();
                return;
            }
        }

        switchSlot(toolSlot);
        setTargetRotation(farmPos);

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY() + 0.5, farmPos.getZ() + 0.5),
                Direction.UP, farmPos, false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private void handleMineLeaves() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos leavesPos = findNearestLeaves();

        if (leavesPos == null) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        double dist = mc.player.getPositionVec().distanceTo(new Vector3d(leavesPos.getX() + 0.5, leavesPos.getY() + 0.5, leavesPos.getZ() + 0.5));
        if (dist > 4.5) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        setTargetRotation(leavesPos);
        if (!rotationReached) return;

        breakBlockWithMode(leavesPos);

        delayTimer.reset();
    }

    private void handleMineLog() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos logPos = findHighestLog();

        if (logPos == null) {
            cancelBaritone();
            currentState = FarmState.RETURN_TO_POS;
            delayTimer.reset();
            return;
        }

        int axeSlot = InventoryUtil.getAxeInInventory(true);
        if (axeSlot != -1) {
            switchSlot(axeSlot);
        }

        setTargetRotation(logPos);
        if (!rotationReached) return;

        mc.playerController.onPlayerDamageBlock(logPos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private BlockPos findHighestLog() {
        BlockPos bestLog = null;
        for (int x = -2; x <= 2; x++) {
            for (int y = 0; y <= 7; y++) {
                for (int z = -2; z <= 2; z++) {
                    BlockPos checkPos = farmPos.add(x, y, z);
                    BlockState state = mc.world.getBlockState(checkPos);
                    if (isLog(state)) {
                        if (bestLog == null || checkPos.getY() > bestLog.getY()) {
                            bestLog = checkPos;
                        }
                    }
                }
            }
        }
        return bestLog;
    }

    private void handleReturnToPos() {
        if (standPos == null) {
            currentState = FarmState.MINE_LEAVES;
            return;
        }

        double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
        
        if (distToStand <= 1.5 || (mc.player.getPosition().getX() == standPos.getX() && mc.player.getPosition().getZ() == standPos.getZ())) {
            cancelBaritone();
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        BlockPos targetLeaf = null;
        for (int i = 0; i <= 3; i++) {
            BlockPos checkPos = standPos.up(i);
            if (!mc.world.isAirBlock(checkPos) && mc.world.getBlockState(checkPos).getBlock() instanceof LeavesBlock) {
                targetLeaf = checkPos;
                break;
            }
        }

        if (targetLeaf != null) {
            cancelBaritone();
            setTargetRotation(targetLeaf);
            updateSmoothRotation();
            if (rotationReached) {
                breakBlockWithMode(targetLeaf);
            }
            return;
        }

        if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
            BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(standPos));
        }
    }

    private void breakBlockWithMode(BlockPos pos) {
        if (growMode.is("Мотыга")) {
            int hoeSlot = findHoeInHotbar();
            if (hoeSlot != -1) {
                switchSlot(hoeSlot);
                ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
                if (autoRepair.getValue() && hoe.getMaxDamage() - hoe.getDamage() < 15) {
                    currentState = FarmState.REPAIR_HOE;
                    delayTimer.reset();
                    return;
                }
            }
        }
        mc.playerController.onPlayerDamageBlock(pos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);
    }

    private int findHoeInHotbar() {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() instanceof net.minecraft.item.HoeItem) {
                return i;
            }
        }
        return -1;
    }

    private int findItemInHotbar(net.minecraft.item.Item item) {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() == item) {
                return i;
            }
        }
        return -1;
    }

    private void handleRepairHoe() {
        if (!delayTimer.hasTimeElapsed(150, false)) return;

        int hoeSlot = findHoeInHotbar();
        if (hoeSlot == -1) {
            currentState = FarmState.IDLE;
            return;
        }

        ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
        if (hoe.getDamage() == 0 || (hoe.getMaxDamage() - hoe.getDamage() > hoe.getMaxDamage() * 0.9)) {
            currentState = FarmState.IDLE;
            return;
        }

        int xpSlot = findItemInHotbar(Items.EXPERIENCE_BOTTLE);
        if (xpSlot == -1) {
            mc.player.sendChatMessage("/ah search Пузырек с опытом");
            currentState = FarmState.BUY_XP;
            xpBought = 0;
            delayTimer.reset();
            return;
        }

        targetPitch = 90.0F;
        targetYaw = mc.player.rotationYaw;
        updateSmoothRotation();

        if (rotationReached) {
            switchSlot(xpSlot);
            mc.playerController.processRightClick(mc.player, mc.world, Hand.MAIN_HAND);
            switchSlot(hoeSlot);
            delayTimer.reset();
        }
    }

    private void handleBuyXp() {
        if (!(mc.currentScreen instanceof ChestScreen)) {
            if (delayTimer.hasTimeElapsed(5000, false)) {
                currentState = FarmState.REPAIR_HOE;
                delayTimer.reset();
            }
            return;
        }

        ChestScreen screen = (ChestScreen) mc.currentScreen;
        String title = screen.getTitle().getString();
        if (!title.contains("Аукцион") && !title.contains("Поиск")) return;

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        Container container = screen.getContainer();
        
        int bestSlot = -1;
        int lowestPrice = Integer.MAX_VALUE;

        for (Slot slot : container.inventorySlots) {
            if (slot.slotNumber > 44) continue;
            
            ItemStack stack = slot.getStack();
            if (stack == null || stack.isEmpty()) continue;
            
            if (stack.getItem() == Items.EXPERIENCE_BOTTLE && stack.getCount() == 64) {
                int price = getAhPrice(stack);
                if (price > 0 && price < lowestPrice) {
                    lowestPrice = price;
                    bestSlot = slot.slotNumber;
                }
            }
        }

        if (bestSlot != -1) {
            mc.playerController.windowClick(container.windowId, bestSlot, 0, ClickType.QUICK_MOVE, mc.player);
            xpBought++;
            delayTimer.reset();
            
            if (xpBought >= buyXpAmount.getValue().intValue()) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        } else {
            if (delayTimer.hasTimeElapsed(3000, false)) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        }
    }

    private int getAhPrice(ItemStack stack) {
        net.minecraft.nbt.CompoundNBT tag = stack.getTag();
        if (tag != null && tag.contains("display", 10)) {
            net.minecraft.nbt.CompoundNBT display = tag.getCompound("display");
            if (display.contains("Lore", 9)) {
                net.minecraft.nbt.ListNBT lore = display.getList("Lore", 8);
                for (int j = 0; j < lore.size(); ++j) {
                    String loreLine = lore.getString(j).toLowerCase();
                    if (loreLine.contains("цена")) {
                        String priceText = loreLine.replaceAll("[^0-9]", "");
                        try {
                            return Integer.parseInt(priceText);
                        } catch (NumberFormatException ignored) {}
                    }
                }
            }
        }
        return -1;
    }

    private void handleCollectDrops() {
        if (!delayTimer.hasTimeElapsed(100, false)) return;

        List<ItemEntity> drops = mc.world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(farmPos).grow(8.0));
        ItemEntity nearestDrop = null;
        double nearestDist = Double.MAX_VALUE;

        for (ItemEntity drop : drops) {
            if (!drop.isAlive() || drop.getItem().isEmpty()) continue;
            net.minecraft.item.Item item = drop.getItem().getItem();
            if (item == Items.APPLE || item instanceof net.minecraft.item.BlockItem && ((net.minecraft.item.BlockItem)item).getBlock() instanceof net.minecraft.block.SaplingBlock) {
                double dist = mc.player.getDistanceSq(drop);
                if (dist < nearestDist) {
                    nearestDist = dist;
                    nearestDrop = drop;
                }
            }
        }

        if (nearestDrop != null) {
            BlockPos target = nearestDrop.getPosition();
            double distToDrop = mc.player.getPositionVec().distanceTo(new Vector3d(target.getX() + 0.5, target.getY() + 0.5, target.getZ() + 0.5));
            
            if (distToDrop <= 1.5) {
                return;
            }

            if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(target));
            }
        } else {
            cancelBaritone();
            currentState = FarmState.IDLE;
            delayTimer.reset();
        }
    }

    private void setTargetRotation(BlockPos pos) {
        double dx = (pos.getX() + 0.5) - mc.player.getPosX();
        double dy = (pos.getY() + 0.5) - (mc.player.getPosY() + mc.player.getEyeHeight());
        double dz = (pos.getZ() + 0.5) - mc.player.getPosZ();
        double dist = Math.sqrt(dx * dx + dz * dz);

        targetYaw = MathHelper.wrapDegrees((float) (Math.toDegrees(Math.atan2(dz, dx)) - 90.0));
        targetPitch = MathHelper.clamp((float) -(Math.toDegrees(Math.atan2(dy, dist))), -90.0F, 90.0F);

        float yawDiff = Math.abs(MathHelper.wrapDegrees(mc.player.rotationYaw - targetYaw));
        float pitchDiff = Math.abs(mc.player.rotationPitch - targetPitch);
        rotationReached = yawDiff < 5.0F && pitchDiff < 5.0F;
    }

    private void updateSmoothRotation() {
        float currentYaw = mc.player.rotationYaw;
        float currentPitch = mc.player.rotationPitch;

        float yawDiff = MathHelper.wrapDegrees(targetYaw - currentYaw);
        float pitchDiff = targetPitch - currentPitch;

        float yawStep = MathHelper.clamp(yawDiff, -ROTATION_SPEED, ROTATION_SPEED);
        float pitchStep = MathHelper.clamp(pitchDiff, -ROTATION_SPEED, ROTATION_SPEED);

        float newYaw = currentYaw + yawStep;
        float newPitch = MathHelper.clamp(currentPitch + pitchStep, -90.0F, 90.0F);

        mc.player.rotationYaw = newYaw;
        mc.player.rotationPitch = newPitch;
        mc.player.rotationYawHead = newYaw;

        mc.player.connection.sendPacket(new CPlayerPacket.RotationPacket(newYaw, newPitch, mc.player.isOnGround()));

        float yawRemaining = Math.abs(MathHelper.wrapDegrees(targetYaw - newYaw));
        float pitchRemaining = Math.abs(targetPitch - newPitch);
        rotationReached = yawRemaining < 3.0F && pitchRemaining < 3.0F;
    }

    private BlockPos findNearestLeaves() {
        List<BlockPos> leaves = new ArrayList<>();
        for (int x = -4; x <= 4; x++) {
            for (int y = 0; y <= 8; y++) {
                for (int z = -4; z <= 4; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (mc.world.getBlockState(pos).getBlock() instanceof LeavesBlock) {
                        leaves.add(pos);
                    }
                }
            }
        }
        if (leaves.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return leaves.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private BlockPos findNearestLog() {
        List<BlockPos> logs = new ArrayList<>();
        for (int x = -1; x <= 1; x++) {
            for (int y = 0; y <= 10; y++) {
                for (int z = -1; z <= 1; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (isLog(mc.world.getBlockState(pos))) {
                        logs.add(pos);
                    }
                }
            }
        }
        if (logs.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return logs.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private boolean isSaplingItem(Item item) {
        return item == Items.OAK_SAPLING || item == Items.SPRUCE_SAPLING || item == Items.BIRCH_SAPLING ||
               item == Items.JUNGLE_SAPLING || item == Items.ACACIA_SAPLING || item == Items.DARK_OAK_SAPLING;
    }

    private boolean isSaplingBlock(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_SAPLING || block == Blocks.SPRUCE_SAPLING || block == Blocks.BIRCH_SAPLING ||
               block == Blocks.JUNGLE_SAPLING || block == Blocks.ACACIA_SAPLING || block == Blocks.DARK_OAK_SAPLING;
    }

    private boolean isLog(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_LOG || block == Blocks.SPRUCE_LOG || block == Blocks.BIRCH_LOG ||
               block == Blocks.JUNGLE_LOG || block == Blocks.ACACIA_LOG || block == Blocks.DARK_OAK_LOG;
    }

    private boolean isDirtLike(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.DIRT || block == Blocks.GRASS_BLOCK || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL;
    }

    private void switchSlot(int slot) {
        if (mc.player.inventory.currentItem != slot) {
            mc.player.connection.sendPacket(new CHeldItemChangePacket(slot));
            mc.player.inventory.currentItem = slot;
        }
    }

    private int findHotbarSlot(boolean sapling, boolean boneMeal, boolean hoe) {
        for (int i = 0; i < 9; i++) {
            Item item = mc.player.inventory.getStackInSlot(i).getItem();
            if (sapling && isSaplingItem(item)) return i;
            if (boneMeal && item == Items.BONE_MEAL) return i;
            if (hoe && item instanceof HoeItem) return i;
        }
        return -1;
    }
}
 
короче эпл фармер покупает сам оопыт и сам чинит при выборе мотыги он ломает листву мотыгоой типо там удача и т.д есть рабоота с баритоном(из-за него багается) убрать моожно на изи и доработать короче ИИ в поомощь думаю вы поймете все P.S тут 600+ строк есчо

Пожалуйста, авторизуйтесь для просмотра ссылки.



AppleFarmer:
Expand Collapse Copy
package fun.danq.constructor.modules.impl.player;

import fun.danq.constructor.api.events.orbit.EventHandler;
import fun.danq.constructor.events.other.TickEvent;
import fun.danq.constructor.mods.baritone.api.BaritoneAPI;
import fun.danq.constructor.mods.baritone.api.pathing.goals.GoalBlock;
import fun.danq.constructor.modules.Category;
import fun.danq.constructor.modules.Module;
import fun.danq.constructor.modules.ModuleInfo;
import fun.danq.constructor.modules.settings.impl.ModeSetting;
import fun.danq.utils.chat.ChatUtil;
import fun.danq.utils.math.StopWatch;
import fun.danq.utils.player.InventoryUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.item.*;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;

import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Items;
import net.minecraft.util.math.AxisAlignedBB;
import java.util.ArrayList;
import java.util.List;

import fun.danq.constructor.modules.settings.impl.BooleanSetting;
import fun.danq.constructor.modules.settings.impl.SliderSetting;

@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "AutoAppleFarm", description = "Автоматически выращивает и рубит деревья для фарма яблок", category = Category.PLAYER)
public class AutoAppleFarm extends Module {

    private enum FarmState {
        IDLE, PLANT_SAPLING, GROW_TREE, MINE_LEAVES, MINE_LOG, RETURN_TO_POS, COLLECT_DROPS, REPAIR_HOE, BUY_XP
    }

    private final ModeSetting growMode = new ModeSetting(this, "Режим роста", "Костная мука", "Мотыга");
    private final BooleanSetting autoRepair = new BooleanSetting(this, "Автопочинка мотыги", true);
    private final SliderSetting buyXpAmount = new SliderSetting(this, "Ск. стаков покупать", 3, 1, 10, 1);

    private int xpBought = 0;

    private FarmState currentState = FarmState.IDLE;
    private BlockPos farmPos = null;
    private BlockPos standPos = null;
    private final StopWatch delayTimer = new StopWatch();
    private final StopWatch warnTimer = new StopWatch();

    private float targetYaw, targetPitch;
    private boolean rotationReached = false;
    private static final float ROTATION_SPEED = 30.0F;

    private boolean oldAllowPlace;
    private boolean oldAllowBreak;

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player != null) {
            Direction facing = mc.player.getHorizontalFacing();
            farmPos = mc.player.getPosition().offset(facing, 2);
            standPos = mc.player.getPosition();
            currentState = FarmState.IDLE;
            delayTimer.reset();
            warnTimer.reset();
            rotationReached = false;
           
            ChatUtil.draw("§a[AutoAppleFarm] §fСаженец будет на: " + farmPos.getX() + ", " + farmPos.getY() + ", " + farmPos.getZ());
        }
    }

    @Override
    public void onDisable() {
        super.onDisable();
        currentState = FarmState.IDLE;
        cancelBaritone();
    }

    private void cancelBaritone() {
        try {
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().cancel();
            }
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoal(null);
            }
            fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything();
        } catch (Exception ignored) {}
    }

    @EventHandler
    public void onTick(TickEvent event) {
        if (mc.player == null || mc.world == null || farmPos == null) return;

        boolean requiresStand = currentState == FarmState.IDLE || currentState == FarmState.PLANT_SAPLING ||
                                currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES ||
                                currentState == FarmState.MINE_LOG;

        if (requiresStand) {
            double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
            if (mc.player.getPosY() < farmPos.getY() + 1 || distToStand > 1.5) {
                if (warnTimer.hasTimeElapsed(3000, true)) {
                    ChatUtil.draw("§e[AutoAppleFarm] §fСпустился с блока. Возвращаюсь назад...");
                }
                currentState = FarmState.RETURN_TO_POS;
                delayTimer.reset();
                return;
            }
        }

        if (currentState == FarmState.PLANT_SAPLING || currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES || currentState == FarmState.MINE_LOG) {
            updateSmoothRotation();
        }

        BlockState stateAtPos = mc.world.getBlockState(farmPos);
        BlockState stateBelow = mc.world.getBlockState(farmPos.down());

        switch (currentState) {
            case IDLE:
                if (isLog(stateAtPos)) {
                    currentState = FarmState.MINE_LOG;
                    delayTimer.reset();
                } else if (isSaplingBlock(stateAtPos)) {
                    currentState = FarmState.GROW_TREE;
                    delayTimer.reset();
                } else if (stateAtPos.getBlock() == Blocks.AIR && isDirtLike(stateBelow)) {
                    currentState = FarmState.PLANT_SAPLING;
                    delayTimer.reset();
                }
                break;

            case PLANT_SAPLING:
                handlePlantSapling();
                break;

            case GROW_TREE:
                handleGrowTree(stateAtPos);
                break;

            case MINE_LEAVES:
                handleMineLeaves();
                break;

            case MINE_LOG:
                handleMineLog();
                break;

            case RETURN_TO_POS:
                handleReturnToPos();
                break;

            case COLLECT_DROPS:
                handleCollectDrops();
                break;

            case REPAIR_HOE:
                handleRepairHoe();
                break;

            case BUY_XP:
                handleBuyXp();
                break;
        }
    }

    private void handlePlantSapling() {
        if (!delayTimer.hasTimeElapsed(400, false)) return;

        int saplingSlot = findHotbarSlot(true, false, false);
        if (saplingSlot == -1) {
            ChatUtil.draw("§c[AutoAppleFarm] §fСаженцы не найдены в хотбаре!");
            toggle();
            return;
        }

        switchSlot(saplingSlot);
        setTargetRotation(farmPos.down());

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY(), farmPos.getZ() + 0.5),
                Direction.UP, farmPos.down(), false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        currentState = FarmState.IDLE;
        delayTimer.reset();
    }

    private void handleGrowTree(BlockState stateAtPos) {
        if (isLog(stateAtPos)) {
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        boolean useHoe = growMode.is("Мотыга");
        int toolSlot;

        if (useHoe) {
            toolSlot = findHotbarSlot(false, false, true);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fМотыга не найдена в хотбаре!");
                toggle();
                return;
            }
        } else {
            toolSlot = findHotbarSlot(false, true, false);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fКостная мука не найдена в хотбаре!");
                toggle();
                return;
            }
        }

        switchSlot(toolSlot);
        setTargetRotation(farmPos);

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY() + 0.5, farmPos.getZ() + 0.5),
                Direction.UP, farmPos, false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private void handleMineLeaves() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos leavesPos = findNearestLeaves();

        if (leavesPos == null) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        double dist = mc.player.getPositionVec().distanceTo(new Vector3d(leavesPos.getX() + 0.5, leavesPos.getY() + 0.5, leavesPos.getZ() + 0.5));
        if (dist > 4.5) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        setTargetRotation(leavesPos);
        if (!rotationReached) return;

        breakBlockWithMode(leavesPos);

        delayTimer.reset();
    }

    private void handleMineLog() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos logPos = findHighestLog();

        if (logPos == null) {
            cancelBaritone();
            currentState = FarmState.RETURN_TO_POS;
            delayTimer.reset();
            return;
        }

        int axeSlot = InventoryUtil.getAxeInInventory(true);
        if (axeSlot != -1) {
            switchSlot(axeSlot);
        }

        setTargetRotation(logPos);
        if (!rotationReached) return;

        mc.playerController.onPlayerDamageBlock(logPos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private BlockPos findHighestLog() {
        BlockPos bestLog = null;
        for (int x = -2; x <= 2; x++) {
            for (int y = 0; y <= 7; y++) {
                for (int z = -2; z <= 2; z++) {
                    BlockPos checkPos = farmPos.add(x, y, z);
                    BlockState state = mc.world.getBlockState(checkPos);
                    if (isLog(state)) {
                        if (bestLog == null || checkPos.getY() > bestLog.getY()) {
                            bestLog = checkPos;
                        }
                    }
                }
            }
        }
        return bestLog;
    }

    private void handleReturnToPos() {
        if (standPos == null) {
            currentState = FarmState.MINE_LEAVES;
            return;
        }

        double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
       
        if (distToStand <= 1.5 || (mc.player.getPosition().getX() == standPos.getX() && mc.player.getPosition().getZ() == standPos.getZ())) {
            cancelBaritone();
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        BlockPos targetLeaf = null;
        for (int i = 0; i <= 3; i++) {
            BlockPos checkPos = standPos.up(i);
            if (!mc.world.isAirBlock(checkPos) && mc.world.getBlockState(checkPos).getBlock() instanceof LeavesBlock) {
                targetLeaf = checkPos;
                break;
            }
        }

        if (targetLeaf != null) {
            cancelBaritone();
            setTargetRotation(targetLeaf);
            updateSmoothRotation();
            if (rotationReached) {
                breakBlockWithMode(targetLeaf);
            }
            return;
        }

        if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
            BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(standPos));
        }
    }

    private void breakBlockWithMode(BlockPos pos) {
        if (growMode.is("Мотыга")) {
            int hoeSlot = findHoeInHotbar();
            if (hoeSlot != -1) {
                switchSlot(hoeSlot);
                ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
                if (autoRepair.getValue() && hoe.getMaxDamage() - hoe.getDamage() < 15) {
                    currentState = FarmState.REPAIR_HOE;
                    delayTimer.reset();
                    return;
                }
            }
        }
        mc.playerController.onPlayerDamageBlock(pos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);
    }

    private int findHoeInHotbar() {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() instanceof net.minecraft.item.HoeItem) {
                return i;
            }
        }
        return -1;
    }

    private int findItemInHotbar(net.minecraft.item.Item item) {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() == item) {
                return i;
            }
        }
        return -1;
    }

    private void handleRepairHoe() {
        if (!delayTimer.hasTimeElapsed(150, false)) return;

        int hoeSlot = findHoeInHotbar();
        if (hoeSlot == -1) {
            currentState = FarmState.IDLE;
            return;
        }

        ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
        if (hoe.getDamage() == 0 || (hoe.getMaxDamage() - hoe.getDamage() > hoe.getMaxDamage() * 0.9)) {
            currentState = FarmState.IDLE;
            return;
        }

        int xpSlot = findItemInHotbar(Items.EXPERIENCE_BOTTLE);
        if (xpSlot == -1) {
            mc.player.sendChatMessage("/ah search Пузырек с опытом");
            currentState = FarmState.BUY_XP;
            xpBought = 0;
            delayTimer.reset();
            return;
        }

        targetPitch = 90.0F;
        targetYaw = mc.player.rotationYaw;
        updateSmoothRotation();

        if (rotationReached) {
            switchSlot(xpSlot);
            mc.playerController.processRightClick(mc.player, mc.world, Hand.MAIN_HAND);
            switchSlot(hoeSlot);
            delayTimer.reset();
        }
    }

    private void handleBuyXp() {
        if (!(mc.currentScreen instanceof ChestScreen)) {
            if (delayTimer.hasTimeElapsed(5000, false)) {
                currentState = FarmState.REPAIR_HOE;
                delayTimer.reset();
            }
            return;
        }

        ChestScreen screen = (ChestScreen) mc.currentScreen;
        String title = screen.getTitle().getString();
        if (!title.contains("Аукцион") && !title.contains("Поиск")) return;

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        Container container = screen.getContainer();
       
        int bestSlot = -1;
        int lowestPrice = Integer.MAX_VALUE;

        for (Slot slot : container.inventorySlots) {
            if (slot.slotNumber > 44) continue;
           
            ItemStack stack = slot.getStack();
            if (stack == null || stack.isEmpty()) continue;
           
            if (stack.getItem() == Items.EXPERIENCE_BOTTLE && stack.getCount() == 64) {
                int price = getAhPrice(stack);
                if (price > 0 && price < lowestPrice) {
                    lowestPrice = price;
                    bestSlot = slot.slotNumber;
                }
            }
        }

        if (bestSlot != -1) {
            mc.playerController.windowClick(container.windowId, bestSlot, 0, ClickType.QUICK_MOVE, mc.player);
            xpBought++;
            delayTimer.reset();
           
            if (xpBought >= buyXpAmount.getValue().intValue()) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        } else {
            if (delayTimer.hasTimeElapsed(3000, false)) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        }
    }

    private int getAhPrice(ItemStack stack) {
        net.minecraft.nbt.CompoundNBT tag = stack.getTag();
        if (tag != null && tag.contains("display", 10)) {
            net.minecraft.nbt.CompoundNBT display = tag.getCompound("display");
            if (display.contains("Lore", 9)) {
                net.minecraft.nbt.ListNBT lore = display.getList("Lore", 8);
                for (int j = 0; j < lore.size(); ++j) {
                    String loreLine = lore.getString(j).toLowerCase();
                    if (loreLine.contains("цена")) {
                        String priceText = loreLine.replaceAll("[^0-9]", "");
                        try {
                            return Integer.parseInt(priceText);
                        } catch (NumberFormatException ignored) {}
                    }
                }
            }
        }
        return -1;
    }

    private void handleCollectDrops() {
        if (!delayTimer.hasTimeElapsed(100, false)) return;

        List<ItemEntity> drops = mc.world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(farmPos).grow(8.0));
        ItemEntity nearestDrop = null;
        double nearestDist = Double.MAX_VALUE;

        for (ItemEntity drop : drops) {
            if (!drop.isAlive() || drop.getItem().isEmpty()) continue;
            net.minecraft.item.Item item = drop.getItem().getItem();
            if (item == Items.APPLE || item instanceof net.minecraft.item.BlockItem && ((net.minecraft.item.BlockItem)item).getBlock() instanceof net.minecraft.block.SaplingBlock) {
                double dist = mc.player.getDistanceSq(drop);
                if (dist < nearestDist) {
                    nearestDist = dist;
                    nearestDrop = drop;
                }
            }
        }

        if (nearestDrop != null) {
            BlockPos target = nearestDrop.getPosition();
            double distToDrop = mc.player.getPositionVec().distanceTo(new Vector3d(target.getX() + 0.5, target.getY() + 0.5, target.getZ() + 0.5));
           
            if (distToDrop <= 1.5) {
                return;
            }

            if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(target));
            }
        } else {
            cancelBaritone();
            currentState = FarmState.IDLE;
            delayTimer.reset();
        }
    }

    private void setTargetRotation(BlockPos pos) {
        double dx = (pos.getX() + 0.5) - mc.player.getPosX();
        double dy = (pos.getY() + 0.5) - (mc.player.getPosY() + mc.player.getEyeHeight());
        double dz = (pos.getZ() + 0.5) - mc.player.getPosZ();
        double dist = Math.sqrt(dx * dx + dz * dz);

        targetYaw = MathHelper.wrapDegrees((float) (Math.toDegrees(Math.atan2(dz, dx)) - 90.0));
        targetPitch = MathHelper.clamp((float) -(Math.toDegrees(Math.atan2(dy, dist))), -90.0F, 90.0F);

        float yawDiff = Math.abs(MathHelper.wrapDegrees(mc.player.rotationYaw - targetYaw));
        float pitchDiff = Math.abs(mc.player.rotationPitch - targetPitch);
        rotationReached = yawDiff < 5.0F && pitchDiff < 5.0F;
    }

    private void updateSmoothRotation() {
        float currentYaw = mc.player.rotationYaw;
        float currentPitch = mc.player.rotationPitch;

        float yawDiff = MathHelper.wrapDegrees(targetYaw - currentYaw);
        float pitchDiff = targetPitch - currentPitch;

        float yawStep = MathHelper.clamp(yawDiff, -ROTATION_SPEED, ROTATION_SPEED);
        float pitchStep = MathHelper.clamp(pitchDiff, -ROTATION_SPEED, ROTATION_SPEED);

        float newYaw = currentYaw + yawStep;
        float newPitch = MathHelper.clamp(currentPitch + pitchStep, -90.0F, 90.0F);

        mc.player.rotationYaw = newYaw;
        mc.player.rotationPitch = newPitch;
        mc.player.rotationYawHead = newYaw;

        mc.player.connection.sendPacket(new CPlayerPacket.RotationPacket(newYaw, newPitch, mc.player.isOnGround()));

        float yawRemaining = Math.abs(MathHelper.wrapDegrees(targetYaw - newYaw));
        float pitchRemaining = Math.abs(targetPitch - newPitch);
        rotationReached = yawRemaining < 3.0F && pitchRemaining < 3.0F;
    }

    private BlockPos findNearestLeaves() {
        List<BlockPos> leaves = new ArrayList<>();
        for (int x = -4; x <= 4; x++) {
            for (int y = 0; y <= 8; y++) {
                for (int z = -4; z <= 4; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (mc.world.getBlockState(pos).getBlock() instanceof LeavesBlock) {
                        leaves.add(pos);
                    }
                }
            }
        }
        if (leaves.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return leaves.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private BlockPos findNearestLog() {
        List<BlockPos> logs = new ArrayList<>();
        for (int x = -1; x <= 1; x++) {
            for (int y = 0; y <= 10; y++) {
                for (int z = -1; z <= 1; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (isLog(mc.world.getBlockState(pos))) {
                        logs.add(pos);
                    }
                }
            }
        }
        if (logs.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return logs.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private boolean isSaplingItem(Item item) {
        return item == Items.OAK_SAPLING || item == Items.SPRUCE_SAPLING || item == Items.BIRCH_SAPLING ||
               item == Items.JUNGLE_SAPLING || item == Items.ACACIA_SAPLING || item == Items.DARK_OAK_SAPLING;
    }

    private boolean isSaplingBlock(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_SAPLING || block == Blocks.SPRUCE_SAPLING || block == Blocks.BIRCH_SAPLING ||
               block == Blocks.JUNGLE_SAPLING || block == Blocks.ACACIA_SAPLING || block == Blocks.DARK_OAK_SAPLING;
    }

    private boolean isLog(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_LOG || block == Blocks.SPRUCE_LOG || block == Blocks.BIRCH_LOG ||
               block == Blocks.JUNGLE_LOG || block == Blocks.ACACIA_LOG || block == Blocks.DARK_OAK_LOG;
    }

    private boolean isDirtLike(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.DIRT || block == Blocks.GRASS_BLOCK || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL;
    }

    private void switchSlot(int slot) {
        if (mc.player.inventory.currentItem != slot) {
            mc.player.connection.sendPacket(new CHeldItemChangePacket(slot));
            mc.player.inventory.currentItem = slot;
        }
    }

    private int findHotbarSlot(boolean sapling, boolean boneMeal, boolean hoe) {
        for (int i = 0; i < 9; i++) {
            Item item = mc.player.inventory.getStackInSlot(i).getItem();
            if (sapling && isSaplingItem(item)) return i;
            if (boneMeal && item == Items.BONE_MEAL) return i;
            if (hoe && item instanceof HoeItem) return i;
        }
        return -1;
    }
}
тип еще сидит на мертвой экспе брух :NotLikeThis:
 
короче эпл фармер покупает сам оопыт и сам чинит при выборе мотыги он ломает листву мотыгоой типо там удача и т.д есть рабоота с баритоном(из-за него багается) убрать моожно на изи и доработать короче ИИ в поомощь думаю вы поймете все P.S тут 600+ строк есчо

Пожалуйста, авторизуйтесь для просмотра ссылки.



AppleFarmer:
Expand Collapse Copy
package fun.danq.constructor.modules.impl.player;

import fun.danq.constructor.api.events.orbit.EventHandler;
import fun.danq.constructor.events.other.TickEvent;
import fun.danq.constructor.mods.baritone.api.BaritoneAPI;
import fun.danq.constructor.mods.baritone.api.pathing.goals.GoalBlock;
import fun.danq.constructor.modules.Category;
import fun.danq.constructor.modules.Module;
import fun.danq.constructor.modules.ModuleInfo;
import fun.danq.constructor.modules.settings.impl.ModeSetting;
import fun.danq.utils.chat.ChatUtil;
import fun.danq.utils.math.StopWatch;
import fun.danq.utils.player.InventoryUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.item.*;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;

import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Items;
import net.minecraft.util.math.AxisAlignedBB;
import java.util.ArrayList;
import java.util.List;

import fun.danq.constructor.modules.settings.impl.BooleanSetting;
import fun.danq.constructor.modules.settings.impl.SliderSetting;

@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "AutoAppleFarm", description = "Автоматически выращивает и рубит деревья для фарма яблок", category = Category.PLAYER)
public class AutoAppleFarm extends Module {

    private enum FarmState {
        IDLE, PLANT_SAPLING, GROW_TREE, MINE_LEAVES, MINE_LOG, RETURN_TO_POS, COLLECT_DROPS, REPAIR_HOE, BUY_XP
    }

    private final ModeSetting growMode = new ModeSetting(this, "Режим роста", "Костная мука", "Мотыга");
    private final BooleanSetting autoRepair = new BooleanSetting(this, "Автопочинка мотыги", true);
    private final SliderSetting buyXpAmount = new SliderSetting(this, "Ск. стаков покупать", 3, 1, 10, 1);

    private int xpBought = 0;

    private FarmState currentState = FarmState.IDLE;
    private BlockPos farmPos = null;
    private BlockPos standPos = null;
    private final StopWatch delayTimer = new StopWatch();
    private final StopWatch warnTimer = new StopWatch();

    private float targetYaw, targetPitch;
    private boolean rotationReached = false;
    private static final float ROTATION_SPEED = 30.0F;

    private boolean oldAllowPlace;
    private boolean oldAllowBreak;

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player != null) {
            Direction facing = mc.player.getHorizontalFacing();
            farmPos = mc.player.getPosition().offset(facing, 2);
            standPos = mc.player.getPosition();
            currentState = FarmState.IDLE;
            delayTimer.reset();
            warnTimer.reset();
            rotationReached = false;
           
            ChatUtil.draw("§a[AutoAppleFarm] §fСаженец будет на: " + farmPos.getX() + ", " + farmPos.getY() + ", " + farmPos.getZ());
        }
    }

    @Override
    public void onDisable() {
        super.onDisable();
        currentState = FarmState.IDLE;
        cancelBaritone();
    }

    private void cancelBaritone() {
        try {
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().cancel();
            }
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoal(null);
            }
            fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything();
        } catch (Exception ignored) {}
    }

    @EventHandler
    public void onTick(TickEvent event) {
        if (mc.player == null || mc.world == null || farmPos == null) return;

        boolean requiresStand = currentState == FarmState.IDLE || currentState == FarmState.PLANT_SAPLING ||
                                currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES ||
                                currentState == FarmState.MINE_LOG;

        if (requiresStand) {
            double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
            if (mc.player.getPosY() < farmPos.getY() + 1 || distToStand > 1.5) {
                if (warnTimer.hasTimeElapsed(3000, true)) {
                    ChatUtil.draw("§e[AutoAppleFarm] §fСпустился с блока. Возвращаюсь назад...");
                }
                currentState = FarmState.RETURN_TO_POS;
                delayTimer.reset();
                return;
            }
        }

        if (currentState == FarmState.PLANT_SAPLING || currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES || currentState == FarmState.MINE_LOG) {
            updateSmoothRotation();
        }

        BlockState stateAtPos = mc.world.getBlockState(farmPos);
        BlockState stateBelow = mc.world.getBlockState(farmPos.down());

        switch (currentState) {
            case IDLE:
                if (isLog(stateAtPos)) {
                    currentState = FarmState.MINE_LOG;
                    delayTimer.reset();
                } else if (isSaplingBlock(stateAtPos)) {
                    currentState = FarmState.GROW_TREE;
                    delayTimer.reset();
                } else if (stateAtPos.getBlock() == Blocks.AIR && isDirtLike(stateBelow)) {
                    currentState = FarmState.PLANT_SAPLING;
                    delayTimer.reset();
                }
                break;

            case PLANT_SAPLING:
                handlePlantSapling();
                break;

            case GROW_TREE:
                handleGrowTree(stateAtPos);
                break;

            case MINE_LEAVES:
                handleMineLeaves();
                break;

            case MINE_LOG:
                handleMineLog();
                break;

            case RETURN_TO_POS:
                handleReturnToPos();
                break;

            case COLLECT_DROPS:
                handleCollectDrops();
                break;

            case REPAIR_HOE:
                handleRepairHoe();
                break;

            case BUY_XP:
                handleBuyXp();
                break;
        }
    }

    private void handlePlantSapling() {
        if (!delayTimer.hasTimeElapsed(400, false)) return;

        int saplingSlot = findHotbarSlot(true, false, false);
        if (saplingSlot == -1) {
            ChatUtil.draw("§c[AutoAppleFarm] §fСаженцы не найдены в хотбаре!");
            toggle();
            return;
        }

        switchSlot(saplingSlot);
        setTargetRotation(farmPos.down());

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY(), farmPos.getZ() + 0.5),
                Direction.UP, farmPos.down(), false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        currentState = FarmState.IDLE;
        delayTimer.reset();
    }

    private void handleGrowTree(BlockState stateAtPos) {
        if (isLog(stateAtPos)) {
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        boolean useHoe = growMode.is("Мотыга");
        int toolSlot;

        if (useHoe) {
            toolSlot = findHotbarSlot(false, false, true);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fМотыга не найдена в хотбаре!");
                toggle();
                return;
            }
        } else {
            toolSlot = findHotbarSlot(false, true, false);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fКостная мука не найдена в хотбаре!");
                toggle();
                return;
            }
        }

        switchSlot(toolSlot);
        setTargetRotation(farmPos);

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY() + 0.5, farmPos.getZ() + 0.5),
                Direction.UP, farmPos, false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private void handleMineLeaves() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos leavesPos = findNearestLeaves();

        if (leavesPos == null) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        double dist = mc.player.getPositionVec().distanceTo(new Vector3d(leavesPos.getX() + 0.5, leavesPos.getY() + 0.5, leavesPos.getZ() + 0.5));
        if (dist > 4.5) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        setTargetRotation(leavesPos);
        if (!rotationReached) return;

        breakBlockWithMode(leavesPos);

        delayTimer.reset();
    }

    private void handleMineLog() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos logPos = findHighestLog();

        if (logPos == null) {
            cancelBaritone();
            currentState = FarmState.RETURN_TO_POS;
            delayTimer.reset();
            return;
        }

        int axeSlot = InventoryUtil.getAxeInInventory(true);
        if (axeSlot != -1) {
            switchSlot(axeSlot);
        }

        setTargetRotation(logPos);
        if (!rotationReached) return;

        mc.playerController.onPlayerDamageBlock(logPos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private BlockPos findHighestLog() {
        BlockPos bestLog = null;
        for (int x = -2; x <= 2; x++) {
            for (int y = 0; y <= 7; y++) {
                for (int z = -2; z <= 2; z++) {
                    BlockPos checkPos = farmPos.add(x, y, z);
                    BlockState state = mc.world.getBlockState(checkPos);
                    if (isLog(state)) {
                        if (bestLog == null || checkPos.getY() > bestLog.getY()) {
                            bestLog = checkPos;
                        }
                    }
                }
            }
        }
        return bestLog;
    }

    private void handleReturnToPos() {
        if (standPos == null) {
            currentState = FarmState.MINE_LEAVES;
            return;
        }

        double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
       
        if (distToStand <= 1.5 || (mc.player.getPosition().getX() == standPos.getX() && mc.player.getPosition().getZ() == standPos.getZ())) {
            cancelBaritone();
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        BlockPos targetLeaf = null;
        for (int i = 0; i <= 3; i++) {
            BlockPos checkPos = standPos.up(i);
            if (!mc.world.isAirBlock(checkPos) && mc.world.getBlockState(checkPos).getBlock() instanceof LeavesBlock) {
                targetLeaf = checkPos;
                break;
            }
        }

        if (targetLeaf != null) {
            cancelBaritone();
            setTargetRotation(targetLeaf);
            updateSmoothRotation();
            if (rotationReached) {
                breakBlockWithMode(targetLeaf);
            }
            return;
        }

        if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
            BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(standPos));
        }
    }

    private void breakBlockWithMode(BlockPos pos) {
        if (growMode.is("Мотыга")) {
            int hoeSlot = findHoeInHotbar();
            if (hoeSlot != -1) {
                switchSlot(hoeSlot);
                ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
                if (autoRepair.getValue() && hoe.getMaxDamage() - hoe.getDamage() < 15) {
                    currentState = FarmState.REPAIR_HOE;
                    delayTimer.reset();
                    return;
                }
            }
        }
        mc.playerController.onPlayerDamageBlock(pos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);
    }

    private int findHoeInHotbar() {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() instanceof net.minecraft.item.HoeItem) {
                return i;
            }
        }
        return -1;
    }

    private int findItemInHotbar(net.minecraft.item.Item item) {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() == item) {
                return i;
            }
        }
        return -1;
    }

    private void handleRepairHoe() {
        if (!delayTimer.hasTimeElapsed(150, false)) return;

        int hoeSlot = findHoeInHotbar();
        if (hoeSlot == -1) {
            currentState = FarmState.IDLE;
            return;
        }

        ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
        if (hoe.getDamage() == 0 || (hoe.getMaxDamage() - hoe.getDamage() > hoe.getMaxDamage() * 0.9)) {
            currentState = FarmState.IDLE;
            return;
        }

        int xpSlot = findItemInHotbar(Items.EXPERIENCE_BOTTLE);
        if (xpSlot == -1) {
            mc.player.sendChatMessage("/ah search Пузырек с опытом");
            currentState = FarmState.BUY_XP;
            xpBought = 0;
            delayTimer.reset();
            return;
        }

        targetPitch = 90.0F;
        targetYaw = mc.player.rotationYaw;
        updateSmoothRotation();

        if (rotationReached) {
            switchSlot(xpSlot);
            mc.playerController.processRightClick(mc.player, mc.world, Hand.MAIN_HAND);
            switchSlot(hoeSlot);
            delayTimer.reset();
        }
    }

    private void handleBuyXp() {
        if (!(mc.currentScreen instanceof ChestScreen)) {
            if (delayTimer.hasTimeElapsed(5000, false)) {
                currentState = FarmState.REPAIR_HOE;
                delayTimer.reset();
            }
            return;
        }

        ChestScreen screen = (ChestScreen) mc.currentScreen;
        String title = screen.getTitle().getString();
        if (!title.contains("Аукцион") && !title.contains("Поиск")) return;

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        Container container = screen.getContainer();
       
        int bestSlot = -1;
        int lowestPrice = Integer.MAX_VALUE;

        for (Slot slot : container.inventorySlots) {
            if (slot.slotNumber > 44) continue;
           
            ItemStack stack = slot.getStack();
            if (stack == null || stack.isEmpty()) continue;
           
            if (stack.getItem() == Items.EXPERIENCE_BOTTLE && stack.getCount() == 64) {
                int price = getAhPrice(stack);
                if (price > 0 && price < lowestPrice) {
                    lowestPrice = price;
                    bestSlot = slot.slotNumber;
                }
            }
        }

        if (bestSlot != -1) {
            mc.playerController.windowClick(container.windowId, bestSlot, 0, ClickType.QUICK_MOVE, mc.player);
            xpBought++;
            delayTimer.reset();
           
            if (xpBought >= buyXpAmount.getValue().intValue()) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        } else {
            if (delayTimer.hasTimeElapsed(3000, false)) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        }
    }

    private int getAhPrice(ItemStack stack) {
        net.minecraft.nbt.CompoundNBT tag = stack.getTag();
        if (tag != null && tag.contains("display", 10)) {
            net.minecraft.nbt.CompoundNBT display = tag.getCompound("display");
            if (display.contains("Lore", 9)) {
                net.minecraft.nbt.ListNBT lore = display.getList("Lore", 8);
                for (int j = 0; j < lore.size(); ++j) {
                    String loreLine = lore.getString(j).toLowerCase();
                    if (loreLine.contains("цена")) {
                        String priceText = loreLine.replaceAll("[^0-9]", "");
                        try {
                            return Integer.parseInt(priceText);
                        } catch (NumberFormatException ignored) {}
                    }
                }
            }
        }
        return -1;
    }

    private void handleCollectDrops() {
        if (!delayTimer.hasTimeElapsed(100, false)) return;

        List<ItemEntity> drops = mc.world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(farmPos).grow(8.0));
        ItemEntity nearestDrop = null;
        double nearestDist = Double.MAX_VALUE;

        for (ItemEntity drop : drops) {
            if (!drop.isAlive() || drop.getItem().isEmpty()) continue;
            net.minecraft.item.Item item = drop.getItem().getItem();
            if (item == Items.APPLE || item instanceof net.minecraft.item.BlockItem && ((net.minecraft.item.BlockItem)item).getBlock() instanceof net.minecraft.block.SaplingBlock) {
                double dist = mc.player.getDistanceSq(drop);
                if (dist < nearestDist) {
                    nearestDist = dist;
                    nearestDrop = drop;
                }
            }
        }

        if (nearestDrop != null) {
            BlockPos target = nearestDrop.getPosition();
            double distToDrop = mc.player.getPositionVec().distanceTo(new Vector3d(target.getX() + 0.5, target.getY() + 0.5, target.getZ() + 0.5));
           
            if (distToDrop <= 1.5) {
                return;
            }

            if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(target));
            }
        } else {
            cancelBaritone();
            currentState = FarmState.IDLE;
            delayTimer.reset();
        }
    }

    private void setTargetRotation(BlockPos pos) {
        double dx = (pos.getX() + 0.5) - mc.player.getPosX();
        double dy = (pos.getY() + 0.5) - (mc.player.getPosY() + mc.player.getEyeHeight());
        double dz = (pos.getZ() + 0.5) - mc.player.getPosZ();
        double dist = Math.sqrt(dx * dx + dz * dz);

        targetYaw = MathHelper.wrapDegrees((float) (Math.toDegrees(Math.atan2(dz, dx)) - 90.0));
        targetPitch = MathHelper.clamp((float) -(Math.toDegrees(Math.atan2(dy, dist))), -90.0F, 90.0F);

        float yawDiff = Math.abs(MathHelper.wrapDegrees(mc.player.rotationYaw - targetYaw));
        float pitchDiff = Math.abs(mc.player.rotationPitch - targetPitch);
        rotationReached = yawDiff < 5.0F && pitchDiff < 5.0F;
    }

    private void updateSmoothRotation() {
        float currentYaw = mc.player.rotationYaw;
        float currentPitch = mc.player.rotationPitch;

        float yawDiff = MathHelper.wrapDegrees(targetYaw - currentYaw);
        float pitchDiff = targetPitch - currentPitch;

        float yawStep = MathHelper.clamp(yawDiff, -ROTATION_SPEED, ROTATION_SPEED);
        float pitchStep = MathHelper.clamp(pitchDiff, -ROTATION_SPEED, ROTATION_SPEED);

        float newYaw = currentYaw + yawStep;
        float newPitch = MathHelper.clamp(currentPitch + pitchStep, -90.0F, 90.0F);

        mc.player.rotationYaw = newYaw;
        mc.player.rotationPitch = newPitch;
        mc.player.rotationYawHead = newYaw;

        mc.player.connection.sendPacket(new CPlayerPacket.RotationPacket(newYaw, newPitch, mc.player.isOnGround()));

        float yawRemaining = Math.abs(MathHelper.wrapDegrees(targetYaw - newYaw));
        float pitchRemaining = Math.abs(targetPitch - newPitch);
        rotationReached = yawRemaining < 3.0F && pitchRemaining < 3.0F;
    }

    private BlockPos findNearestLeaves() {
        List<BlockPos> leaves = new ArrayList<>();
        for (int x = -4; x <= 4; x++) {
            for (int y = 0; y <= 8; y++) {
                for (int z = -4; z <= 4; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (mc.world.getBlockState(pos).getBlock() instanceof LeavesBlock) {
                        leaves.add(pos);
                    }
                }
            }
        }
        if (leaves.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return leaves.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private BlockPos findNearestLog() {
        List<BlockPos> logs = new ArrayList<>();
        for (int x = -1; x <= 1; x++) {
            for (int y = 0; y <= 10; y++) {
                for (int z = -1; z <= 1; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (isLog(mc.world.getBlockState(pos))) {
                        logs.add(pos);
                    }
                }
            }
        }
        if (logs.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return logs.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private boolean isSaplingItem(Item item) {
        return item == Items.OAK_SAPLING || item == Items.SPRUCE_SAPLING || item == Items.BIRCH_SAPLING ||
               item == Items.JUNGLE_SAPLING || item == Items.ACACIA_SAPLING || item == Items.DARK_OAK_SAPLING;
    }

    private boolean isSaplingBlock(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_SAPLING || block == Blocks.SPRUCE_SAPLING || block == Blocks.BIRCH_SAPLING ||
               block == Blocks.JUNGLE_SAPLING || block == Blocks.ACACIA_SAPLING || block == Blocks.DARK_OAK_SAPLING;
    }

    private boolean isLog(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_LOG || block == Blocks.SPRUCE_LOG || block == Blocks.BIRCH_LOG ||
               block == Blocks.JUNGLE_LOG || block == Blocks.ACACIA_LOG || block == Blocks.DARK_OAK_LOG;
    }

    private boolean isDirtLike(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.DIRT || block == Blocks.GRASS_BLOCK || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL;
    }

    private void switchSlot(int slot) {
        if (mc.player.inventory.currentItem != slot) {
            mc.player.connection.sendPacket(new CHeldItemChangePacket(slot));
            mc.player.inventory.currentItem = slot;
        }
    }

    private int findHotbarSlot(boolean sapling, boolean boneMeal, boolean hoe) {
        for (int i = 0; i < 9; i++) {
            Item item = mc.player.inventory.getStackInSlot(i).getItem();
            if (sapling && isSaplingItem(item)) return i;
            if (boneMeal && item == Items.BONE_MEAL) return i;
            if (hoe && item instanceof HoeItem) return i;
        }
        return -1;
    }
}
легенда 25 выпустила новую работу
тип еще сидит на мертвой экспе брух :NotLikeThis:
а какая разница а чем сидеть главное чтобы нравилось
 
легенда 25 выпустила новую работу

а какая разница а чем сидеть главное чтобы нравилось
1 16 5 в принципе еле живая за то что он на экспе сидит я никак не осуждаю это чистое удивление тк мертвая уже база
 
тип еще сидит на мертвой экспе брух :NotLikeThis:
мне нехуй делать
1 16 5 в принципе еле живая за то что он на экспе сидит я никак не осуждаю это чистое удивление тк мертвая уже

легенда 25 выпустила новую работу

а какая разница а чем сидеть главное чтобы нравилось
я думал меня все забыли , сяб
 
Последнее редактирование:
короче эпл фармер покупает сам оопыт и сам чинит при выборе мотыги он ломает листву мотыгоой типо там удача и т.д есть рабоота с баритоном(из-за него багается) убрать моожно на изи и доработать короче ИИ в поомощь думаю вы поймете все P.S тут 600+ строк есчо

Пожалуйста, авторизуйтесь для просмотра ссылки.



AppleFarmer:
Expand Collapse Copy
package fun.danq.constructor.modules.impl.player;

import fun.danq.constructor.api.events.orbit.EventHandler;
import fun.danq.constructor.events.other.TickEvent;
import fun.danq.constructor.mods.baritone.api.BaritoneAPI;
import fun.danq.constructor.mods.baritone.api.pathing.goals.GoalBlock;
import fun.danq.constructor.modules.Category;
import fun.danq.constructor.modules.Module;
import fun.danq.constructor.modules.ModuleInfo;
import fun.danq.constructor.modules.settings.impl.ModeSetting;
import fun.danq.utils.chat.ChatUtil;
import fun.danq.utils.math.StopWatch;
import fun.danq.utils.player.InventoryUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.item.*;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;

import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Items;
import net.minecraft.util.math.AxisAlignedBB;
import java.util.ArrayList;
import java.util.List;

import fun.danq.constructor.modules.settings.impl.BooleanSetting;
import fun.danq.constructor.modules.settings.impl.SliderSetting;

@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "AutoAppleFarm", description = "Автоматически выращивает и рубит деревья для фарма яблок", category = Category.PLAYER)
public class AutoAppleFarm extends Module {

    private enum FarmState {
        IDLE, PLANT_SAPLING, GROW_TREE, MINE_LEAVES, MINE_LOG, RETURN_TO_POS, COLLECT_DROPS, REPAIR_HOE, BUY_XP
    }

    private final ModeSetting growMode = new ModeSetting(this, "Режим роста", "Костная мука", "Мотыга");
    private final BooleanSetting autoRepair = new BooleanSetting(this, "Автопочинка мотыги", true);
    private final SliderSetting buyXpAmount = new SliderSetting(this, "Ск. стаков покупать", 3, 1, 10, 1);

    private int xpBought = 0;

    private FarmState currentState = FarmState.IDLE;
    private BlockPos farmPos = null;
    private BlockPos standPos = null;
    private final StopWatch delayTimer = new StopWatch();
    private final StopWatch warnTimer = new StopWatch();

    private float targetYaw, targetPitch;
    private boolean rotationReached = false;
    private static final float ROTATION_SPEED = 30.0F;

    private boolean oldAllowPlace;
    private boolean oldAllowBreak;

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player != null) {
            Direction facing = mc.player.getHorizontalFacing();
            farmPos = mc.player.getPosition().offset(facing, 2);
            standPos = mc.player.getPosition();
            currentState = FarmState.IDLE;
            delayTimer.reset();
            warnTimer.reset();
            rotationReached = false;
           
            ChatUtil.draw("§a[AutoAppleFarm] §fСаженец будет на: " + farmPos.getX() + ", " + farmPos.getY() + ", " + farmPos.getZ());
        }
    }

    @Override
    public void onDisable() {
        super.onDisable();
        currentState = FarmState.IDLE;
        cancelBaritone();
    }

    private void cancelBaritone() {
        try {
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getMineProcess().cancel();
            }
            if (fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoal(null);
            }
            fun.danq.constructor.mods.baritone.api.BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything();
        } catch (Exception ignored) {}
    }

    @EventHandler
    public void onTick(TickEvent event) {
        if (mc.player == null || mc.world == null || farmPos == null) return;

        boolean requiresStand = currentState == FarmState.IDLE || currentState == FarmState.PLANT_SAPLING ||
                                currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES ||
                                currentState == FarmState.MINE_LOG;

        if (requiresStand) {
            double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
            if (mc.player.getPosY() < farmPos.getY() + 1 || distToStand > 1.5) {
                if (warnTimer.hasTimeElapsed(3000, true)) {
                    ChatUtil.draw("§e[AutoAppleFarm] §fСпустился с блока. Возвращаюсь назад...");
                }
                currentState = FarmState.RETURN_TO_POS;
                delayTimer.reset();
                return;
            }
        }

        if (currentState == FarmState.PLANT_SAPLING || currentState == FarmState.GROW_TREE || currentState == FarmState.MINE_LEAVES || currentState == FarmState.MINE_LOG) {
            updateSmoothRotation();
        }

        BlockState stateAtPos = mc.world.getBlockState(farmPos);
        BlockState stateBelow = mc.world.getBlockState(farmPos.down());

        switch (currentState) {
            case IDLE:
                if (isLog(stateAtPos)) {
                    currentState = FarmState.MINE_LOG;
                    delayTimer.reset();
                } else if (isSaplingBlock(stateAtPos)) {
                    currentState = FarmState.GROW_TREE;
                    delayTimer.reset();
                } else if (stateAtPos.getBlock() == Blocks.AIR && isDirtLike(stateBelow)) {
                    currentState = FarmState.PLANT_SAPLING;
                    delayTimer.reset();
                }
                break;

            case PLANT_SAPLING:
                handlePlantSapling();
                break;

            case GROW_TREE:
                handleGrowTree(stateAtPos);
                break;

            case MINE_LEAVES:
                handleMineLeaves();
                break;

            case MINE_LOG:
                handleMineLog();
                break;

            case RETURN_TO_POS:
                handleReturnToPos();
                break;

            case COLLECT_DROPS:
                handleCollectDrops();
                break;

            case REPAIR_HOE:
                handleRepairHoe();
                break;

            case BUY_XP:
                handleBuyXp();
                break;
        }
    }

    private void handlePlantSapling() {
        if (!delayTimer.hasTimeElapsed(400, false)) return;

        int saplingSlot = findHotbarSlot(true, false, false);
        if (saplingSlot == -1) {
            ChatUtil.draw("§c[AutoAppleFarm] §fСаженцы не найдены в хотбаре!");
            toggle();
            return;
        }

        switchSlot(saplingSlot);
        setTargetRotation(farmPos.down());

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY(), farmPos.getZ() + 0.5),
                Direction.UP, farmPos.down(), false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        currentState = FarmState.IDLE;
        delayTimer.reset();
    }

    private void handleGrowTree(BlockState stateAtPos) {
        if (isLog(stateAtPos)) {
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        boolean useHoe = growMode.is("Мотыга");
        int toolSlot;

        if (useHoe) {
            toolSlot = findHotbarSlot(false, false, true);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fМотыга не найдена в хотбаре!");
                toggle();
                return;
            }
        } else {
            toolSlot = findHotbarSlot(false, true, false);
            if (toolSlot == -1) {
                ChatUtil.draw("§c[AutoAppleFarm] §fКостная мука не найдена в хотбаре!");
                toggle();
                return;
            }
        }

        switchSlot(toolSlot);
        setTargetRotation(farmPos);

        if (!rotationReached) return;

        BlockRayTraceResult hit = new BlockRayTraceResult(
                new Vector3d(farmPos.getX() + 0.5, farmPos.getY() + 0.5, farmPos.getZ() + 0.5),
                Direction.UP, farmPos, false
        );
        mc.playerController.rightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, hit);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private void handleMineLeaves() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos leavesPos = findNearestLeaves();

        if (leavesPos == null) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        double dist = mc.player.getPositionVec().distanceTo(new Vector3d(leavesPos.getX() + 0.5, leavesPos.getY() + 0.5, leavesPos.getZ() + 0.5));
        if (dist > 4.5) {
            currentState = FarmState.COLLECT_DROPS;
            delayTimer.reset();
            return;
        }

        setTargetRotation(leavesPos);
        if (!rotationReached) return;

        breakBlockWithMode(leavesPos);

        delayTimer.reset();
    }

    private void handleMineLog() {
        if (!delayTimer.hasTimeElapsed(50, false)) return;

        BlockPos logPos = findHighestLog();

        if (logPos == null) {
            cancelBaritone();
            currentState = FarmState.RETURN_TO_POS;
            delayTimer.reset();
            return;
        }

        int axeSlot = InventoryUtil.getAxeInInventory(true);
        if (axeSlot != -1) {
            switchSlot(axeSlot);
        }

        setTargetRotation(logPos);
        if (!rotationReached) return;

        mc.playerController.onPlayerDamageBlock(logPos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);

        delayTimer.reset();
    }

    private BlockPos findHighestLog() {
        BlockPos bestLog = null;
        for (int x = -2; x <= 2; x++) {
            for (int y = 0; y <= 7; y++) {
                for (int z = -2; z <= 2; z++) {
                    BlockPos checkPos = farmPos.add(x, y, z);
                    BlockState state = mc.world.getBlockState(checkPos);
                    if (isLog(state)) {
                        if (bestLog == null || checkPos.getY() > bestLog.getY()) {
                            bestLog = checkPos;
                        }
                    }
                }
            }
        }
        return bestLog;
    }

    private void handleReturnToPos() {
        if (standPos == null) {
            currentState = FarmState.MINE_LEAVES;
            return;
        }

        double distToStand = mc.player.getPositionVec().distanceTo(new Vector3d(standPos.getX() + 0.5, standPos.getY(), standPos.getZ() + 0.5));
       
        if (distToStand <= 1.5 || (mc.player.getPosition().getX() == standPos.getX() && mc.player.getPosition().getZ() == standPos.getZ())) {
            cancelBaritone();
            currentState = FarmState.MINE_LEAVES;
            delayTimer.reset();
            return;
        }

        BlockPos targetLeaf = null;
        for (int i = 0; i <= 3; i++) {
            BlockPos checkPos = standPos.up(i);
            if (!mc.world.isAirBlock(checkPos) && mc.world.getBlockState(checkPos).getBlock() instanceof LeavesBlock) {
                targetLeaf = checkPos;
                break;
            }
        }

        if (targetLeaf != null) {
            cancelBaritone();
            setTargetRotation(targetLeaf);
            updateSmoothRotation();
            if (rotationReached) {
                breakBlockWithMode(targetLeaf);
            }
            return;
        }

        if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
            BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(standPos));
        }
    }

    private void breakBlockWithMode(BlockPos pos) {
        if (growMode.is("Мотыга")) {
            int hoeSlot = findHoeInHotbar();
            if (hoeSlot != -1) {
                switchSlot(hoeSlot);
                ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
                if (autoRepair.getValue() && hoe.getMaxDamage() - hoe.getDamage() < 15) {
                    currentState = FarmState.REPAIR_HOE;
                    delayTimer.reset();
                    return;
                }
            }
        }
        mc.playerController.onPlayerDamageBlock(pos, Direction.UP);
        mc.player.swingArm(Hand.MAIN_HAND);
    }

    private int findHoeInHotbar() {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() instanceof net.minecraft.item.HoeItem) {
                return i;
            }
        }
        return -1;
    }

    private int findItemInHotbar(net.minecraft.item.Item item) {
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (stack.getItem() == item) {
                return i;
            }
        }
        return -1;
    }

    private void handleRepairHoe() {
        if (!delayTimer.hasTimeElapsed(150, false)) return;

        int hoeSlot = findHoeInHotbar();
        if (hoeSlot == -1) {
            currentState = FarmState.IDLE;
            return;
        }

        ItemStack hoe = mc.player.inventory.getStackInSlot(hoeSlot);
        if (hoe.getDamage() == 0 || (hoe.getMaxDamage() - hoe.getDamage() > hoe.getMaxDamage() * 0.9)) {
            currentState = FarmState.IDLE;
            return;
        }

        int xpSlot = findItemInHotbar(Items.EXPERIENCE_BOTTLE);
        if (xpSlot == -1) {
            mc.player.sendChatMessage("/ah search Пузырек с опытом");
            currentState = FarmState.BUY_XP;
            xpBought = 0;
            delayTimer.reset();
            return;
        }

        targetPitch = 90.0F;
        targetYaw = mc.player.rotationYaw;
        updateSmoothRotation();

        if (rotationReached) {
            switchSlot(xpSlot);
            mc.playerController.processRightClick(mc.player, mc.world, Hand.MAIN_HAND);
            switchSlot(hoeSlot);
            delayTimer.reset();
        }
    }

    private void handleBuyXp() {
        if (!(mc.currentScreen instanceof ChestScreen)) {
            if (delayTimer.hasTimeElapsed(5000, false)) {
                currentState = FarmState.REPAIR_HOE;
                delayTimer.reset();
            }
            return;
        }

        ChestScreen screen = (ChestScreen) mc.currentScreen;
        String title = screen.getTitle().getString();
        if (!title.contains("Аукцион") && !title.contains("Поиск")) return;

        if (!delayTimer.hasTimeElapsed(200, false)) return;

        Container container = screen.getContainer();
       
        int bestSlot = -1;
        int lowestPrice = Integer.MAX_VALUE;

        for (Slot slot : container.inventorySlots) {
            if (slot.slotNumber > 44) continue;
           
            ItemStack stack = slot.getStack();
            if (stack == null || stack.isEmpty()) continue;
           
            if (stack.getItem() == Items.EXPERIENCE_BOTTLE && stack.getCount() == 64) {
                int price = getAhPrice(stack);
                if (price > 0 && price < lowestPrice) {
                    lowestPrice = price;
                    bestSlot = slot.slotNumber;
                }
            }
        }

        if (bestSlot != -1) {
            mc.playerController.windowClick(container.windowId, bestSlot, 0, ClickType.QUICK_MOVE, mc.player);
            xpBought++;
            delayTimer.reset();
           
            if (xpBought >= buyXpAmount.getValue().intValue()) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        } else {
            if (delayTimer.hasTimeElapsed(3000, false)) {
                mc.player.closeScreen();
                currentState = FarmState.REPAIR_HOE;
            }
        }
    }

    private int getAhPrice(ItemStack stack) {
        net.minecraft.nbt.CompoundNBT tag = stack.getTag();
        if (tag != null && tag.contains("display", 10)) {
            net.minecraft.nbt.CompoundNBT display = tag.getCompound("display");
            if (display.contains("Lore", 9)) {
                net.minecraft.nbt.ListNBT lore = display.getList("Lore", 8);
                for (int j = 0; j < lore.size(); ++j) {
                    String loreLine = lore.getString(j).toLowerCase();
                    if (loreLine.contains("цена")) {
                        String priceText = loreLine.replaceAll("[^0-9]", "");
                        try {
                            return Integer.parseInt(priceText);
                        } catch (NumberFormatException ignored) {}
                    }
                }
            }
        }
        return -1;
    }

    private void handleCollectDrops() {
        if (!delayTimer.hasTimeElapsed(100, false)) return;

        List<ItemEntity> drops = mc.world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(farmPos).grow(8.0));
        ItemEntity nearestDrop = null;
        double nearestDist = Double.MAX_VALUE;

        for (ItemEntity drop : drops) {
            if (!drop.isAlive() || drop.getItem().isEmpty()) continue;
            net.minecraft.item.Item item = drop.getItem().getItem();
            if (item == Items.APPLE || item instanceof net.minecraft.item.BlockItem && ((net.minecraft.item.BlockItem)item).getBlock() instanceof net.minecraft.block.SaplingBlock) {
                double dist = mc.player.getDistanceSq(drop);
                if (dist < nearestDist) {
                    nearestDist = dist;
                    nearestDrop = drop;
                }
            }
        }

        if (nearestDrop != null) {
            BlockPos target = nearestDrop.getPosition();
            double distToDrop = mc.player.getPositionVec().distanceTo(new Vector3d(target.getX() + 0.5, target.getY() + 0.5, target.getZ() + 0.5));
           
            if (distToDrop <= 1.5) {
                return;
            }

            if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
                BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(target));
            }
        } else {
            cancelBaritone();
            currentState = FarmState.IDLE;
            delayTimer.reset();
        }
    }

    private void setTargetRotation(BlockPos pos) {
        double dx = (pos.getX() + 0.5) - mc.player.getPosX();
        double dy = (pos.getY() + 0.5) - (mc.player.getPosY() + mc.player.getEyeHeight());
        double dz = (pos.getZ() + 0.5) - mc.player.getPosZ();
        double dist = Math.sqrt(dx * dx + dz * dz);

        targetYaw = MathHelper.wrapDegrees((float) (Math.toDegrees(Math.atan2(dz, dx)) - 90.0));
        targetPitch = MathHelper.clamp((float) -(Math.toDegrees(Math.atan2(dy, dist))), -90.0F, 90.0F);

        float yawDiff = Math.abs(MathHelper.wrapDegrees(mc.player.rotationYaw - targetYaw));
        float pitchDiff = Math.abs(mc.player.rotationPitch - targetPitch);
        rotationReached = yawDiff < 5.0F && pitchDiff < 5.0F;
    }

    private void updateSmoothRotation() {
        float currentYaw = mc.player.rotationYaw;
        float currentPitch = mc.player.rotationPitch;

        float yawDiff = MathHelper.wrapDegrees(targetYaw - currentYaw);
        float pitchDiff = targetPitch - currentPitch;

        float yawStep = MathHelper.clamp(yawDiff, -ROTATION_SPEED, ROTATION_SPEED);
        float pitchStep = MathHelper.clamp(pitchDiff, -ROTATION_SPEED, ROTATION_SPEED);

        float newYaw = currentYaw + yawStep;
        float newPitch = MathHelper.clamp(currentPitch + pitchStep, -90.0F, 90.0F);

        mc.player.rotationYaw = newYaw;
        mc.player.rotationPitch = newPitch;
        mc.player.rotationYawHead = newYaw;

        mc.player.connection.sendPacket(new CPlayerPacket.RotationPacket(newYaw, newPitch, mc.player.isOnGround()));

        float yawRemaining = Math.abs(MathHelper.wrapDegrees(targetYaw - newYaw));
        float pitchRemaining = Math.abs(targetPitch - newPitch);
        rotationReached = yawRemaining < 3.0F && pitchRemaining < 3.0F;
    }

    private BlockPos findNearestLeaves() {
        List<BlockPos> leaves = new ArrayList<>();
        for (int x = -4; x <= 4; x++) {
            for (int y = 0; y <= 8; y++) {
                for (int z = -4; z <= 4; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (mc.world.getBlockState(pos).getBlock() instanceof LeavesBlock) {
                        leaves.add(pos);
                    }
                }
            }
        }
        if (leaves.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return leaves.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private BlockPos findNearestLog() {
        List<BlockPos> logs = new ArrayList<>();
        for (int x = -1; x <= 1; x++) {
            for (int y = 0; y <= 10; y++) {
                for (int z = -1; z <= 1; z++) {
                    BlockPos pos = farmPos.add(x, y, z);
                    if (isLog(mc.world.getBlockState(pos))) {
                        logs.add(pos);
                    }
                }
            }
        }
        if (logs.isEmpty()) return null;

        Vector3d playerPos = mc.player.getPositionVec();
        return logs.stream()
                .min((a, b) -> Double.compare(
                        playerPos.squareDistanceTo(a.getX() + 0.5, a.getY() + 0.5, a.getZ() + 0.5),
                        playerPos.squareDistanceTo(b.getX() + 0.5, b.getY() + 0.5, b.getZ() + 0.5)
                ))
                .orElse(null);
    }

    private boolean isSaplingItem(Item item) {
        return item == Items.OAK_SAPLING || item == Items.SPRUCE_SAPLING || item == Items.BIRCH_SAPLING ||
               item == Items.JUNGLE_SAPLING || item == Items.ACACIA_SAPLING || item == Items.DARK_OAK_SAPLING;
    }

    private boolean isSaplingBlock(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_SAPLING || block == Blocks.SPRUCE_SAPLING || block == Blocks.BIRCH_SAPLING ||
               block == Blocks.JUNGLE_SAPLING || block == Blocks.ACACIA_SAPLING || block == Blocks.DARK_OAK_SAPLING;
    }

    private boolean isLog(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.OAK_LOG || block == Blocks.SPRUCE_LOG || block == Blocks.BIRCH_LOG ||
               block == Blocks.JUNGLE_LOG || block == Blocks.ACACIA_LOG || block == Blocks.DARK_OAK_LOG;
    }

    private boolean isDirtLike(BlockState state) {
        Block block = state.getBlock();
        return block == Blocks.DIRT || block == Blocks.GRASS_BLOCK || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL;
    }

    private void switchSlot(int slot) {
        if (mc.player.inventory.currentItem != slot) {
            mc.player.connection.sendPacket(new CHeldItemChangePacket(slot));
            mc.player.inventory.currentItem = slot;
        }
    }

    private int findHotbarSlot(boolean sapling, boolean boneMeal, boolean hoe) {
        for (int i = 0; i < 9; i++) {
            Item item = mc.player.inventory.getStackInSlot(i).getItem();
            if (sapling && isSaplingItem(item)) return i;
            if (boneMeal && item == Items.BONE_MEAL) return i;
            if (hoe && item instanceof HoeItem) return i;
        }
        return -1;
    }
}
1.мертвые импорты

2.Метод findNearestLog, который ищет ближайшее бревно, объявлен, но не вызывается ваще.. вместо него findHighestLog

3.импорт java.util.List используется, а вот зачем импортирован java.util.ArrayList отдельно если List уже есть это вопрос стиля
 
Назад
Сверху Снизу