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

Часть функционала Funtime AutoFarm

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
21 Фев 2022
Сообщения
121
Реакции
11
Выберите загрузчик игры
  1. Fabric
Автофарм какао-бобов под фантайм, гораздо еффективнее чем в какой-то дельте. Надо запускать два бота - один ломает, другой сажает, они синкаются и один идет за другим. Бот сам чинит свой топор. Прибыль с одного бота около 30кк в час, строите 10 ферм, запускаете на сутки +пару миллиардов получаете.
Ферму нужно строить чтобы бот ходил под ней, 2 блока под бота + 4 блока бобов. Много параметров фермы hard-coded, поэтому разбирайтесь как сделать чтобы у вас это заработало.
FarmManager.java:
Expand Collapse Copy
package xyz.breadloaf.imguimc.werwedc;

import imgui.type.ImBoolean;
import imgui.type.ImInt;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CocoaBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;

public class FarmManager {
    public static class CocoaFarmer {

        // --- Configuration ---
        public static final ImInt originX = new ImInt(0);
        public static final ImInt originZ = new ImInt(-44);
        public static final ImInt farmMaxX = new ImInt(63);
        public static final ImInt farmMaxZ = new ImInt(0);
        public static final ImBoolean isEnabled = new ImBoolean(false);

        // --- State Machine ---
        private enum State {
            BREAKING,
            CHANGING_LANE_STRAFE,
            BREAKING_RETURN,
            DEPOSITING_FOR_PLANT,  // New state for planter's barrel
            DEPOSITING_FOR_STORAGE, // New state for profit chest
            CHANGING_LANE_ADVANCE,
            RETURNING_TO_ORIGIN,
            REPAIRING,
            WAITING_FOR_GROWTH
        }

        private enum RepairSubState {
            IDLE, LOCATING_BARREL, TAKING_BOTTLES, EQUIPPING_OFFHAND, REPAIRING_WITH_BOTTLES
        }

        private static State currentState = State.REPAIRING;
        private static State stateAfterDeposit;
        private static RepairSubState repairState = RepairSubState.LOCATING_BARREL;

        public static String getCurrentStateName() {
            return currentState.name() + (currentState == State.REPAIRING ? " (" + repairState.name() + ")" : "");
        }

        // --- Farming Logic ---
        private static int currentRowZ = originZ.get();
        private static boolean initialized = false;
        private static boolean wasEnabledLastTick = false;
        private static boolean hasOpenedContainer = false;
        private static int bottlesToTake = 2;
        private static long lastActionTime = 0;
        private static int repairClicksDone = 0;
        private static long lastRepairClickTime = 0;

        public static void reset() {
            isEnabled.set(false);
            currentState = State.BREAKING;
            repairState = RepairSubState.IDLE;
            initialized = false;
            currentRowZ = originZ.get();
        }

        public static void onTick(Minecraft mc) {
            boolean isCurrentlyEnabled = isEnabled.get();

            if (!isCurrentlyEnabled && wasEnabledLastTick) {
                mc.options.keyUp.setDown(false);
                mc.options.keyAttack.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyUse.setDown(false);
                reset();
            }

            wasEnabledLastTick = isCurrentlyEnabled;
            if (!isCurrentlyEnabled) return;

            final LocalPlayer player = mc.player;
            if (player == null) return;

            boolean isGuiOpen = mc.screen != null;
            boolean shouldPause = isGuiOpen && currentState != State.DEPOSITING_FOR_PLANT && currentState != State.DEPOSITING_FOR_STORAGE && currentState != State.REPAIRING;
            if (shouldPause) {
                mc.options.keyUp.setDown(false);
                mc.options.keyAttack.setDown(false);
                mc.options.keyRight.setDown(false);
                return;
            }

            if (!initialized) {
                currentRowZ = originZ.get();
                initialized = true;
            }

            switch (currentState) {
                case BREAKING:
                    if (player.getX() >= farmMaxX.get()) {
                        mc.options.keyUp.setDown(false);
                        currentState = State.CHANGING_LANE_STRAFE;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);

                    if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                        mc.gameMode.startDestroyBlock(blockHitResult.getBlockPos(), blockHitResult.getDirection());
                    }
                    break;

                case CHANGING_LANE_STRAFE:
                    final double targetStrafeZ = currentRowZ + 1 - 0.3;
                    if (player.getZ() >= targetStrafeZ - 0.001) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.BREAKING_RETURN;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case BREAKING_RETURN:
                    if (player.getZ() >= farmMaxZ.get() - 1) {
                        if (player.getX() <= originX.get() + 1.3 + 0.001) {
                            mc.options.keyUp.setDown(false);
                            stateAfterDeposit = State.RETURNING_TO_ORIGIN;
                            currentState = State.DEPOSITING_FOR_PLANT; // Start deposit sequence
                            return;
                        }
                    } else {
                        if (player.getX() <= originX.get() + 0.3 + 0.001) {
                            mc.options.keyUp.setDown(false);
                            currentRowZ += 3;
                            stateAfterDeposit = State.CHANGING_LANE_ADVANCE;
                            currentState = State.DEPOSITING_FOR_PLANT; // Start deposit sequence
                            return;
                        }
                    }
                    if (player.getYRot() != 90f) player.setYRot(90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);

                    if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                        mc.gameMode.startDestroyBlock(blockHitResult.getBlockPos(), blockHitResult.getDirection());
                    }
                    break;

                case DEPOSITING_FOR_PLANT:
                    handleDepositingForPlant(mc, player);
                    break;

                case DEPOSITING_FOR_STORAGE:
                    handleDepositingForStorage(mc, player);
                    break;

                case CHANGING_LANE_ADVANCE:
                    final double targetAdvanceZ = currentRowZ - 0.488;
                    if (player.getZ() >= targetAdvanceZ - 0.01) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.BREAKING;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case RETURNING_TO_ORIGIN:
                    if (mc.screen instanceof AbstractContainerScreen) {
                        player.closeContainer();
                    }
                    final double targetReturnZ = originZ.get() - 0.7;
                    if (player.getZ() <= targetReturnZ + 0.01) {
                        mc.options.keyUp.setDown(false);
                        repairState = RepairSubState.LOCATING_BARREL;
                        currentState = State.REPAIRING;
                        repairClicksDone = 0; // Reset for the new repair cycle
                        currentRowZ = originZ.get();
                        return;
                    }
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (player.getXRot() != 0f) player.setXRot(0f);
                    if (currentRowZ != originZ.get()) currentRowZ = originZ.get();
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);
                    break;

                case REPAIRING:
                    handleRepairing(mc, player);
                    break;

                case WAITING_FOR_GROWTH:
                    int grownCocoaCount = 0;
                    for (int x = -3; x <= 3; x++) {
                        for (int y = -3; y <= 3; y++) {
                            for (int z = -3; z <= 3; z++) {
                                BlockPos pos = player.blockPosition().offset(x, y, z);
                                BlockState state = mc.level.getBlockState(pos);
                                if (state.getBlock() instanceof CocoaBlock && state.getValue(CocoaBlock.AGE) == 2) {
                                    grownCocoaCount++;
                                }
                            }
                        }
                    }
                    if (grownCocoaCount >= 3) {
                        currentState = State.BREAKING;
                    }
                    break;
            }
        }

        private static void handleDepositingForPlant(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedContainer = true;
                if (System.currentTimeMillis() - lastActionTime < 200) return;

                int cocoaInBarrel = countItemsInContainer(player, Items.COCOA_BEANS);
                int cocoaInPlayer = countItemsInInventory(player, Items.COCOA_BEANS);

                if (cocoaInBarrel >= 8 * 64 || cocoaInPlayer == 0) {
                    player.closeContainer();
                    return;
                }

                // Find a stack in player inv to move
                int playerSlot = -1;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        playerSlot = getContainerSlotFromInventory(player, i);
                        break;
                    }
                }

                if (playerSlot != -1) {
                    mc.gameMode.handleInventoryMouseClick(player.containerMenu.containerId, playerSlot, 0, ClickType.QUICK_MOVE, player);
                    lastActionTime = System.currentTimeMillis();
                } else { // No more cocoa to move
                    player.closeContainer();
                }

            } else { // GUI is not open
                if (hasOpenedContainer) {
                    hasOpenedContainer = false;
                    currentState = State.DEPOSITING_FOR_STORAGE; // Proceed to next deposit stage
                    return;
                }
                if (player.getYRot() != 90f) player.setYRot(90f);
                if (player.getXRot() != 90f) player.setXRot(90f); // Look down for barrel
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.BARREL)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleDepositingForStorage(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedContainer = true;
                boolean hasCocoa = false;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        hasCocoa = true;
                        int slotId = getContainerSlotFromInventory(player, i);
                        if(slotId != -1) {
                            mc.gameMode.handleInventoryMouseClick(player.containerMenu.containerId, slotId, 0, ClickType.QUICK_MOVE, player);
                            return;
                        }
                    }
                }
                if (!hasCocoa) player.closeContainer();
            } else {
                if (hasOpenedContainer) {
                    hasOpenedContainer = false;
                    currentState = stateAfterDeposit; // Transition to final destination
                    return;
                }
                if (player.getYRot() != 90f) player.setYRot(90f);
                if (player.getXRot() != 0f) player.setXRot(0f); // Look straight for chest
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.CHEST)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleRepairing(Minecraft mc, LocalPlayer player) {
            // Check if we have completed all 60 clicks
            if (repairClicksDone >= 130) {
                currentState = State.WAITING_FOR_GROWTH;
                return;
            }

            // Set the player's rotation
            if (player.getYRot() != -170f) player.setYRot(-170f);
            if (player.getXRot() != 0f) player.setXRot(0f);

            // Check if 500ms have passed since the last click
            if (System.currentTimeMillis() - lastRepairClickTime > 500) {
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.LEVER)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                        repairClicksDone++;
                        lastRepairClickTime = System.currentTimeMillis();
                    }
                }
            }
        }

        private static int getContainerSlotFromInventory(LocalPlayer player, int inventorySlot) {
            for (int i = 0; i < player.containerMenu.slots.size(); i++) {
                var slot = player.containerMenu.slots.get(i);
                if (slot.container == player.getInventory() && slot.getContainerSlot() == inventorySlot) {
                    return i;
                }
            }
            return -1;
        }

        private static int countItemsInContainer(LocalPlayer player, net.minecraft.world.item.Item item) {
            if (!(Minecraft.getInstance().screen instanceof AbstractContainerScreen)) return 0;
            int count = 0;
            int containerSlots = player.containerMenu.slots.size() - player.getInventory().getContainerSize();
            for(int i = 0; i < containerSlots; i++) {
                ItemStack stack = player.containerMenu.slots.get(i).getItem();
                if(stack.is(item)) {
                    count += stack.getCount();
                }
            }
            return count;
        }

        private static int countItemsInInventory(LocalPlayer player, net.minecraft.world.item.Item item) {
            int count = 0;
            for(ItemStack stack : player.getInventory().items) {
                if(stack.is(item)) {
                    count += stack.getCount();
                }
            }
            return count;
        }
    }
}

PlantManager.java:
Expand Collapse Copy
package xyz.breadloaf.imguimc.werwedc;

import imgui.type.ImBoolean;
import imgui.type.ImInt;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CocoaBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;

public class PlantManager {
    public static class CocoaPlanter {

        // --- Configuration ---
        public static final ImInt originX = new ImInt(0);
        public static final ImInt originZ = new ImInt(-44);
        public static final ImInt farmMaxX = new ImInt(63);
        public static final ImInt farmMaxZ = new ImInt(0);
        public static final ImBoolean isEnabled = new ImBoolean(false);

        // --- State Machine ---
        private enum State {
            WAITING_FOR_HARVEST,
            DEPOSITING_LEFTOVERS, // New state
            TAKING_COCOA,
            PLANTING,
            CHANGING_LANE_STRAFE,
            PLANTING_RETURN,
            CHANGING_LANE_ADVANCE,
            RETURNING_TO_ORIGIN
        }

        private static State currentState = State.TAKING_COCOA;
        private static boolean wasEnabledLastTick = false;
        private static int plantStage = 0;
        private static boolean hasOpenedChestForTaking = false;
        private static boolean hasOpenedChestForDepositing = false;
        private static long lastPlantTime = 0;
        private static long lastInventoryActionTime = 0;
        private static int lastFinishedBlockX = -10000;
        private static int currentRowZ = originZ.get();
        private static boolean initialized = false;
        private static boolean justReturnedToOrigin = false;
        private static long lastStartedReturningToOriginTime = 0;
        public static String getCurrentStateName() {
            return currentState.name();
        }

        public static void reset() {
            isEnabled.set(false);
            currentState = State.TAKING_COCOA;
            plantStage = 0;
            lastFinishedBlockX = -10000;
            initialized = false;
            hasOpenedChestForTaking = false;
            hasOpenedChestForDepositing = false;
            justReturnedToOrigin = false;
            currentRowZ = originZ.get();
        }

        public static void onTick(Minecraft mc) {
            boolean isCurrentlyEnabled = isEnabled.get();

            if (!isCurrentlyEnabled && wasEnabledLastTick) {
                mc.options.keyUp.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyLeft.setDown(false);
                reset();
            }

            wasEnabledLastTick = isCurrentlyEnabled;

            if (!isCurrentlyEnabled) {
                return;
            }

            final LocalPlayer player = mc.player;
            if (player == null) {
                return;
            }

            if (mc.screen instanceof ChatScreen) {
                mc.options.keyUp.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyLeft.setDown(false);
                return;
            }

            if (!initialized) {
                currentRowZ = originZ.get();
                initialized = true;
            }

            switch (currentState) {
                case WAITING_FOR_HARVEST:
                    for (int x = -3; x <= 3; x++) {
                        for (int y = -3; y <= 3; y++) {
                            for (int z = -3; z <= 3; z++) {
                                BlockPos pos = player.blockPosition().offset(x, y, z);
                                if (mc.level.getBlockState(pos).getBlock() instanceof CocoaBlock) {
                                    return;
                                }
                            }
                        }
                    }
                    currentState = State.DEPOSITING_LEFTOVERS;
                    break;

                case DEPOSITING_LEFTOVERS:
                    handleDepositingLeftovers(mc, player);
                    break;

                case TAKING_COCOA:
                    handleTakingCocoa(mc, player);
                    break;

                case PLANTING:
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);

                    if (player.getBlockX() >= farmMaxX.get()) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.CHANGING_LANE_STRAFE;
                        break;
                    }

                    if (!ensureHoldingCocoa(player) || player.getBlockX() == lastFinishedBlockX) {
                        break;
                    }

                    if (System.currentTimeMillis() - lastPlantTime > 25) {
                        performPlanting(mc, player, false);
                        if (plantStage >= 4) {
                            plantStage = 0;
                            lastFinishedBlockX = player.getBlockX();
                        }
                    }
                    break;

                case PLANTING_RETURN:
                    if (player.getYRot() != 0f) player.setYRot(0f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);

                    if (player.getZ() >= farmMaxZ.get() - 1) {
                        if (player.getX() <= originX.get() + 1.3 + 0.001) {
                            mc.options.keyRight.setDown(false);
                            currentState = State.RETURNING_TO_ORIGIN;
                            lastStartedReturningToOriginTime = System.currentTimeMillis();
                            break;
                        }
                    } else {
                        if (player.getX() <= originX.get() + 0.3 + 0.001) {
                            mc.options.keyRight.setDown(false);
                            currentRowZ += 3;
                            currentState = State.CHANGING_LANE_ADVANCE;
                            break;
                        }
                    }

                    if (!ensureHoldingCocoa(player) || player.getBlockX() == lastFinishedBlockX) {
                        break;
                    }

                    if (System.currentTimeMillis() - lastPlantTime > 25) {
                        performPlanting(mc, player, true);
                        if (plantStage >= 4) {
                            plantStage = 0;
                            lastFinishedBlockX = player.getBlockX();
                        }
                    }
                    break;

                case CHANGING_LANE_STRAFE:
                    final double targetStrafeZ = currentRowZ + 1 - 0.3;
                    if (player.getZ() >= targetStrafeZ - 0.001) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.PLANTING_RETURN;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case CHANGING_LANE_ADVANCE:
                    final double targetAdvanceZ = currentRowZ - 0.488;
                    if(player.getZ() >= targetAdvanceZ - 0.01) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.DEPOSITING_LEFTOVERS;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case RETURNING_TO_ORIGIN:
                    if (System.currentTimeMillis() - lastStartedReturningToOriginTime < 30000){
                        break;
                    }
                    final double targetReturnZ = originZ.get() - 0.7;
                    if (player.getZ() <= targetReturnZ + 0.01) {
                        mc.options.keyUp.setDown(false);
                        justReturnedToOrigin = true;
                        currentState = State.WAITING_FOR_HARVEST;
                        if (currentRowZ != originZ.get()) currentRowZ = originZ.get();
                        return;
                    }
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);
                    break;
            }
        }

        // --- Helper Methods ---

        private static void handleDepositingLeftovers(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedChestForDepositing = true;
                boolean hasCocoa = false;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        hasCocoa = true;
                        int slotId = getContainerSlotFromInventory(player, i);
                        if(slotId != -1) {
                            clickSlot(mc, slotId, ClickType.QUICK_MOVE);
                            return; // Do one move per tick
                        }
                    }
                }
                if (!hasCocoa) player.closeContainer();
            } else {
                if (hasOpenedChestForDepositing) {
                    hasOpenedChestForDepositing = false;
                    currentState = State.TAKING_COCOA;
                    return;
                }
                if (player.getYRot() != 45f) player.setYRot(45f);
                if (player.getXRot() != 0f) player.setXRot(0f);
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.CHEST)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleTakingCocoa(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedChestForTaking = true;
                if (System.currentTimeMillis() - lastInventoryActionTime < 150) return;

                if (!player.containerMenu.getCarried().isEmpty()) {
                    int targetHotbarSlot = findAvailableHotbarSlot(player);
                    if (targetHotbarSlot != -1) {
                        int containerSlot = getContainerSlotFromInventory(player, targetHotbarSlot);
                        clickSlot(mc, containerSlot);
                    } else {
                        player.closeContainer();
                    }
                    return;
                }

                int slotToClear = findSlotToClearInHotbar(player);
                if (slotToClear != -1) {
                    int containerSlot = getContainerSlotFromInventory(player, slotToClear);
                    clickSlot(mc, containerSlot, ClickType.QUICK_MOVE);
                    return;
                }

                if (countFullCocoaStacksInHotbar(player) < 8) {
                    int sourceChestSlot = findFullCocoaStackInChest(player);
                    if (sourceChestSlot != -1) {
                        clickSlot(mc, sourceChestSlot, ClickType.QUICK_MOVE);
                        return;
                    }
                }
                player.closeContainer();
            } else {
                if (hasOpenedChestForTaking) {
                    if (System.currentTimeMillis() - lastInventoryActionTime < 250) return;
                    hasOpenedChestForTaking = false;

                    if (player.getInventory().contains(new ItemStack(Items.COCOA_BEANS))) {
                        if (justReturnedToOrigin) justReturnedToOrigin = false;
                        currentState = State.PLANTING;
                    } else {
                        reset();
                    }
                    return;
                }

                float targetYaw;
                float targetPitch;

                // Case 1: Is this the last row?
                if (currentRowZ + 3 >= farmMaxZ.get()) {
                    targetYaw = -68.6f;
                    targetPitch = 44.5f;
                }
                // Case 2: Is this the first row of a new cycle? (or the very first start)
                else if (justReturnedToOrigin || !initialized) {
                    targetYaw = 21.2f;
                    targetPitch = 47.9f;
                }
                // Case 3: All other intermediate rows
                else {
                    targetYaw = 0f;
                    targetPitch = 50f;
                }

                if (player.getYRot() != targetYaw) player.setYRot(targetYaw);
                if (player.getXRot() != targetPitch) player.setXRot(targetPitch);
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.BARREL)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void clickSlot(Minecraft mc, int slotId) {
            clickSlot(mc, slotId, ClickType.PICKUP);
        }

        private static void clickSlot(Minecraft mc, int slotId, ClickType type) {
            mc.gameMode.handleInventoryMouseClick(mc.player.containerMenu.containerId, slotId, 0, type, mc.player);
            lastInventoryActionTime = System.currentTimeMillis();
        }

        private static boolean ensureHoldingCocoa(LocalPlayer player) {
            if (player.getMainHandItem().is(Items.COCOA_BEANS)) return true;
            for (int i = 0; i < 9; i++) {
                if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                    player.getInventory().selected = i;
                    return true;
                }
            }
            return false;
        }

        private static int findAvailableHotbarSlot(LocalPlayer player) {
            for (int i = 0; i < 8; i++) {
                if (player.getInventory().getItem(i).isEmpty()) return i;
            }
            return -1;
        }

        private static int findSlotToClearInHotbar(LocalPlayer player) {
            for (int i = 0; i < 8; i++) {
                ItemStack stack = player.getInventory().getItem(i);
                if (!stack.isEmpty() && (!stack.is(Items.COCOA_BEANS) || stack.getCount() < 64)) {
                    return i;
                }
            }
            return -1;
        }

        private static int countFullCocoaStacksInHotbar(LocalPlayer player) {
            int count = 0;
            for(int i = 0; i < 8; i++) {
                ItemStack stack = player.getInventory().getItem(i);
                if (stack.is(Items.COCOA_BEANS) && stack.getCount() == 64) {
                    count++;
                }
            }
            return count;
        }

        private static int findFullCocoaStackInChest(LocalPlayer player) {
            int chestSlotCount = player.containerMenu.slots.size() - player.getInventory().getContainerSize();
            for (int i = 0; i < chestSlotCount; i++) {
                ItemStack stack = player.containerMenu.slots.get(i).getItem();
                if (stack.is(Items.COCOA_BEANS) && stack.getCount() == 64) {
                    return i;
                }
            }
            return -1;
        }

        private static int getContainerSlotFromInventory(LocalPlayer player, int inventorySlot) {
            for (int i = 0; i < player.containerMenu.slots.size(); i++) {
                var slot = player.containerMenu.slots.get(i);
                if (slot.container == player.getInventory() && slot.getContainerSlot() == inventorySlot) {
                    return i;
                }
            }
            return -1;
        }

        private static void performPlanting(Minecraft mc, LocalPlayer player, boolean isReturn) {
            BlockPos logPos;
            float pitch;
            Direction hitDirection;
            Vec3 hitVec;

            if (isReturn) {
                switch(plantStage) {
                    case 0: logPos = player.blockPosition().south().above(5); pitch = -85.3f; break;
                    case 1: logPos = player.blockPosition().south().above(4); pitch = -83f;   break;
                    case 2: logPos = player.blockPosition().south().above(3); pitch = -80f;   break;
                    case 3: logPos = player.blockPosition().south().above(2); pitch = -60f;   break;
                    default: return;
                }
                hitDirection = Direction.NORTH;
                hitVec = new Vec3(logPos.getX() + 0.5, logPos.getY() + 0.5, logPos.getZ());
            } else {
                switch(plantStage) {
                    case 0: logPos = player.blockPosition().north().above(5); pitch = -82f; break;
                    case 1: logPos = player.blockPosition().north().above(4); pitch = -80f;   break;
                    case 2: logPos = player.blockPosition().north().above(3); pitch = -73f;   break;
                    case 3: logPos = player.blockPosition().north().above(2); pitch = -60f;   break;
                    default: return;
                }
                hitDirection = Direction.SOUTH;
                hitVec = new Vec3(logPos.getX() + 0.5, logPos.getY() + 0.5, logPos.getZ() + 1.0);
            }

            player.setXRot(pitch);

            if (mc.level.getBlockState(logPos).is(BlockTags.JUNGLE_LOGS)) {
                BlockHitResult hitResult = new BlockHitResult(hitVec, hitDirection, logPos, false);
                mc.gameMode.useItemOn(player, InteractionHand.MAIN_HAND, hitResult);
            }

            plantStage++;
            lastPlantTime = System.currentTimeMillis();
        }
    }
}
Какой должна быть ферма:

1758693428991.png
 
Последнее редактирование:
Автофарм какао-бобов под фантайм, гораздо еффективнее чем в какой-то дельте. Надо запускать два бота - один ломает, другой сажает, они синкаются и один идет за другим. Бот сам чинит свой топор. Прибыль с одного бота около 30кк в час, строите 10 ферм, запускаете на сутки +пару миллиардов получаете.
Ферму нужно строить чтобы бот ходил под ней, 2 блока под бота + 4 блока бобов. Много параметров фермы hard-coded, поэтому разбирайтесь как сделать чтобы у вас это заработало.
FarmManager.java:
Expand Collapse Copy
package xyz.breadloaf.imguimc.werwedc;

import imgui.type.ImBoolean;
import imgui.type.ImInt;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CocoaBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;

public class FarmManager {
    public static class CocoaFarmer {

        // --- Configuration ---
        public static final ImInt originX = new ImInt(0);
        public static final ImInt originZ = new ImInt(-44);
        public static final ImInt farmMaxX = new ImInt(63);
        public static final ImInt farmMaxZ = new ImInt(0);
        public static final ImBoolean isEnabled = new ImBoolean(false);

        // --- State Machine ---
        private enum State {
            BREAKING,
            CHANGING_LANE_STRAFE,
            BREAKING_RETURN,
            DEPOSITING_FOR_PLANT,  // New state for planter's barrel
            DEPOSITING_FOR_STORAGE, // New state for profit chest
            CHANGING_LANE_ADVANCE,
            RETURNING_TO_ORIGIN,
            REPAIRING,
            WAITING_FOR_GROWTH
        }

        private enum RepairSubState {
            IDLE, LOCATING_BARREL, TAKING_BOTTLES, EQUIPPING_OFFHAND, REPAIRING_WITH_BOTTLES
        }

        private static State currentState = State.REPAIRING;
        private static State stateAfterDeposit;
        private static RepairSubState repairState = RepairSubState.LOCATING_BARREL;

        public static String getCurrentStateName() {
            return currentState.name() + (currentState == State.REPAIRING ? " (" + repairState.name() + ")" : "");
        }

        // --- Farming Logic ---
        private static int currentRowZ = originZ.get();
        private static boolean initialized = false;
        private static boolean wasEnabledLastTick = false;
        private static boolean hasOpenedContainer = false;
        private static int bottlesToTake = 2;
        private static long lastActionTime = 0;
        private static int repairClicksDone = 0;
        private static long lastRepairClickTime = 0;

        public static void reset() {
            isEnabled.set(false);
            currentState = State.BREAKING;
            repairState = RepairSubState.IDLE;
            initialized = false;
            currentRowZ = originZ.get();
        }

        public static void onTick(Minecraft mc) {
            boolean isCurrentlyEnabled = isEnabled.get();

            if (!isCurrentlyEnabled && wasEnabledLastTick) {
                mc.options.keyUp.setDown(false);
                mc.options.keyAttack.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyUse.setDown(false);
                reset();
            }

            wasEnabledLastTick = isCurrentlyEnabled;
            if (!isCurrentlyEnabled) return;

            final LocalPlayer player = mc.player;
            if (player == null) return;

            boolean isGuiOpen = mc.screen != null;
            boolean shouldPause = isGuiOpen && currentState != State.DEPOSITING_FOR_PLANT && currentState != State.DEPOSITING_FOR_STORAGE && currentState != State.REPAIRING;
            if (shouldPause) {
                mc.options.keyUp.setDown(false);
                mc.options.keyAttack.setDown(false);
                mc.options.keyRight.setDown(false);
                return;
            }

            if (!initialized) {
                currentRowZ = originZ.get();
                initialized = true;
            }

            switch (currentState) {
                case BREAKING:
                    if (player.getX() >= farmMaxX.get()) {
                        mc.options.keyUp.setDown(false);
                        currentState = State.CHANGING_LANE_STRAFE;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);

                    if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                        mc.gameMode.startDestroyBlock(blockHitResult.getBlockPos(), blockHitResult.getDirection());
                    }
                    break;

                case CHANGING_LANE_STRAFE:
                    final double targetStrafeZ = currentRowZ + 1 - 0.3;
                    if (player.getZ() >= targetStrafeZ - 0.001) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.BREAKING_RETURN;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case BREAKING_RETURN:
                    if (player.getZ() >= farmMaxZ.get() - 1) {
                        if (player.getX() <= originX.get() + 1.3 + 0.001) {
                            mc.options.keyUp.setDown(false);
                            stateAfterDeposit = State.RETURNING_TO_ORIGIN;
                            currentState = State.DEPOSITING_FOR_PLANT; // Start deposit sequence
                            return;
                        }
                    } else {
                        if (player.getX() <= originX.get() + 0.3 + 0.001) {
                            mc.options.keyUp.setDown(false);
                            currentRowZ += 3;
                            stateAfterDeposit = State.CHANGING_LANE_ADVANCE;
                            currentState = State.DEPOSITING_FOR_PLANT; // Start deposit sequence
                            return;
                        }
                    }
                    if (player.getYRot() != 90f) player.setYRot(90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);

                    if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                        mc.gameMode.startDestroyBlock(blockHitResult.getBlockPos(), blockHitResult.getDirection());
                    }
                    break;

                case DEPOSITING_FOR_PLANT:
                    handleDepositingForPlant(mc, player);
                    break;

                case DEPOSITING_FOR_STORAGE:
                    handleDepositingForStorage(mc, player);
                    break;

                case CHANGING_LANE_ADVANCE:
                    final double targetAdvanceZ = currentRowZ - 0.488;
                    if (player.getZ() >= targetAdvanceZ - 0.01) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.BREAKING;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (player.getXRot() != -60f) player.setXRot(-60f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case RETURNING_TO_ORIGIN:
                    if (mc.screen instanceof AbstractContainerScreen) {
                        player.closeContainer();
                    }
                    final double targetReturnZ = originZ.get() - 0.7;
                    if (player.getZ() <= targetReturnZ + 0.01) {
                        mc.options.keyUp.setDown(false);
                        repairState = RepairSubState.LOCATING_BARREL;
                        currentState = State.REPAIRING;
                        repairClicksDone = 0; // Reset for the new repair cycle
                        currentRowZ = originZ.get();
                        return;
                    }
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (player.getXRot() != 0f) player.setXRot(0f);
                    if (currentRowZ != originZ.get()) currentRowZ = originZ.get();
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);
                    break;

                case REPAIRING:
                    handleRepairing(mc, player);
                    break;

                case WAITING_FOR_GROWTH:
                    int grownCocoaCount = 0;
                    for (int x = -3; x <= 3; x++) {
                        for (int y = -3; y <= 3; y++) {
                            for (int z = -3; z <= 3; z++) {
                                BlockPos pos = player.blockPosition().offset(x, y, z);
                                BlockState state = mc.level.getBlockState(pos);
                                if (state.getBlock() instanceof CocoaBlock && state.getValue(CocoaBlock.AGE) == 2) {
                                    grownCocoaCount++;
                                }
                            }
                        }
                    }
                    if (grownCocoaCount >= 3) {
                        currentState = State.BREAKING;
                    }
                    break;
            }
        }

        private static void handleDepositingForPlant(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedContainer = true;
                if (System.currentTimeMillis() - lastActionTime < 200) return;

                int cocoaInBarrel = countItemsInContainer(player, Items.COCOA_BEANS);
                int cocoaInPlayer = countItemsInInventory(player, Items.COCOA_BEANS);

                if (cocoaInBarrel >= 8 * 64 || cocoaInPlayer == 0) {
                    player.closeContainer();
                    return;
                }

                // Find a stack in player inv to move
                int playerSlot = -1;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        playerSlot = getContainerSlotFromInventory(player, i);
                        break;
                    }
                }

                if (playerSlot != -1) {
                    mc.gameMode.handleInventoryMouseClick(player.containerMenu.containerId, playerSlot, 0, ClickType.QUICK_MOVE, player);
                    lastActionTime = System.currentTimeMillis();
                } else { // No more cocoa to move
                    player.closeContainer();
                }

            } else { // GUI is not open
                if (hasOpenedContainer) {
                    hasOpenedContainer = false;
                    currentState = State.DEPOSITING_FOR_STORAGE; // Proceed to next deposit stage
                    return;
                }
                if (player.getYRot() != 90f) player.setYRot(90f);
                if (player.getXRot() != 90f) player.setXRot(90f); // Look down for barrel
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.BARREL)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleDepositingForStorage(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedContainer = true;
                boolean hasCocoa = false;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        hasCocoa = true;
                        int slotId = getContainerSlotFromInventory(player, i);
                        if(slotId != -1) {
                            mc.gameMode.handleInventoryMouseClick(player.containerMenu.containerId, slotId, 0, ClickType.QUICK_MOVE, player);
                            return;
                        }
                    }
                }
                if (!hasCocoa) player.closeContainer();
            } else {
                if (hasOpenedContainer) {
                    hasOpenedContainer = false;
                    currentState = stateAfterDeposit; // Transition to final destination
                    return;
                }
                if (player.getYRot() != 90f) player.setYRot(90f);
                if (player.getXRot() != 0f) player.setXRot(0f); // Look straight for chest
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.CHEST)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleRepairing(Minecraft mc, LocalPlayer player) {
            // Check if we have completed all 60 clicks
            if (repairClicksDone >= 130) {
                currentState = State.WAITING_FOR_GROWTH;
                return;
            }

            // Set the player's rotation
            if (player.getYRot() != -170f) player.setYRot(-170f);
            if (player.getXRot() != 0f) player.setXRot(0f);

            // Check if 500ms have passed since the last click
            if (System.currentTimeMillis() - lastRepairClickTime > 500) {
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.LEVER)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                        repairClicksDone++;
                        lastRepairClickTime = System.currentTimeMillis();
                    }
                }
            }
        }

        private static int getContainerSlotFromInventory(LocalPlayer player, int inventorySlot) {
            for (int i = 0; i < player.containerMenu.slots.size(); i++) {
                var slot = player.containerMenu.slots.get(i);
                if (slot.container == player.getInventory() && slot.getContainerSlot() == inventorySlot) {
                    return i;
                }
            }
            return -1;
        }

        private static int countItemsInContainer(LocalPlayer player, net.minecraft.world.item.Item item) {
            if (!(Minecraft.getInstance().screen instanceof AbstractContainerScreen)) return 0;
            int count = 0;
            int containerSlots = player.containerMenu.slots.size() - player.getInventory().getContainerSize();
            for(int i = 0; i < containerSlots; i++) {
                ItemStack stack = player.containerMenu.slots.get(i).getItem();
                if(stack.is(item)) {
                    count += stack.getCount();
                }
            }
            return count;
        }

        private static int countItemsInInventory(LocalPlayer player, net.minecraft.world.item.Item item) {
            int count = 0;
            for(ItemStack stack : player.getInventory().items) {
                if(stack.is(item)) {
                    count += stack.getCount();
                }
            }
            return count;
        }
    }
}

PlantManager.java:
Expand Collapse Copy
package xyz.breadloaf.imguimc.werwedc;

import imgui.type.ImBoolean;
import imgui.type.ImInt;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CocoaBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;

public class PlantManager {
    public static class CocoaPlanter {

        // --- Configuration ---
        public static final ImInt originX = new ImInt(0);
        public static final ImInt originZ = new ImInt(-44);
        public static final ImInt farmMaxX = new ImInt(63);
        public static final ImInt farmMaxZ = new ImInt(0);
        public static final ImBoolean isEnabled = new ImBoolean(false);

        // --- State Machine ---
        private enum State {
            WAITING_FOR_HARVEST,
            DEPOSITING_LEFTOVERS, // New state
            TAKING_COCOA,
            PLANTING,
            CHANGING_LANE_STRAFE,
            PLANTING_RETURN,
            CHANGING_LANE_ADVANCE,
            RETURNING_TO_ORIGIN
        }

        private static State currentState = State.TAKING_COCOA;
        private static boolean wasEnabledLastTick = false;
        private static int plantStage = 0;
        private static boolean hasOpenedChestForTaking = false;
        private static boolean hasOpenedChestForDepositing = false;
        private static long lastPlantTime = 0;
        private static long lastInventoryActionTime = 0;
        private static int lastFinishedBlockX = -10000;
        private static int currentRowZ = originZ.get();
        private static boolean initialized = false;
        private static boolean justReturnedToOrigin = false;
        private static long lastStartedReturningToOriginTime = 0;
        public static String getCurrentStateName() {
            return currentState.name();
        }

        public static void reset() {
            isEnabled.set(false);
            currentState = State.TAKING_COCOA;
            plantStage = 0;
            lastFinishedBlockX = -10000;
            initialized = false;
            hasOpenedChestForTaking = false;
            hasOpenedChestForDepositing = false;
            justReturnedToOrigin = false;
            currentRowZ = originZ.get();
        }

        public static void onTick(Minecraft mc) {
            boolean isCurrentlyEnabled = isEnabled.get();

            if (!isCurrentlyEnabled && wasEnabledLastTick) {
                mc.options.keyUp.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyLeft.setDown(false);
                reset();
            }

            wasEnabledLastTick = isCurrentlyEnabled;

            if (!isCurrentlyEnabled) {
                return;
            }

            final LocalPlayer player = mc.player;
            if (player == null) {
                return;
            }

            if (mc.screen instanceof ChatScreen) {
                mc.options.keyUp.setDown(false);
                mc.options.keyRight.setDown(false);
                mc.options.keyLeft.setDown(false);
                return;
            }

            if (!initialized) {
                currentRowZ = originZ.get();
                initialized = true;
            }

            switch (currentState) {
                case WAITING_FOR_HARVEST:
                    for (int x = -3; x <= 3; x++) {
                        for (int y = -3; y <= 3; y++) {
                            for (int z = -3; z <= 3; z++) {
                                BlockPos pos = player.blockPosition().offset(x, y, z);
                                if (mc.level.getBlockState(pos).getBlock() instanceof CocoaBlock) {
                                    return;
                                }
                            }
                        }
                    }
                    currentState = State.DEPOSITING_LEFTOVERS;
                    break;

                case DEPOSITING_LEFTOVERS:
                    handleDepositingLeftovers(mc, player);
                    break;

                case TAKING_COCOA:
                    handleTakingCocoa(mc, player);
                    break;

                case PLANTING:
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);

                    if (player.getBlockX() >= farmMaxX.get()) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.CHANGING_LANE_STRAFE;
                        break;
                    }

                    if (!ensureHoldingCocoa(player) || player.getBlockX() == lastFinishedBlockX) {
                        break;
                    }

                    if (System.currentTimeMillis() - lastPlantTime > 25) {
                        performPlanting(mc, player, false);
                        if (plantStage >= 4) {
                            plantStage = 0;
                            lastFinishedBlockX = player.getBlockX();
                        }
                    }
                    break;

                case PLANTING_RETURN:
                    if (player.getYRot() != 0f) player.setYRot(0f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);

                    if (player.getZ() >= farmMaxZ.get() - 1) {
                        if (player.getX() <= originX.get() + 1.3 + 0.001) {
                            mc.options.keyRight.setDown(false);
                            currentState = State.RETURNING_TO_ORIGIN;
                            lastStartedReturningToOriginTime = System.currentTimeMillis();
                            break;
                        }
                    } else {
                        if (player.getX() <= originX.get() + 0.3 + 0.001) {
                            mc.options.keyRight.setDown(false);
                            currentRowZ += 3;
                            currentState = State.CHANGING_LANE_ADVANCE;
                            break;
                        }
                    }

                    if (!ensureHoldingCocoa(player) || player.getBlockX() == lastFinishedBlockX) {
                        break;
                    }

                    if (System.currentTimeMillis() - lastPlantTime > 25) {
                        performPlanting(mc, player, true);
                        if (plantStage >= 4) {
                            plantStage = 0;
                            lastFinishedBlockX = player.getBlockX();
                        }
                    }
                    break;

                case CHANGING_LANE_STRAFE:
                    final double targetStrafeZ = currentRowZ + 1 - 0.3;
                    if (player.getZ() >= targetStrafeZ - 0.001) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.PLANTING_RETURN;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case CHANGING_LANE_ADVANCE:
                    final double targetAdvanceZ = currentRowZ - 0.488;
                    if(player.getZ() >= targetAdvanceZ - 0.01) {
                        mc.options.keyRight.setDown(false);
                        currentState = State.DEPOSITING_LEFTOVERS;
                        return;
                    }
                    if (player.getYRot() != -90f) player.setYRot(-90f);
                    if (!mc.options.keyRight.isDown()) mc.options.keyRight.setDown(true);
                    break;

                case RETURNING_TO_ORIGIN:
                    if (System.currentTimeMillis() - lastStartedReturningToOriginTime < 30000){
                        break;
                    }
                    final double targetReturnZ = originZ.get() - 0.7;
                    if (player.getZ() <= targetReturnZ + 0.01) {
                        mc.options.keyUp.setDown(false);
                        justReturnedToOrigin = true;
                        currentState = State.WAITING_FOR_HARVEST;
                        if (currentRowZ != originZ.get()) currentRowZ = originZ.get();
                        return;
                    }
                    if (player.getYRot() != -180f) player.setYRot(-180f);
                    if (!mc.options.keyUp.isDown()) mc.options.keyUp.setDown(true);
                    break;
            }
        }

        // --- Helper Methods ---

        private static void handleDepositingLeftovers(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedChestForDepositing = true;
                boolean hasCocoa = false;
                for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
                    if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                        hasCocoa = true;
                        int slotId = getContainerSlotFromInventory(player, i);
                        if(slotId != -1) {
                            clickSlot(mc, slotId, ClickType.QUICK_MOVE);
                            return; // Do one move per tick
                        }
                    }
                }
                if (!hasCocoa) player.closeContainer();
            } else {
                if (hasOpenedChestForDepositing) {
                    hasOpenedChestForDepositing = false;
                    currentState = State.TAKING_COCOA;
                    return;
                }
                if (player.getYRot() != 45f) player.setYRot(45f);
                if (player.getXRot() != 0f) player.setXRot(0f);
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.CHEST)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void handleTakingCocoa(Minecraft mc, LocalPlayer player) {
            if (mc.screen instanceof AbstractContainerScreen) {
                hasOpenedChestForTaking = true;
                if (System.currentTimeMillis() - lastInventoryActionTime < 150) return;

                if (!player.containerMenu.getCarried().isEmpty()) {
                    int targetHotbarSlot = findAvailableHotbarSlot(player);
                    if (targetHotbarSlot != -1) {
                        int containerSlot = getContainerSlotFromInventory(player, targetHotbarSlot);
                        clickSlot(mc, containerSlot);
                    } else {
                        player.closeContainer();
                    }
                    return;
                }

                int slotToClear = findSlotToClearInHotbar(player);
                if (slotToClear != -1) {
                    int containerSlot = getContainerSlotFromInventory(player, slotToClear);
                    clickSlot(mc, containerSlot, ClickType.QUICK_MOVE);
                    return;
                }

                if (countFullCocoaStacksInHotbar(player) < 8) {
                    int sourceChestSlot = findFullCocoaStackInChest(player);
                    if (sourceChestSlot != -1) {
                        clickSlot(mc, sourceChestSlot, ClickType.QUICK_MOVE);
                        return;
                    }
                }
                player.closeContainer();
            } else {
                if (hasOpenedChestForTaking) {
                    if (System.currentTimeMillis() - lastInventoryActionTime < 250) return;
                    hasOpenedChestForTaking = false;

                    if (player.getInventory().contains(new ItemStack(Items.COCOA_BEANS))) {
                        if (justReturnedToOrigin) justReturnedToOrigin = false;
                        currentState = State.PLANTING;
                    } else {
                        reset();
                    }
                    return;
                }

                float targetYaw;
                float targetPitch;

                // Case 1: Is this the last row?
                if (currentRowZ + 3 >= farmMaxZ.get()) {
                    targetYaw = -68.6f;
                    targetPitch = 44.5f;
                }
                // Case 2: Is this the first row of a new cycle? (or the very first start)
                else if (justReturnedToOrigin || !initialized) {
                    targetYaw = 21.2f;
                    targetPitch = 47.9f;
                }
                // Case 3: All other intermediate rows
                else {
                    targetYaw = 0f;
                    targetPitch = 50f;
                }

                if (player.getYRot() != targetYaw) player.setYRot(targetYaw);
                if (player.getXRot() != targetPitch) player.setXRot(targetPitch);
                if (mc.hitResult instanceof BlockHitResult blockHitResult) {
                    if (mc.level.getBlockState(blockHitResult.getBlockPos()).is(Blocks.BARREL)) {
                        mc.gameMode.useItemOn(player, player.getUsedItemHand(), blockHitResult);
                    }
                }
            }
        }

        private static void clickSlot(Minecraft mc, int slotId) {
            clickSlot(mc, slotId, ClickType.PICKUP);
        }

        private static void clickSlot(Minecraft mc, int slotId, ClickType type) {
            mc.gameMode.handleInventoryMouseClick(mc.player.containerMenu.containerId, slotId, 0, type, mc.player);
            lastInventoryActionTime = System.currentTimeMillis();
        }

        private static boolean ensureHoldingCocoa(LocalPlayer player) {
            if (player.getMainHandItem().is(Items.COCOA_BEANS)) return true;
            for (int i = 0; i < 9; i++) {
                if (player.getInventory().getItem(i).is(Items.COCOA_BEANS)) {
                    player.getInventory().selected = i;
                    return true;
                }
            }
            return false;
        }

        private static int findAvailableHotbarSlot(LocalPlayer player) {
            for (int i = 0; i < 8; i++) {
                if (player.getInventory().getItem(i).isEmpty()) return i;
            }
            return -1;
        }

        private static int findSlotToClearInHotbar(LocalPlayer player) {
            for (int i = 0; i < 8; i++) {
                ItemStack stack = player.getInventory().getItem(i);
                if (!stack.isEmpty() && (!stack.is(Items.COCOA_BEANS) || stack.getCount() < 64)) {
                    return i;
                }
            }
            return -1;
        }

        private static int countFullCocoaStacksInHotbar(LocalPlayer player) {
            int count = 0;
            for(int i = 0; i < 8; i++) {
                ItemStack stack = player.getInventory().getItem(i);
                if (stack.is(Items.COCOA_BEANS) && stack.getCount() == 64) {
                    count++;
                }
            }
            return count;
        }

        private static int findFullCocoaStackInChest(LocalPlayer player) {
            int chestSlotCount = player.containerMenu.slots.size() - player.getInventory().getContainerSize();
            for (int i = 0; i < chestSlotCount; i++) {
                ItemStack stack = player.containerMenu.slots.get(i).getItem();
                if (stack.is(Items.COCOA_BEANS) && stack.getCount() == 64) {
                    return i;
                }
            }
            return -1;
        }

        private static int getContainerSlotFromInventory(LocalPlayer player, int inventorySlot) {
            for (int i = 0; i < player.containerMenu.slots.size(); i++) {
                var slot = player.containerMenu.slots.get(i);
                if (slot.container == player.getInventory() && slot.getContainerSlot() == inventorySlot) {
                    return i;
                }
            }
            return -1;
        }

        private static void performPlanting(Minecraft mc, LocalPlayer player, boolean isReturn) {
            BlockPos logPos;
            float pitch;
            Direction hitDirection;
            Vec3 hitVec;

            if (isReturn) {
                switch(plantStage) {
                    case 0: logPos = player.blockPosition().south().above(5); pitch = -85.3f; break;
                    case 1: logPos = player.blockPosition().south().above(4); pitch = -83f;   break;
                    case 2: logPos = player.blockPosition().south().above(3); pitch = -80f;   break;
                    case 3: logPos = player.blockPosition().south().above(2); pitch = -60f;   break;
                    default: return;
                }
                hitDirection = Direction.NORTH;
                hitVec = new Vec3(logPos.getX() + 0.5, logPos.getY() + 0.5, logPos.getZ());
            } else {
                switch(plantStage) {
                    case 0: logPos = player.blockPosition().north().above(5); pitch = -82f; break;
                    case 1: logPos = player.blockPosition().north().above(4); pitch = -80f;   break;
                    case 2: logPos = player.blockPosition().north().above(3); pitch = -73f;   break;
                    case 3: logPos = player.blockPosition().north().above(2); pitch = -60f;   break;
                    default: return;
                }
                hitDirection = Direction.SOUTH;
                hitVec = new Vec3(logPos.getX() + 0.5, logPos.getY() + 0.5, logPos.getZ() + 1.0);
            }

            player.setXRot(pitch);

            if (mc.level.getBlockState(logPos).is(BlockTags.JUNGLE_LOGS)) {
                BlockHitResult hitResult = new BlockHitResult(hitVec, hitDirection, logPos, false);
                mc.gameMode.useItemOn(player, InteractionHand.MAIN_HAND, hitResult);
            }

            plantStage++;
            lastPlantTime = System.currentTimeMillis();
        }
    }
}
Какой должна быть ферма:

Посмотреть вложение 316457
Ну молодец,реально полезная вещь,очень круто.
 
А, забыл добавить, что там куча задержек потому что фантайм начинает искуственно залагивать гуишки если их слишком часто открывать
 

Похожие темы

Назад
Сверху Снизу