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

Часть функционала AutoPotion Авто Зелье варка Update

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
17 Июл 2024
Сообщения
383
Реакции
5
Выберите загрузчик игры
  1. Vanilla
  2. Прочие моды
Сделал апдейп который все просили чтобы я сделал больше 1 зелье варки и убрал обосаные кординаты и я сделал
cс не будет моего потому что мне снесли ютуб( будет конетина
Пожалуйста, авторизуйтесь для просмотра ссылки.
1:06 работает так само только сделал чтобы он поворачивался как в килке
Код:
Expand Collapse Copy
package client.main.module.impl.misc;

import client.events.EventUpdate;
import client.main.module.api.Category;
import client.main.module.api.Module;
import client.main.module.api.ModuleRegister;
import client.main.module.settings.impl.BooleanSetting;
import client.main.module.settings.impl.ModeSetting;
import client.main.component.impl.Rotation;
import client.main.component.impl.RotationComponent;
import client.util.math.StopWatch;
import com.google.common.eventbus.Subscribe;
import net.minecraft.client.gui.screen.inventory.BrewingStandScreen;
import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.inventory.container.BrewingStandContainer;
import net.minecraft.inventory.container.ChestContainer;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.tileentity.BrewingStandTileEntity;
import net.minecraft.tileentity.ChestTileEntity;
import net.minecraft.tileentity.TileEntity;
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.vector.Vector3d;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@ModuleRegister(name = "AutoPotion", type = Category.Misc, desc = "Auto brew: scans chests by content, multiple stands")
public class AutoPotion extends Module {

    private final ModeSetting recipe = new ModeSetting("Рецепт", "Невидимость", "Невидимость", "Сила 2", "Скорость 2");
    private final BooleanSetting useChests = new BooleanSetting("Сундуки", true);

    private static final Item[] RECIPE_INVISIBILITY = {Items.NETHER_WART, Items.GOLDEN_CARROT, Items.FERMENTED_SPIDER_EYE, Items.REDSTONE};
    private static final Item[] RECIPE_STRENGTH_2 = {Items.NETHER_WART, Items.BLAZE_POWDER, Items.GLOWSTONE_DUST};
    private static final Item[] RECIPE_SPEED_2 = {Items.NETHER_WART, Items.SUGAR, Items.GLOWSTONE_DUST};

    private enum Stage {
        SCAN_BLOCKS,
        ANALYZE_OPEN, ANALYZE_CHECK,
        TAKE_BOTTLES_OPEN, TAKE_BOTTLES,
        TAKE_ING_OPEN, TAKE_ING,
        FILL_OPEN, FILL_BOTTLES, FILL_ING,
        WAIT_BREW,
        COLLECT_OPEN, COLLECT,
        STORE_OPEN, STORE
    }

    private BlockPos bottleChest = null;
    private BlockPos ingredientChest = null;
    private BlockPos potionChest = null;
    private final List<BlockPos> allChests = new ArrayList<>();
    private int analyzeIdx = 0;
    private final List<BlockPos> stands = new ArrayList<>();
    private int standIdx = 0;
    private int ingStep = 0;
    private Stage stage = Stage.SCAN_BLOCKS;
    private final StopWatch timer = new StopWatch();
    private final StopWatch openTimer = new StopWatch();
    private boolean analyzed = false;

    public AutoPotion() { addSettings(recipe, useChests); }

    private Item[] getRecipe() {
        if (recipe.is("Сила 2")) return RECIPE_STRENGTH_2;
        if (recipe.is("Скорость 2")) return RECIPE_SPEED_2;
        return RECIPE_INVISIBILITY;
    }

    @Override
    public boolean onEnable() {
        stage = Stage.SCAN_BLOCKS;
        stands.clear(); allChests.clear();
        bottleChest = ingredientChest = potionChest = null;
        standIdx = 0; ingStep = 0; analyzeIdx = 0; analyzed = false;
        return super.onEnable();
    }

    @Override
    public boolean onDisable() {
        if (mc.player != null && mc.currentScreen != null) mc.player.closeScreen();
        return super.onDisable();
    }

    @Subscribe
    public void onUpdate(EventUpdate e) {
        if (mc.player == null || mc.world == null) return;
        if (!timer.isReached(150)) return;
        timer.reset();

        switch (stage) {
            case SCAN_BLOCKS -> scanBlocks();
            case ANALYZE_OPEN -> analyzeOpen();
            case ANALYZE_CHECK -> analyzeCheck();
            case TAKE_BOTTLES_OPEN -> chestOpen(bottleChest, Stage.TAKE_BOTTLES);
            case TAKE_BOTTLES -> takeBottles();
            case TAKE_ING_OPEN -> chestOpen(ingredientChest, Stage.TAKE_ING);
            case TAKE_ING -> takeIngredients();
            case FILL_OPEN -> fillOpen();
            case FILL_BOTTLES -> fillBottles();
            case FILL_ING -> fillIngredient();
            case WAIT_BREW -> waitBrew();
            case COLLECT_OPEN -> collectOpen();
            case COLLECT -> collect();
            case STORE_OPEN -> chestOpen(potionChest, Stage.STORE);
            case STORE -> store();
        }
    }

    private void scanBlocks() {
        if (analyzed) { startBrewing(); return; }
        stands.clear(); allChests.clear();
        BlockPos p = mc.player.getPosition();
        for (BlockPos pos : BlockPos.getAllInBoxMutable(p.add(-5,-3,-5), p.add(5,3,5))) {
            TileEntity te = mc.world.getTileEntity(pos);
            if (te instanceof ChestTileEntity || te instanceof net.minecraft.tileentity.TrappedChestTileEntity) {
                BlockPos imm = pos.toImmutable();
                boolean duplicate = false;
                for (BlockPos existing : allChests) {
                    if (existing.getX() == imm.getX() && existing.getY() == imm.getY()
                            && Math.abs(existing.getZ() - imm.getZ()) <= 1) { duplicate = true; break; }
                    if (existing.getZ() == imm.getZ() && existing.getY() == imm.getY()
                            && Math.abs(existing.getX() - imm.getX()) <= 1) { duplicate = true; break; }
                }
                if (!duplicate) allChests.add(imm);
            }
            else if (te instanceof BrewingStandTileEntity)
                stands.add(pos.toImmutable());
        }
        if (stands.isEmpty()) { print("Зельеварки не найдены!"); setenabled(false, false); return; }
        stands.sort(Comparator.comparingDouble(pos -> mc.player.getDistanceSq(pos.getX(), pos.getY(), pos.getZ())));
        if (!useChests.get() || allChests.isEmpty()) { analyzed = true; startBrewing(); return; }
        analyzeIdx = 0;
        stage = Stage.ANALYZE_OPEN;
    }

    private void analyzeOpen() {
        if (analyzeIdx >= allChests.size()) {
            analyzed = true;
            mc.player.closeScreen();
            print("Бутылки:" + (bottleChest != null ? "OK" : "нет")
                    + " Ингр:" + (ingredientChest != null ? "OK" : "нет")
                    + " Зелья:" + (potionChest != null ? "OK" : "нет"));
            startBrewing();
            return;
        }
        if (isChestOpen()) { stage = Stage.ANALYZE_CHECK; return; }
        if (openTimer.isReached(700)) { openBlock(allChests.get(analyzeIdx)); openTimer.reset(); }
    }

    private void analyzeCheck() {
        if (!isChestOpen()) { stage = Stage.ANALYZE_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean hasWaterBottles = false;
        boolean hasIngredients = false;
        boolean hasPotions = false;
        boolean isEmpty = true;
        Item[] rec = getRecipe();
        for (int i = 0; i < slots; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (s.isEmpty()) continue;
            isEmpty = false;
            if (s.getItem() == Items.POTION) {
                if (PotionUtils.getPotionFromItem(s) == Potions.WATER) hasWaterBottles = true;
                else hasPotions = true;
            }
            for (Item ing : rec) {
                if (s.getItem() == ing) { hasIngredients = true; break; }
            }
        }
        BlockPos pos = allChests.get(analyzeIdx);
        if (hasWaterBottles && bottleChest == null) bottleChest = pos;
        else if (hasIngredients && ingredientChest == null) ingredientChest = pos;
        else if ((hasPotions || isEmpty) && potionChest == null) potionChest = pos;
        mc.player.closeScreen();
        analyzeIdx++;
        stage = Stage.ANALYZE_OPEN;
    }

    private void startBrewing() {
        standIdx = 0; ingStep = 0;
        if (useChests.get() && bottleChest != null && needBottles()) stage = Stage.TAKE_BOTTLES_OPEN;
        else if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
        else stage = Stage.FILL_OPEN;
    }

    private void chestOpen(BlockPos pos, Stage next) {
        if (pos == null) { stage = Stage.FILL_OPEN; return; }
        if (isChestOpen()) { stage = next; return; }
        if (openTimer.isReached(700)) { openBlock(pos); openTimer.reset(); }
    }

    private void takeBottles() {
        if (!isChestOpen()) { stage = Stage.TAKE_BOTTLES_OPEN; return; }
        int emptySlots = 0;
        for (int i = 0; i < 36; i++) if (mc.player.inventory.getStackInSlot(i).isEmpty()) emptySlots++;
        if (emptySlots <= 9) {
            mc.player.closeScreen();
            if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
            else stage = Stage.FILL_OPEN;
            return;
        }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean took = false;
        for (int i = 0; i < slots; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (!s.isEmpty() && s.getItem() == Items.POTION
                    && PotionUtils.getPotionFromItem(s) == Potions.WATER) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                took = true; break;
            }
        }
        if (!took || !needBottles()) {
            mc.player.closeScreen();
            if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
            else stage = Stage.FILL_OPEN;
        }
    }

    private void takeIngredients() {
        if (!isChestOpen()) { stage = Stage.TAKE_ING_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean took = false;
        Item[] rec = getRecipe();
        for (Item ing : rec) {
            if (hasItem(ing)) continue;
            for (int i = 0; i < slots; i++) {
                ItemStack s = c.inventorySlots.get(i).getStack();
                if (!s.isEmpty() && s.getItem() == ing) {
                    mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                    took = true; break;
                }
            }
            if (took) break;
        }
        if (!took) { mc.player.closeScreen(); stage = Stage.FILL_OPEN; }
    }

    private void store() {
        if (!isChestOpen()) { stage = Stage.STORE_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int chestSlots = c.getNumRows() * 9;
        int total = c.inventorySlots.size();
        boolean stored = false;
        for (int i = chestSlots; i < total; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (!s.isEmpty() && s.getItem() == Items.POTION
                    && PotionUtils.getPotionFromItem(s) != Potions.WATER) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                stored = true; break;
            }
        }
        if (!stored) { mc.player.closeScreen(); startBrewing(); }
    }

    private void fillOpen() {
        if (standIdx >= stands.size()) { standIdx = 0; stage = Stage.WAIT_BREW; return; }
        if (isBrewingOpen()) { stage = Stage.FILL_BOTTLES; return; }
        if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
    }

    private void fillBottles() {
        if (!isBrewingOpen()) { stage = Stage.FILL_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        for (int i = 0; i <= 2; i++) {
            if (c.inventorySlots.get(i).getStack().isEmpty()) {
                int cs = findBrewSlot(Items.POTION, true);
                if (cs != -1) {
                    mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                    mc.playerController.windowClick(c.windowId, i, 1, ClickType.PICKUP, mc.player);
                    mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                    return;
                } else {
                    if (useChests.get() && bottleChest != null) {
                        mc.player.closeScreen();
                        stage = Stage.TAKE_BOTTLES_OPEN;
                        return;
                    }
                }
            }
        }
        stage = Stage.FILL_ING;
    }

    private void fillIngredient() {
        if (!isBrewingOpen()) { stage = Stage.FILL_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        Item ing = getRecipe()[ingStep];
        ItemStack slot3 = c.inventorySlots.get(3).getStack();
        if (!slot3.isEmpty() && slot3.getItem() != ing) {
            mc.playerController.windowClick(c.windowId, 3, 0, ClickType.QUICK_MOVE, mc.player);
            return;
        }
        if (slot3.isEmpty()) {
            int cs = findBrewSlot(ing, false);
            if (cs != -1) {
                mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                mc.playerController.windowClick(c.windowId, 3, 1, ClickType.PICKUP, mc.player);
                mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
            } else {
                if (useChests.get() && ingredientChest != null) {
                    mc.player.closeScreen();
                    stage = Stage.TAKE_ING_OPEN;
                    return;
                }
            }
        }
        mc.player.closeScreen(); standIdx++; stage = Stage.FILL_OPEN;
    }

    private void waitBrew() {
        if (!isBrewingOpen()) {
            if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
            return;
        }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        if (c.inventorySlots.get(3).getStack().isEmpty()) {
            mc.player.closeScreen();
            standIdx++;
            if (standIdx >= stands.size()) {
                standIdx = 0;
                ingStep++;
                if (ingStep >= getRecipe().length) { standIdx = 0; stage = Stage.COLLECT_OPEN; }
                else { standIdx = 0; stage = Stage.FILL_OPEN; }
            }
        }
    }

    private void collectOpen() {
        if (standIdx >= stands.size()) {
            stage = (useChests.get() && potionChest != null) ? Stage.STORE_OPEN : Stage.FILL_OPEN;
            standIdx = 0; ingStep = 0; return;
        }
        if (isBrewingOpen()) { stage = Stage.COLLECT; return; }
        if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
    }

    private void collect() {
        if (!isBrewingOpen()) { stage = Stage.COLLECT_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        boolean found = false;
        for (int i = 0; i <= 2; i++) {
            if (!c.inventorySlots.get(i).getStack().isEmpty()) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                found = true; break;
            }
        }
        if (!found) { mc.player.closeScreen(); standIdx++; }
    }

    private void openBlock(BlockPos pos) {
        if (pos == null) return;
        Vector3d target = Vector3d.copyCentered(pos);
        Vector3d eyes = mc.player.getEyePosition(1.0f);
        Vector3d diff = target.subtract(eyes).normalize();
        float yaw = (float) Math.toDegrees(Math.atan2(-diff.x, diff.z));
        float pitch = (float) -Math.toDegrees(Math.atan2(diff.y, Math.hypot(diff.x, diff.z)));
        RotationComponent.update(new Rotation(yaw, pitch), 360.0f, 360.0f, 0, 1);
        BlockRayTraceResult rtr = new BlockRayTraceResult(
                Vector3d.copyCentered(pos), Direction.UP, pos, false);
        mc.playerController.processRightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, rtr);
    }

    private boolean isBrewingOpen() {
        return mc.currentScreen instanceof BrewingStandScreen && mc.player.openContainer instanceof BrewingStandContainer;
    }

    private boolean isChestOpen() {
        return mc.currentScreen instanceof ChestScreen && mc.player.openContainer instanceof ChestContainer;
    }

    private boolean needBottles() {
        int c = 0;
        int emptySlots = 0;
        for (int i = 0; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) == Potions.WATER) c += s.getCount();
            if (s.isEmpty()) emptySlots++;
        }
        return c < stands.size() * 3 && emptySlots > 9;
    }

    private boolean needIngredients() {
        for (Item i : getRecipe()) if (!hasItem(i)) return true;
        return false;
    }

    private boolean hasItem(Item item) {
        for (int i = 0; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (!s.isEmpty() && s.getItem() == item) return true;
        }
        return false;
    }

    private int findBrewSlot(Item item, boolean water) {
        for (int i = 9; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.isEmpty() || s.getItem() != item) continue;
            if (water && s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) != Potions.WATER) continue;
            return (i - 9) + 5;
        }
        for (int i = 0; i < 9; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.isEmpty() || s.getItem() != item) continue;
            if (water && s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) != Potions.WATER) continue;
            return i + 32;
        }
        return -1;
    }
}
 
Сделал апдейп который все просили чтобы я сделал больше 1 зелье варки и убрал обосаные кординаты и я сделал
cс не будет моего потому что мне снесли ютуб( будет конетина
Пожалуйста, авторизуйтесь для просмотра ссылки.
1:06 работает так само только сделал чтобы он поворачивался как в килке
Код:
Expand Collapse Copy
package client.main.module.impl.misc;

import client.events.EventUpdate;
import client.main.module.api.Category;
import client.main.module.api.Module;
import client.main.module.api.ModuleRegister;
import client.main.module.settings.impl.BooleanSetting;
import client.main.module.settings.impl.ModeSetting;
import client.main.component.impl.Rotation;
import client.main.component.impl.RotationComponent;
import client.util.math.StopWatch;
import com.google.common.eventbus.Subscribe;
import net.minecraft.client.gui.screen.inventory.BrewingStandScreen;
import net.minecraft.client.gui.screen.inventory.ChestScreen;
import net.minecraft.inventory.container.BrewingStandContainer;
import net.minecraft.inventory.container.ChestContainer;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.tileentity.BrewingStandTileEntity;
import net.minecraft.tileentity.ChestTileEntity;
import net.minecraft.tileentity.TileEntity;
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.vector.Vector3d;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@ModuleRegister(name = "AutoPotion", type = Category.Misc, desc = "Auto brew: scans chests by content, multiple stands")
public class AutoPotion extends Module {

    private final ModeSetting recipe = new ModeSetting("Рецепт", "Невидимость", "Невидимость", "Сила 2", "Скорость 2");
    private final BooleanSetting useChests = new BooleanSetting("Сундуки", true);

    private static final Item[] RECIPE_INVISIBILITY = {Items.NETHER_WART, Items.GOLDEN_CARROT, Items.FERMENTED_SPIDER_EYE, Items.REDSTONE};
    private static final Item[] RECIPE_STRENGTH_2 = {Items.NETHER_WART, Items.BLAZE_POWDER, Items.GLOWSTONE_DUST};
    private static final Item[] RECIPE_SPEED_2 = {Items.NETHER_WART, Items.SUGAR, Items.GLOWSTONE_DUST};

    private enum Stage {
        SCAN_BLOCKS,
        ANALYZE_OPEN, ANALYZE_CHECK,
        TAKE_BOTTLES_OPEN, TAKE_BOTTLES,
        TAKE_ING_OPEN, TAKE_ING,
        FILL_OPEN, FILL_BOTTLES, FILL_ING,
        WAIT_BREW,
        COLLECT_OPEN, COLLECT,
        STORE_OPEN, STORE
    }

    private BlockPos bottleChest = null;
    private BlockPos ingredientChest = null;
    private BlockPos potionChest = null;
    private final List<BlockPos> allChests = new ArrayList<>();
    private int analyzeIdx = 0;
    private final List<BlockPos> stands = new ArrayList<>();
    private int standIdx = 0;
    private int ingStep = 0;
    private Stage stage = Stage.SCAN_BLOCKS;
    private final StopWatch timer = new StopWatch();
    private final StopWatch openTimer = new StopWatch();
    private boolean analyzed = false;

    public AutoPotion() { addSettings(recipe, useChests); }

    private Item[] getRecipe() {
        if (recipe.is("Сила 2")) return RECIPE_STRENGTH_2;
        if (recipe.is("Скорость 2")) return RECIPE_SPEED_2;
        return RECIPE_INVISIBILITY;
    }

    @Override
    public boolean onEnable() {
        stage = Stage.SCAN_BLOCKS;
        stands.clear(); allChests.clear();
        bottleChest = ingredientChest = potionChest = null;
        standIdx = 0; ingStep = 0; analyzeIdx = 0; analyzed = false;
        return super.onEnable();
    }

    @Override
    public boolean onDisable() {
        if (mc.player != null && mc.currentScreen != null) mc.player.closeScreen();
        return super.onDisable();
    }

    @Subscribe
    public void onUpdate(EventUpdate e) {
        if (mc.player == null || mc.world == null) return;
        if (!timer.isReached(150)) return;
        timer.reset();

        switch (stage) {
            case SCAN_BLOCKS -> scanBlocks();
            case ANALYZE_OPEN -> analyzeOpen();
            case ANALYZE_CHECK -> analyzeCheck();
            case TAKE_BOTTLES_OPEN -> chestOpen(bottleChest, Stage.TAKE_BOTTLES);
            case TAKE_BOTTLES -> takeBottles();
            case TAKE_ING_OPEN -> chestOpen(ingredientChest, Stage.TAKE_ING);
            case TAKE_ING -> takeIngredients();
            case FILL_OPEN -> fillOpen();
            case FILL_BOTTLES -> fillBottles();
            case FILL_ING -> fillIngredient();
            case WAIT_BREW -> waitBrew();
            case COLLECT_OPEN -> collectOpen();
            case COLLECT -> collect();
            case STORE_OPEN -> chestOpen(potionChest, Stage.STORE);
            case STORE -> store();
        }
    }

    private void scanBlocks() {
        if (analyzed) { startBrewing(); return; }
        stands.clear(); allChests.clear();
        BlockPos p = mc.player.getPosition();
        for (BlockPos pos : BlockPos.getAllInBoxMutable(p.add(-5,-3,-5), p.add(5,3,5))) {
            TileEntity te = mc.world.getTileEntity(pos);
            if (te instanceof ChestTileEntity || te instanceof net.minecraft.tileentity.TrappedChestTileEntity) {
                BlockPos imm = pos.toImmutable();
                boolean duplicate = false;
                for (BlockPos existing : allChests) {
                    if (existing.getX() == imm.getX() && existing.getY() == imm.getY()
                            && Math.abs(existing.getZ() - imm.getZ()) <= 1) { duplicate = true; break; }
                    if (existing.getZ() == imm.getZ() && existing.getY() == imm.getY()
                            && Math.abs(existing.getX() - imm.getX()) <= 1) { duplicate = true; break; }
                }
                if (!duplicate) allChests.add(imm);
            }
            else if (te instanceof BrewingStandTileEntity)
                stands.add(pos.toImmutable());
        }
        if (stands.isEmpty()) { print("Зельеварки не найдены!"); setenabled(false, false); return; }
        stands.sort(Comparator.comparingDouble(pos -> mc.player.getDistanceSq(pos.getX(), pos.getY(), pos.getZ())));
        if (!useChests.get() || allChests.isEmpty()) { analyzed = true; startBrewing(); return; }
        analyzeIdx = 0;
        stage = Stage.ANALYZE_OPEN;
    }

    private void analyzeOpen() {
        if (analyzeIdx >= allChests.size()) {
            analyzed = true;
            mc.player.closeScreen();
            print("Бутылки:" + (bottleChest != null ? "OK" : "нет")
                    + " Ингр:" + (ingredientChest != null ? "OK" : "нет")
                    + " Зелья:" + (potionChest != null ? "OK" : "нет"));
            startBrewing();
            return;
        }
        if (isChestOpen()) { stage = Stage.ANALYZE_CHECK; return; }
        if (openTimer.isReached(700)) { openBlock(allChests.get(analyzeIdx)); openTimer.reset(); }
    }

    private void analyzeCheck() {
        if (!isChestOpen()) { stage = Stage.ANALYZE_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean hasWaterBottles = false;
        boolean hasIngredients = false;
        boolean hasPotions = false;
        boolean isEmpty = true;
        Item[] rec = getRecipe();
        for (int i = 0; i < slots; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (s.isEmpty()) continue;
            isEmpty = false;
            if (s.getItem() == Items.POTION) {
                if (PotionUtils.getPotionFromItem(s) == Potions.WATER) hasWaterBottles = true;
                else hasPotions = true;
            }
            for (Item ing : rec) {
                if (s.getItem() == ing) { hasIngredients = true; break; }
            }
        }
        BlockPos pos = allChests.get(analyzeIdx);
        if (hasWaterBottles && bottleChest == null) bottleChest = pos;
        else if (hasIngredients && ingredientChest == null) ingredientChest = pos;
        else if ((hasPotions || isEmpty) && potionChest == null) potionChest = pos;
        mc.player.closeScreen();
        analyzeIdx++;
        stage = Stage.ANALYZE_OPEN;
    }

    private void startBrewing() {
        standIdx = 0; ingStep = 0;
        if (useChests.get() && bottleChest != null && needBottles()) stage = Stage.TAKE_BOTTLES_OPEN;
        else if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
        else stage = Stage.FILL_OPEN;
    }

    private void chestOpen(BlockPos pos, Stage next) {
        if (pos == null) { stage = Stage.FILL_OPEN; return; }
        if (isChestOpen()) { stage = next; return; }
        if (openTimer.isReached(700)) { openBlock(pos); openTimer.reset(); }
    }

    private void takeBottles() {
        if (!isChestOpen()) { stage = Stage.TAKE_BOTTLES_OPEN; return; }
        int emptySlots = 0;
        for (int i = 0; i < 36; i++) if (mc.player.inventory.getStackInSlot(i).isEmpty()) emptySlots++;
        if (emptySlots <= 9) {
            mc.player.closeScreen();
            if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
            else stage = Stage.FILL_OPEN;
            return;
        }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean took = false;
        for (int i = 0; i < slots; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (!s.isEmpty() && s.getItem() == Items.POTION
                    && PotionUtils.getPotionFromItem(s) == Potions.WATER) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                took = true; break;
            }
        }
        if (!took || !needBottles()) {
            mc.player.closeScreen();
            if (useChests.get() && ingredientChest != null && needIngredients()) stage = Stage.TAKE_ING_OPEN;
            else stage = Stage.FILL_OPEN;
        }
    }

    private void takeIngredients() {
        if (!isChestOpen()) { stage = Stage.TAKE_ING_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int slots = c.getNumRows() * 9;
        boolean took = false;
        Item[] rec = getRecipe();
        for (Item ing : rec) {
            if (hasItem(ing)) continue;
            for (int i = 0; i < slots; i++) {
                ItemStack s = c.inventorySlots.get(i).getStack();
                if (!s.isEmpty() && s.getItem() == ing) {
                    mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                    took = true; break;
                }
            }
            if (took) break;
        }
        if (!took) { mc.player.closeScreen(); stage = Stage.FILL_OPEN; }
    }

    private void store() {
        if (!isChestOpen()) { stage = Stage.STORE_OPEN; return; }
        ChestContainer c = (ChestContainer) mc.player.openContainer;
        int chestSlots = c.getNumRows() * 9;
        int total = c.inventorySlots.size();
        boolean stored = false;
        for (int i = chestSlots; i < total; i++) {
            ItemStack s = c.inventorySlots.get(i).getStack();
            if (!s.isEmpty() && s.getItem() == Items.POTION
                    && PotionUtils.getPotionFromItem(s) != Potions.WATER) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                stored = true; break;
            }
        }
        if (!stored) { mc.player.closeScreen(); startBrewing(); }
    }

    private void fillOpen() {
        if (standIdx >= stands.size()) { standIdx = 0; stage = Stage.WAIT_BREW; return; }
        if (isBrewingOpen()) { stage = Stage.FILL_BOTTLES; return; }
        if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
    }

    private void fillBottles() {
        if (!isBrewingOpen()) { stage = Stage.FILL_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        for (int i = 0; i <= 2; i++) {
            if (c.inventorySlots.get(i).getStack().isEmpty()) {
                int cs = findBrewSlot(Items.POTION, true);
                if (cs != -1) {
                    mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                    mc.playerController.windowClick(c.windowId, i, 1, ClickType.PICKUP, mc.player);
                    mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                    return;
                } else {
                    if (useChests.get() && bottleChest != null) {
                        mc.player.closeScreen();
                        stage = Stage.TAKE_BOTTLES_OPEN;
                        return;
                    }
                }
            }
        }
        stage = Stage.FILL_ING;
    }

    private void fillIngredient() {
        if (!isBrewingOpen()) { stage = Stage.FILL_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        Item ing = getRecipe()[ingStep];
        ItemStack slot3 = c.inventorySlots.get(3).getStack();
        if (!slot3.isEmpty() && slot3.getItem() != ing) {
            mc.playerController.windowClick(c.windowId, 3, 0, ClickType.QUICK_MOVE, mc.player);
            return;
        }
        if (slot3.isEmpty()) {
            int cs = findBrewSlot(ing, false);
            if (cs != -1) {
                mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
                mc.playerController.windowClick(c.windowId, 3, 1, ClickType.PICKUP, mc.player);
                mc.playerController.windowClick(c.windowId, cs, 0, ClickType.PICKUP, mc.player);
            } else {
                if (useChests.get() && ingredientChest != null) {
                    mc.player.closeScreen();
                    stage = Stage.TAKE_ING_OPEN;
                    return;
                }
            }
        }
        mc.player.closeScreen(); standIdx++; stage = Stage.FILL_OPEN;
    }

    private void waitBrew() {
        if (!isBrewingOpen()) {
            if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
            return;
        }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        if (c.inventorySlots.get(3).getStack().isEmpty()) {
            mc.player.closeScreen();
            standIdx++;
            if (standIdx >= stands.size()) {
                standIdx = 0;
                ingStep++;
                if (ingStep >= getRecipe().length) { standIdx = 0; stage = Stage.COLLECT_OPEN; }
                else { standIdx = 0; stage = Stage.FILL_OPEN; }
            }
        }
    }

    private void collectOpen() {
        if (standIdx >= stands.size()) {
            stage = (useChests.get() && potionChest != null) ? Stage.STORE_OPEN : Stage.FILL_OPEN;
            standIdx = 0; ingStep = 0; return;
        }
        if (isBrewingOpen()) { stage = Stage.COLLECT; return; }
        if (openTimer.isReached(700)) { openBlock(stands.get(standIdx)); openTimer.reset(); }
    }

    private void collect() {
        if (!isBrewingOpen()) { stage = Stage.COLLECT_OPEN; return; }
        BrewingStandContainer c = (BrewingStandContainer) mc.player.openContainer;
        boolean found = false;
        for (int i = 0; i <= 2; i++) {
            if (!c.inventorySlots.get(i).getStack().isEmpty()) {
                mc.playerController.windowClick(c.windowId, i, 0, ClickType.QUICK_MOVE, mc.player);
                found = true; break;
            }
        }
        if (!found) { mc.player.closeScreen(); standIdx++; }
    }

    private void openBlock(BlockPos pos) {
        if (pos == null) return;
        Vector3d target = Vector3d.copyCentered(pos);
        Vector3d eyes = mc.player.getEyePosition(1.0f);
        Vector3d diff = target.subtract(eyes).normalize();
        float yaw = (float) Math.toDegrees(Math.atan2(-diff.x, diff.z));
        float pitch = (float) -Math.toDegrees(Math.atan2(diff.y, Math.hypot(diff.x, diff.z)));
        RotationComponent.update(new Rotation(yaw, pitch), 360.0f, 360.0f, 0, 1);
        BlockRayTraceResult rtr = new BlockRayTraceResult(
                Vector3d.copyCentered(pos), Direction.UP, pos, false);
        mc.playerController.processRightClickBlock(mc.player, mc.world, Hand.MAIN_HAND, rtr);
    }

    private boolean isBrewingOpen() {
        return mc.currentScreen instanceof BrewingStandScreen && mc.player.openContainer instanceof BrewingStandContainer;
    }

    private boolean isChestOpen() {
        return mc.currentScreen instanceof ChestScreen && mc.player.openContainer instanceof ChestContainer;
    }

    private boolean needBottles() {
        int c = 0;
        int emptySlots = 0;
        for (int i = 0; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) == Potions.WATER) c += s.getCount();
            if (s.isEmpty()) emptySlots++;
        }
        return c < stands.size() * 3 && emptySlots > 9;
    }

    private boolean needIngredients() {
        for (Item i : getRecipe()) if (!hasItem(i)) return true;
        return false;
    }

    private boolean hasItem(Item item) {
        for (int i = 0; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (!s.isEmpty() && s.getItem() == item) return true;
        }
        return false;
    }

    private int findBrewSlot(Item item, boolean water) {
        for (int i = 9; i < 36; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.isEmpty() || s.getItem() != item) continue;
            if (water && s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) != Potions.WATER) continue;
            return (i - 9) + 5;
        }
        for (int i = 0; i < 9; i++) {
            ItemStack s = mc.player.inventory.getStackInSlot(i);
            if (s.isEmpty() || s.getItem() != item) continue;
            if (water && s.getItem() == Items.POTION && PotionUtils.getPotionFromItem(s) != Potions.WATER) continue;
            return i + 32;
        }
        return -1;
    }
}
/up
 
Назад
Сверху Снизу