• Я зарабатываю 100 000 RUB / месяц на этом сайте!

    А знаешь как? Я всего-лишь публикую (создаю темы), а админ мне платит. Трачу деньги на мороженое, робуксы и сервера в Minecraft. А ещё на паль из Китая. 

    Хочешь так же? Пиши и узнавай условия: https://t.me/alex_redact
    Реклама: https://t.me/yougame_official

Визуальная часть Spirt hack gui skid

даже если лого монолита, это какая то смесь миднайта, монолита и спиртхака.

но от спиртхака тут ничего нет
это изначалььно гуи миднайто было, потом я хотел сделать монолит, но сделай спирт хак xD
 
хотите могу сурсы ликнуть
ss
Посмотреть вложение 310599

code
code:
Expand Collapse Copy
package club.monolith.chuppachups.other.render.midnight;

import club.monolith.chuppachups.main.MainClass;
import club.monolith.chuppachups.main.functions.api.Category;
import club.monolith.chuppachups.main.functions.api.Function;
import club.monolith.chuppachups.other.render.midnight.component.impl.*;
import club.monolith.chuppachups.other.render.midnight.component.impl.Component;
import club.monolith.chuppachups.other.render.styles.Style;
import club.monolith.chuppachups.other.utility.client.ClientUtil;
import club.monolith.chuppachups.other.utility.client.Vec2i;
import club.monolith.chuppachups.other.utility.font.Fonts;
import club.monolith.chuppachups.other.utility.math.MathUtil;
import club.monolith.chuppachups.other.utility.render.DisplayUtils;
import club.monolith.chuppachups.other.utility.render.Scissor;
import club.monolith.chuppachups.other.utility.render.Stencil;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.util.text.StringTextComponent;
import org.lwjgl.glfw.GLFW;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import static club.monolith.chuppachups.other.render.midnight.component.impl.ModuleComponent.binding;
import static club.monolith.chuppachups.other.utility.client.IMinecraft.mc;

public class ClickGui extends Screen {
    private final float gameX = 40;
    private final float gameY = 105;
    private final float gameWidth =  36.8f;;
    private final float gameHeight =  23.8f;
    private List<Vec2i> snake = new ArrayList<>();
    private Vec2i food;
    private int dirX = 1;
    private int dirY = 0;
    private long lastUpdateTime = 0;
    private final long updateInterval = 200; // обновлять игру каждые 200 мс

    private boolean homeMode = true;

    public ClickGui() {
        super(new StringTextComponent("GUI"));
        for (Function function : MainClass.getInstance().getFunctionRegistry().getList()) {
            objects.add(new ModuleComponent(function));
        }
        for (Style style : MainClass.getInstance().getStyleManager().getStyleList()) {
            this.theme.add(new ThemeComponent(style));
        }
        cfg.clear();
        for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
        }
    }
    private void initSnakeGame() {
        snake.clear();
        snake.add(new Vec2i(20, 15));
        snake.add(new Vec2i(19, 15));
        snake.add(new Vec2i(18, 15));
        dirX = 1;
        dirY = 0;
        placeFood();
    }
    private void updateSnake() {
        Vec2i head = snake.get(0);
        Vec2i newHead = new Vec2i(head.getX() + dirX, head.getY() + dirY);


        if (newHead.getX() < 0 || newHead.getX() >= (int)gameWidth || newHead.getY() < 0 || newHead.getY() >= (int)gameHeight) {
            initSnakeGame();
            return;
        }


        if (snake.contains(newHead)) {
            initSnakeGame();
            return;
        }

        snake.add(0, newHead);

        if (newHead.equals(food)) {
            placeFood();
        } else {
            snake.remove(snake.size() - 1);
        }
    }

    private void placeFood() {
        Random rand = new Random();
        int x, y;
        do {
            x = rand.nextInt((int) gameWidth);
            y = rand.nextInt((int) gameHeight);
        } while (snake.contains(new Vec2i(x, y)));
        food = new Vec2i(x, y);
    }
    double xPanel, yPanel;
    Category current = Category.COMBAT;

    float animation;

    public ArrayList<ModuleComponent> objects = new ArrayList<>();

    private CopyOnWriteArrayList<ConfigComponent> config = new CopyOnWriteArrayList<>();

    public List<ThemeComponent> theme = new ArrayList<>();

    public float scroll = 0;
    public float animateScroll = 0;

    @Override
    public void onClose() {
        super.onClose();
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        scroll += delta * 15;
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

    @Override
    public void closeScreen() {
        if (typing || !searchText.isEmpty()) {
            typing = false;
            searchText = "";
        }
        if (configTyping || !configName.isEmpty()) {
            configTyping = false;
            configName = "";
        }
    }
    @Override
    public boolean isPauseScreen() {
        return false;
    }

    boolean searchOpened;
    float seacrh;

    private String searchText = "";
    public static boolean typing;

    @Override
    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
        super.render(matrixStack, mouseX, mouseY, partialTicks);
        this.minecraft.keyboardListener.enableRepeatEvents(true);
        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        xPanel = x;
        yPanel = y;
        animation = MathUtil.lerp(animation, 0, 5);

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        int finalMouseX = mouseX;
        int finalMouseY = mouseY;

        mc.gameRenderer.setupOverlayRendering(2);
        renderBackground(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderCategories(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY, 12.0f);
        renderComponents(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderColorPicker(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderSearchBar(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        mc.gameRenderer.setupOverlayRendering();


    }

    void renderColorPicker(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        if (ColorComponent.opened != null) {
            ColorComponent.opened.draw(matrixStack, mouseX, mouseY);
        }
        if (ThemeComponent.selected != null) {
            ThemeComponent.selected.draw(matrixStack, mouseX, mouseY);
        }
    }

    void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        int gameX = (int) (x + 40);
        int gameY = (int) (y + 105);
        int tileSize = 10;
        float gameWidth =  36.8f;
        float gameHeight =  23.8f;

        DisplayUtils.drawShadow(x, y - 17, width - 42, height + 35, 20, new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
           DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());


        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        if (current == Category.MAIN) {
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(22, 24, 28).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21).getRGB());
            DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());
            // Кнопка Home
            DisplayUtils.drawRoundedRect(
                    buttonsX + 2,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Home",
                    buttonsX + buttonWidth / 2f + 2,
                    buttonsY + 6,
                    -1
            );

            // Кнопка Minigames
            DisplayUtils.drawRoundedRect(
                    buttonsX + 76,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    !homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Minigames",
                    buttonsX + 111,
                    buttonsY + 6,
                    -1
            );

            if (homeMode) {
                // Отрисовка юзера и подписки (Home)
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );
            } else {
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );


                // Обновляем змейку по времени
                long now = System.currentTimeMillis();
                if (now - lastUpdateTime > updateInterval) {
                    updateSnake();
                    lastUpdateTime = now;
                }

                // Фон игрового поля
                DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());

                // Рисуем еду (красный квадрат)
                int foodX = gameX + food.getX() * tileSize;
                int foodY = gameY + food.getY() * tileSize;
                DisplayUtils.drawRoundedRect(foodX, foodY, tileSize, tileSize, 2f, new Color(255, 0, 0).getRGB());

                // Рисуем тело змейки зелёным
                for (int i = 1; i < snake.size(); i++) {
                    Vec2i part = snake.get(i);
                    int partX = gameX + part.getX() * tileSize;
                    int partY = gameY + part.getY() * tileSize;
                    DisplayUtils.drawRoundedRect(partX, partY, tileSize, tileSize, 2f, new Color(0, 200, 0).getRGB());
                }

                // Голова — ярко-зеленая
                Vec2i head = snake.get(0);
                int headX = gameX + head.getX() * tileSize;
                int headY = gameY + head.getY() * tileSize;
                DisplayUtils.drawRoundedRect(headX, headY, tileSize, tileSize, 2f, new Color(0, 255, 0).getRGB());
            }
        }
        DisplayUtils.drawImage(
                new ResourceLocation("expensive/images/ui/ava.png"),
                572 ,
                81,
                20,
                20,
                new Color(255, 255, 255).getRGB()
        );
        Fonts.quicksand_medium[15].drawCenteredString(
                matrixStack,
                "ChuppaChups",
                x + (width + 290) / 2f,
                y -3,
                -1
        );
    }









    void renderCategories(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel,
                          int mouseX, int mouseY, float iconOffsetY) {
        float heightCategory = 38 / 2f;
        float mainXOffset = 4f;

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (t == current) {
                // Прямоугольник для активной категории
                DisplayUtils.drawRoundedRect(
                        x + 0.8f, // отступ слева
                        yOffset + 2,
                        leftPanel - 97, // ширина, с отступами
                        heightCategory + 3,
                        new Vector4f(0, 0, 0, 0), // закругления
                        new Color(74, 166, 218).getRGB() // цвет фона
                );
            }
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/logo.png"),
                    248 ,
                    84,
                    60,
                    30,
                    new Color(255, 255, 255).getRGB()
            );


            // Иконка категории
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/" + t.name().toLowerCase() + ".png"),
                    (float) (x + 16 + t.anim),
                    (float) (yOffset + 5.5f),
                    10f,
                    10f,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );

            float textXOffset = (float) (x + 8 + t.anim + (t == Category.MAIN ? mainXOffset : 0f));

            // Название категории
            Fonts.mrubik[13].drawString(
                    matrixStack,
                    t.name(),
                    textXOffset,
                    yOffset + 20,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );
        }
    }




    void renderComponents(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        Scissor.push();
        Scissor.setFromComponentCoordinates(x, y + 64 / 2f, width, height - 64 / 2f);
        drawComponents(matrixStack, mouseX, mouseY);
        Scissor.unset();
        Scissor.pop();
        DisplayUtils.drawRoundedRect(x + leftPanel, y + 64 / 2f, width - leftPanel, height - 64 / 2f, new Vector4f(0, 0, 6, 6), new Color(22, 24, 28, ((int) (255 * animation))).getRGB());
    }

    void renderSearchBar(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (220 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        DisplayUtils.drawRoundedRect(barX, y - 10, barWidth, barHeight, 0, new Color(17, 18, 21, 255).brighter().getRGB());

        matrixStack.push();
        matrixStack.translate(barX, y + 14, 0);
        matrixStack.scale(1.0f, 1.0f, 1.0f);
        matrixStack.translate(-barX, -y - 14, 0);

        float xOffset = 0;
        float fontTextWidth = Fonts.gilroy[16].getWidth(searchText);

        if (fontTextWidth > barWidth) {
            xOffset = fontTextWidth - barWidth;
        }


        Fonts.gilroy[16].drawString(
                matrixStack,
                searchText + (typing ? (System.currentTimeMillis() % 1000 > 500 ? "|" : "") : ""),
                barX + 25    - xOffset,
                y - 3,
                -1
        );

        Stencil.uninitStencilBuffer();
        matrixStack.pop();

        // Иконки справа
        Fonts.icons[16].drawString(matrixStack, "B", x + width - (1600 / 2f) / 2f, y + (-4 / 2f) / 2f - 1, -1);
    }








    public CopyOnWriteArrayList<ConfigComponent> cfg = new CopyOnWriteArrayList<>();

    private String configName = "";
    private boolean configTyping;
    public static String confign;

    void drawComponents(MatrixStack stack, int mouseX, int mouseY) {

        List<ModuleComponent> moduleComponentList = objects.stream()
                .filter(moduleObject -> {
                    if (!searchText.isEmpty()) {
                        return true;
                    } else {
                        return moduleObject.function.getCategory() == current;
                    }
                }).toList();

        List<ModuleComponent> first = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 == 0)
                .toList();

        List<ModuleComponent> second = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 != 0)
                .toList();

        for (ConfigComponent c : config) {
            if (c.config.getFile().getName().equalsIgnoreCase(confign)) {
                selectedCfg = c;
            }
        }

        float scale = 2f;
        animateScroll = MathUtil.lerp(animateScroll, scroll, 10);
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);

        if (current == Category.MAIN) {
            if (homeMode) {
                DisplayUtils.drawRoundedRect(x + leftPanel - 56, y + 64 / 2F + 120,
                        355, height - 64 / 2F - 80, 0, new Color(12, 17, 21, 160).getRGB());
            }

            float fontTextWidth = Fonts.gilroy[16].getWidth(configName);
            float xOffset = 0;
            float availableWidth = width - leftPanel - 35 - 35 * 2;

            if (fontTextWidth > availableWidth) {
                xOffset = fontTextWidth - (availableWidth - 8);
            }

            Stencil.uninitStencilBuffer();
            config = cfg;

            float scissorX = x + leftPanel - 100;
            float scissorY = y + 64 / 2F + 120;
            float scissorWidth = 500;
            float scissorHeight = height - 64 / 2F - 80;

            Scissor.push();
            Scissor.setFromComponentCoordinates(scissorX, scissorY, scissorWidth, scissorHeight);

            float offset = scissorY + 8 + animateScroll;

            if (homeMode) {
                for (ConfigComponent component : config) {
                    component.parent = this;
                    component.selected = component == selectedCfg;
                    component.setPosition((float) (xPanel + 45), offset - 5, 352, 20);
                    component.drawComponent(stack, mouseX, mouseY);
                    offset += component.height + 2;
                }
            }

            Scissor.unset();
            Scissor.pop();

            scroll = Math.min(scroll, 0);
        }

        float offset = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size1 = 0;
        for (ModuleComponent component : first) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (35 + 12)), offset, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset + component.height -8;
                float descX = component.x + 5;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset += Fonts.gilroy[12].getFontHeight() + 2;
                size1 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset += settingComp.height;
                        size1 += settingComp.height;
                    }
                }
            }

            offset += component.height + 8;
            size1 += component.height + 8;
        }

        float offset2 = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size2 = 0;
        for (ModuleComponent component : second) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (45 + 12) + 314 / 2f + 10), offset2, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset2 + component.height - 9;
                float descX = component.x + 5   ;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset2 += Fonts.gilroy[12].getFontHeight() + 2;
                size2 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset2 += settingComp.height;
                        size2 += settingComp.height;
                    }
                }
            }

            offset2 += component.height + 8;
            size2 += component.height + 8;
        }

        float max = Math.max(size1, size2);
        if (max < height) {
            scroll = 0;
        } else {
            scroll = MathHelper.clamp(scroll, -(max - height + 50), 0);
        }
    }


    @Override
    public void init(Minecraft minecraft, int width, int height) {
        super.init(minecraft, width, height);
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        typing = false;
        configTyping = false;
        configOpened = false;
        configName = "";

        // ⬇️ Загрузка конфигов при входе в меню
        cfg.clear();
        for (String configName : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(configName)));
        }
        config = cfg;
    }


    @Override
    public boolean mouseReleased(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.mouseReleased((int) mouseX, (int) mouseY, button);
        }
//        for (ThemeComponent component : theme) {
//            if (current != Category.Theme) continue;
//            component.parent = this;
//            component.mouseReleased((int) mouseX, (int) mouseY, button);
//        }
        if (ColorComponent.opened != null) {
            ColorComponent.opened.unclick((int) mouseX, (int) mouseY);
        }
        return super.mouseReleased(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
            mc.displayGuiScreen(null);
            this.minecraft.keyboardListener.enableRepeatEvents(false);
        }

        boolean ctrlDown = Screen.hasControlDown();

        // Управление змейкой (WASD), только если в Minigames (категория MAIN и homeMode == false)
        if (current == Category.MAIN && !homeMode) {
            switch (keyCode) {
                case GLFW.GLFW_KEY_W:
                    if (dirY != 1) { // не даём змейке развернуться на 180°
                        dirX = 0;
                        dirY = -1;
                    }
                    return true;
                case GLFW.GLFW_KEY_S:
                    if (dirY != -1) {
                        dirX = 0;
                        dirY = 1;
                    }
                    return true;
                case GLFW.GLFW_KEY_A:
                    if (dirX != 1) {
                        dirX = -1;
                        dirY = 0;
                    }
                    return true;
                case GLFW.GLFW_KEY_D:
                    if (dirX != -1) {
                        dirX = 1;
                        dirY = 0;
                    }
                    return true;
            }
        }

        if (typing) {
            if (!(current == Category.MAIN)) {
                if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                    String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                    searchText += pasteText;
                }
                if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                    if (!searchText.isEmpty()) {
                        searchText = searchText.substring(0, searchText.length() - 1);
                    }
                }
                if (keyCode == GLFW.GLFW_KEY_DELETE) {
                    searchText = "";
                }
                if (keyCode == GLFW.GLFW_KEY_ENTER) {
                    typing = false;
                }
            }
        }

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.keyTyped(keyCode, scanCode, modifiers);
        }

        if (binding != null) {
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                binding.function.setBind(0);
            } else {
                binding.function.setBind(keyCode);
            }
            binding = null;
        }

        if (configTyping) {
            if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                configName += pasteText;
            }
            if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                if (!configName.isEmpty()) {
                    configName = configName.substring(0, configName.length() - 1);
                }
            }
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                configName = "";
            }
            if (keyCode == GLFW.GLFW_KEY_ENTER) {
                configTyping = false;
            }
        }

        return super.keyPressed(keyCode, scanCode, modifiers);
    }


    @Override
    public boolean charTyped(char codePoint, int modifiers) {
        if (typing)
            searchText += codePoint;
        if (configTyping)
            configName += codePoint;

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.charTyped(codePoint, modifiers);
        }
        return super.charTyped(codePoint, modifiers);
    }



    private boolean configOpened;

    private ConfigComponent selectedCfg;

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);

        mouseX = fixed.getX();
        mouseY = fixed.getY();

        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 199 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        float heightCategory = 45 / 2f;
        float iconOffsetY = 10.0f;
        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (64 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        float barY = y - 15;



        if (ColorComponent.opened != null) {
            if (!ColorComponent.opened.click((int) mouseX, (int) mouseY))
                return super.mouseClicked(mouseX, mouseY, button);
        }

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x, yOffset, 44, heightCategory)) {
                if (current == t) continue;

                current = t;
                animation = 1;
                scroll = 0;
                searchText = "";
                ColorComponent.opened = null;
                ThemeComponent.selected = null;
                typing = false;
            }
        }

        // *** Конфиги кликабельны только если homeMode == true и категория MAIN ***
        if (current == Category.MAIN && homeMode) {
            for (ConfigComponent component : config) {
                component.parent = this;
                if (MathUtil.isInRegion((float) mouseX, (float) mouseY, component.x + component.width - 35 - 2, component.y + 2, 35 - 2, 32 / 2f))
                    selectedCfg = component;
                component.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        // Кнопки сохранения/обновления конфигов обрабатываем в любом режиме
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            MainClass.getInstance().getConfigStorage().saveConfiguration(configName);
            configName = "";
            configTyping = false;
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 35 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }

        // *** Модули кликабельны только если homeMode == true ***
        if (homeMode && MathUtil.isInRegion((float) mouseX, (float) mouseY, x, y + 64 / 2f, width, height - 64 / 2f)) {
            for (ModuleComponent m : objects) {
                if (searchText.isEmpty()) {
                    if (m.function.getCategory() != current) continue;
                } else {
                    if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
                }
                m.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - ((64 / 2f) * 2) / 2f - 1, y + (64 / 2f) / 2f - 5, 10, 10)) {
            try {
                Runtime.getRuntime().exec("explorer " + MainClass.getInstance().getConfigStorage().CONFIG_DIR);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + leftPanel + 6 + ((width - leftPanel - 12 - (64 / 2f) / 2f) / 2f) * (1 - seacrh), y + 7, (width - leftPanel - 12 - (64 / 2f) / 2f) * (seacrh), 64 / 2f - 14)) {
            typing = !typing;
        } else {
            typing = false;
        }

        // Кнопки переключения Home / Minigames — без изменений
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = true;
            return true;
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX + buttonWidth + spacing, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = false;
            initSnakeGame(); // старт игры при переключении
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

}

есть chat gpt код
не не нужно
 
1751824696205.png

С этой хуйни чуть со стула не выпал, кроме того что чел "пытался скиднуть гуи спиртхака", чел сделал смесь из миднайта с чем нибудь другим и налепив блять лого монолита ($INVITEZADOHUYA$), так ещё он заюзал это на базе EXPENSIVE ANCIENT (ну хотя бы не 3.1 или 2.0)
 
С этой хуйни чуть со стула не выпал, кроме того что чел "пытался скиднуть гуи спиртхака", чел сделал смесь из миднайта с чем нибудь другим и налепив блять лого монолита ($INVITEZADOHUYA$), так ещё он заюзал это на базе EXPENSIVE ANCIENT (ну хотя бы не 3.1 или 2.0)
у меня своя база, пытаюсь? ты видел рендер утил и шейдер утил в экспе? это буквально чат жпт клиент, делалось на примере спирта а не в точь точь, если я скидил то получилось на много красивее
 
хотите могу сурсы ликнуть
ss
Посмотреть вложение 310599

code
code:
Expand Collapse Copy
package club.monolith.chuppachups.other.render.midnight;

import club.monolith.chuppachups.main.MainClass;
import club.monolith.chuppachups.main.functions.api.Category;
import club.monolith.chuppachups.main.functions.api.Function;
import club.monolith.chuppachups.other.render.midnight.component.impl.*;
import club.monolith.chuppachups.other.render.midnight.component.impl.Component;
import club.monolith.chuppachups.other.render.styles.Style;
import club.monolith.chuppachups.other.utility.client.ClientUtil;
import club.monolith.chuppachups.other.utility.client.Vec2i;
import club.monolith.chuppachups.other.utility.font.Fonts;
import club.monolith.chuppachups.other.utility.math.MathUtil;
import club.monolith.chuppachups.other.utility.render.DisplayUtils;
import club.monolith.chuppachups.other.utility.render.Scissor;
import club.monolith.chuppachups.other.utility.render.Stencil;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.util.text.StringTextComponent;
import org.lwjgl.glfw.GLFW;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import static club.monolith.chuppachups.other.render.midnight.component.impl.ModuleComponent.binding;
import static club.monolith.chuppachups.other.utility.client.IMinecraft.mc;

public class ClickGui extends Screen {
    private final float gameX = 40;
    private final float gameY = 105;
    private final float gameWidth =  36.8f;;
    private final float gameHeight =  23.8f;
    private List<Vec2i> snake = new ArrayList<>();
    private Vec2i food;
    private int dirX = 1;
    private int dirY = 0;
    private long lastUpdateTime = 0;
    private final long updateInterval = 200; // обновлять игру каждые 200 мс

    private boolean homeMode = true;

    public ClickGui() {
        super(new StringTextComponent("GUI"));
        for (Function function : MainClass.getInstance().getFunctionRegistry().getList()) {
            objects.add(new ModuleComponent(function));
        }
        for (Style style : MainClass.getInstance().getStyleManager().getStyleList()) {
            this.theme.add(new ThemeComponent(style));
        }
        cfg.clear();
        for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
        }
    }
    private void initSnakeGame() {
        snake.clear();
        snake.add(new Vec2i(20, 15));
        snake.add(new Vec2i(19, 15));
        snake.add(new Vec2i(18, 15));
        dirX = 1;
        dirY = 0;
        placeFood();
    }
    private void updateSnake() {
        Vec2i head = snake.get(0);
        Vec2i newHead = new Vec2i(head.getX() + dirX, head.getY() + dirY);


        if (newHead.getX() < 0 || newHead.getX() >= (int)gameWidth || newHead.getY() < 0 || newHead.getY() >= (int)gameHeight) {
            initSnakeGame();
            return;
        }


        if (snake.contains(newHead)) {
            initSnakeGame();
            return;
        }

        snake.add(0, newHead);

        if (newHead.equals(food)) {
            placeFood();
        } else {
            snake.remove(snake.size() - 1);
        }
    }

    private void placeFood() {
        Random rand = new Random();
        int x, y;
        do {
            x = rand.nextInt((int) gameWidth);
            y = rand.nextInt((int) gameHeight);
        } while (snake.contains(new Vec2i(x, y)));
        food = new Vec2i(x, y);
    }
    double xPanel, yPanel;
    Category current = Category.COMBAT;

    float animation;

    public ArrayList<ModuleComponent> objects = new ArrayList<>();

    private CopyOnWriteArrayList<ConfigComponent> config = new CopyOnWriteArrayList<>();

    public List<ThemeComponent> theme = new ArrayList<>();

    public float scroll = 0;
    public float animateScroll = 0;

    @Override
    public void onClose() {
        super.onClose();
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        scroll += delta * 15;
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

    @Override
    public void closeScreen() {
        if (typing || !searchText.isEmpty()) {
            typing = false;
            searchText = "";
        }
        if (configTyping || !configName.isEmpty()) {
            configTyping = false;
            configName = "";
        }
    }
    @Override
    public boolean isPauseScreen() {
        return false;
    }

    boolean searchOpened;
    float seacrh;

    private String searchText = "";
    public static boolean typing;

    @Override
    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
        super.render(matrixStack, mouseX, mouseY, partialTicks);
        this.minecraft.keyboardListener.enableRepeatEvents(true);
        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        xPanel = x;
        yPanel = y;
        animation = MathUtil.lerp(animation, 0, 5);

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        int finalMouseX = mouseX;
        int finalMouseY = mouseY;

        mc.gameRenderer.setupOverlayRendering(2);
        renderBackground(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderCategories(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY, 12.0f);
        renderComponents(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderColorPicker(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderSearchBar(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        mc.gameRenderer.setupOverlayRendering();


    }

    void renderColorPicker(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        if (ColorComponent.opened != null) {
            ColorComponent.opened.draw(matrixStack, mouseX, mouseY);
        }
        if (ThemeComponent.selected != null) {
            ThemeComponent.selected.draw(matrixStack, mouseX, mouseY);
        }
    }

    void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        int gameX = (int) (x + 40);
        int gameY = (int) (y + 105);
        int tileSize = 10;
        float gameWidth =  36.8f;
        float gameHeight =  23.8f;

        DisplayUtils.drawShadow(x, y - 17, width - 42, height + 35, 20, new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
           DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());


        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        if (current == Category.MAIN) {
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(22, 24, 28).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21).getRGB());
            DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());
            // Кнопка Home
            DisplayUtils.drawRoundedRect(
                    buttonsX + 2,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Home",
                    buttonsX + buttonWidth / 2f + 2,
                    buttonsY + 6,
                    -1
            );

            // Кнопка Minigames
            DisplayUtils.drawRoundedRect(
                    buttonsX + 76,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    !homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Minigames",
                    buttonsX + 111,
                    buttonsY + 6,
                    -1
            );

            if (homeMode) {
                // Отрисовка юзера и подписки (Home)
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );
            } else {
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );


                // Обновляем змейку по времени
                long now = System.currentTimeMillis();
                if (now - lastUpdateTime > updateInterval) {
                    updateSnake();
                    lastUpdateTime = now;
                }

                // Фон игрового поля
                DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());

                // Рисуем еду (красный квадрат)
                int foodX = gameX + food.getX() * tileSize;
                int foodY = gameY + food.getY() * tileSize;
                DisplayUtils.drawRoundedRect(foodX, foodY, tileSize, tileSize, 2f, new Color(255, 0, 0).getRGB());

                // Рисуем тело змейки зелёным
                for (int i = 1; i < snake.size(); i++) {
                    Vec2i part = snake.get(i);
                    int partX = gameX + part.getX() * tileSize;
                    int partY = gameY + part.getY() * tileSize;
                    DisplayUtils.drawRoundedRect(partX, partY, tileSize, tileSize, 2f, new Color(0, 200, 0).getRGB());
                }

                // Голова — ярко-зеленая
                Vec2i head = snake.get(0);
                int headX = gameX + head.getX() * tileSize;
                int headY = gameY + head.getY() * tileSize;
                DisplayUtils.drawRoundedRect(headX, headY, tileSize, tileSize, 2f, new Color(0, 255, 0).getRGB());
            }
        }
        DisplayUtils.drawImage(
                new ResourceLocation("expensive/images/ui/ava.png"),
                572 ,
                81,
                20,
                20,
                new Color(255, 255, 255).getRGB()
        );
        Fonts.quicksand_medium[15].drawCenteredString(
                matrixStack,
                "ChuppaChups",
                x + (width + 290) / 2f,
                y -3,
                -1
        );
    }









    void renderCategories(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel,
                          int mouseX, int mouseY, float iconOffsetY) {
        float heightCategory = 38 / 2f;
        float mainXOffset = 4f;

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (t == current) {
                // Прямоугольник для активной категории
                DisplayUtils.drawRoundedRect(
                        x + 0.8f, // отступ слева
                        yOffset + 2,
                        leftPanel - 97, // ширина, с отступами
                        heightCategory + 3,
                        new Vector4f(0, 0, 0, 0), // закругления
                        new Color(74, 166, 218).getRGB() // цвет фона
                );
            }
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/logo.png"),
                    248 ,
                    84,
                    60,
                    30,
                    new Color(255, 255, 255).getRGB()
            );


            // Иконка категории
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/" + t.name().toLowerCase() + ".png"),
                    (float) (x + 16 + t.anim),
                    (float) (yOffset + 5.5f),
                    10f,
                    10f,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );

            float textXOffset = (float) (x + 8 + t.anim + (t == Category.MAIN ? mainXOffset : 0f));

            // Название категории
            Fonts.mrubik[13].drawString(
                    matrixStack,
                    t.name(),
                    textXOffset,
                    yOffset + 20,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );
        }
    }




    void renderComponents(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        Scissor.push();
        Scissor.setFromComponentCoordinates(x, y + 64 / 2f, width, height - 64 / 2f);
        drawComponents(matrixStack, mouseX, mouseY);
        Scissor.unset();
        Scissor.pop();
        DisplayUtils.drawRoundedRect(x + leftPanel, y + 64 / 2f, width - leftPanel, height - 64 / 2f, new Vector4f(0, 0, 6, 6), new Color(22, 24, 28, ((int) (255 * animation))).getRGB());
    }

    void renderSearchBar(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (220 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        DisplayUtils.drawRoundedRect(barX, y - 10, barWidth, barHeight, 0, new Color(17, 18, 21, 255).brighter().getRGB());

        matrixStack.push();
        matrixStack.translate(barX, y + 14, 0);
        matrixStack.scale(1.0f, 1.0f, 1.0f);
        matrixStack.translate(-barX, -y - 14, 0);

        float xOffset = 0;
        float fontTextWidth = Fonts.gilroy[16].getWidth(searchText);

        if (fontTextWidth > barWidth) {
            xOffset = fontTextWidth - barWidth;
        }


        Fonts.gilroy[16].drawString(
                matrixStack,
                searchText + (typing ? (System.currentTimeMillis() % 1000 > 500 ? "|" : "") : ""),
                barX + 25    - xOffset,
                y - 3,
                -1
        );

        Stencil.uninitStencilBuffer();
        matrixStack.pop();

        // Иконки справа
        Fonts.icons[16].drawString(matrixStack, "B", x + width - (1600 / 2f) / 2f, y + (-4 / 2f) / 2f - 1, -1);
    }








    public CopyOnWriteArrayList<ConfigComponent> cfg = new CopyOnWriteArrayList<>();

    private String configName = "";
    private boolean configTyping;
    public static String confign;

    void drawComponents(MatrixStack stack, int mouseX, int mouseY) {

        List<ModuleComponent> moduleComponentList = objects.stream()
                .filter(moduleObject -> {
                    if (!searchText.isEmpty()) {
                        return true;
                    } else {
                        return moduleObject.function.getCategory() == current;
                    }
                }).toList();

        List<ModuleComponent> first = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 == 0)
                .toList();

        List<ModuleComponent> second = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 != 0)
                .toList();

        for (ConfigComponent c : config) {
            if (c.config.getFile().getName().equalsIgnoreCase(confign)) {
                selectedCfg = c;
            }
        }

        float scale = 2f;
        animateScroll = MathUtil.lerp(animateScroll, scroll, 10);
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);

        if (current == Category.MAIN) {
            if (homeMode) {
                DisplayUtils.drawRoundedRect(x + leftPanel - 56, y + 64 / 2F + 120,
                        355, height - 64 / 2F - 80, 0, new Color(12, 17, 21, 160).getRGB());
            }

            float fontTextWidth = Fonts.gilroy[16].getWidth(configName);
            float xOffset = 0;
            float availableWidth = width - leftPanel - 35 - 35 * 2;

            if (fontTextWidth > availableWidth) {
                xOffset = fontTextWidth - (availableWidth - 8);
            }

            Stencil.uninitStencilBuffer();
            config = cfg;

            float scissorX = x + leftPanel - 100;
            float scissorY = y + 64 / 2F + 120;
            float scissorWidth = 500;
            float scissorHeight = height - 64 / 2F - 80;

            Scissor.push();
            Scissor.setFromComponentCoordinates(scissorX, scissorY, scissorWidth, scissorHeight);

            float offset = scissorY + 8 + animateScroll;

            if (homeMode) {
                for (ConfigComponent component : config) {
                    component.parent = this;
                    component.selected = component == selectedCfg;
                    component.setPosition((float) (xPanel + 45), offset - 5, 352, 20);
                    component.drawComponent(stack, mouseX, mouseY);
                    offset += component.height + 2;
                }
            }

            Scissor.unset();
            Scissor.pop();

            scroll = Math.min(scroll, 0);
        }

        float offset = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size1 = 0;
        for (ModuleComponent component : first) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (35 + 12)), offset, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset + component.height -8;
                float descX = component.x + 5;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset += Fonts.gilroy[12].getFontHeight() + 2;
                size1 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset += settingComp.height;
                        size1 += settingComp.height;
                    }
                }
            }

            offset += component.height + 8;
            size1 += component.height + 8;
        }

        float offset2 = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size2 = 0;
        for (ModuleComponent component : second) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (45 + 12) + 314 / 2f + 10), offset2, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset2 + component.height - 9;
                float descX = component.x + 5   ;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset2 += Fonts.gilroy[12].getFontHeight() + 2;
                size2 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset2 += settingComp.height;
                        size2 += settingComp.height;
                    }
                }
            }

            offset2 += component.height + 8;
            size2 += component.height + 8;
        }

        float max = Math.max(size1, size2);
        if (max < height) {
            scroll = 0;
        } else {
            scroll = MathHelper.clamp(scroll, -(max - height + 50), 0);
        }
    }


    @Override
    public void init(Minecraft minecraft, int width, int height) {
        super.init(minecraft, width, height);
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        typing = false;
        configTyping = false;
        configOpened = false;
        configName = "";

        // ⬇️ Загрузка конфигов при входе в меню
        cfg.clear();
        for (String configName : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(configName)));
        }
        config = cfg;
    }


    @Override
    public boolean mouseReleased(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.mouseReleased((int) mouseX, (int) mouseY, button);
        }
//        for (ThemeComponent component : theme) {
//            if (current != Category.Theme) continue;
//            component.parent = this;
//            component.mouseReleased((int) mouseX, (int) mouseY, button);
//        }
        if (ColorComponent.opened != null) {
            ColorComponent.opened.unclick((int) mouseX, (int) mouseY);
        }
        return super.mouseReleased(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
            mc.displayGuiScreen(null);
            this.minecraft.keyboardListener.enableRepeatEvents(false);
        }

        boolean ctrlDown = Screen.hasControlDown();

        // Управление змейкой (WASD), только если в Minigames (категория MAIN и homeMode == false)
        if (current == Category.MAIN && !homeMode) {
            switch (keyCode) {
                case GLFW.GLFW_KEY_W:
                    if (dirY != 1) { // не даём змейке развернуться на 180°
                        dirX = 0;
                        dirY = -1;
                    }
                    return true;
                case GLFW.GLFW_KEY_S:
                    if (dirY != -1) {
                        dirX = 0;
                        dirY = 1;
                    }
                    return true;
                case GLFW.GLFW_KEY_A:
                    if (dirX != 1) {
                        dirX = -1;
                        dirY = 0;
                    }
                    return true;
                case GLFW.GLFW_KEY_D:
                    if (dirX != -1) {
                        dirX = 1;
                        dirY = 0;
                    }
                    return true;
            }
        }

        if (typing) {
            if (!(current == Category.MAIN)) {
                if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                    String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                    searchText += pasteText;
                }
                if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                    if (!searchText.isEmpty()) {
                        searchText = searchText.substring(0, searchText.length() - 1);
                    }
                }
                if (keyCode == GLFW.GLFW_KEY_DELETE) {
                    searchText = "";
                }
                if (keyCode == GLFW.GLFW_KEY_ENTER) {
                    typing = false;
                }
            }
        }

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.keyTyped(keyCode, scanCode, modifiers);
        }

        if (binding != null) {
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                binding.function.setBind(0);
            } else {
                binding.function.setBind(keyCode);
            }
            binding = null;
        }

        if (configTyping) {
            if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                configName += pasteText;
            }
            if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                if (!configName.isEmpty()) {
                    configName = configName.substring(0, configName.length() - 1);
                }
            }
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                configName = "";
            }
            if (keyCode == GLFW.GLFW_KEY_ENTER) {
                configTyping = false;
            }
        }

        return super.keyPressed(keyCode, scanCode, modifiers);
    }


    @Override
    public boolean charTyped(char codePoint, int modifiers) {
        if (typing)
            searchText += codePoint;
        if (configTyping)
            configName += codePoint;

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.charTyped(codePoint, modifiers);
        }
        return super.charTyped(codePoint, modifiers);
    }



    private boolean configOpened;

    private ConfigComponent selectedCfg;

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);

        mouseX = fixed.getX();
        mouseY = fixed.getY();

        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 199 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        float heightCategory = 45 / 2f;
        float iconOffsetY = 10.0f;
        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (64 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        float barY = y - 15;



        if (ColorComponent.opened != null) {
            if (!ColorComponent.opened.click((int) mouseX, (int) mouseY))
                return super.mouseClicked(mouseX, mouseY, button);
        }

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x, yOffset, 44, heightCategory)) {
                if (current == t) continue;

                current = t;
                animation = 1;
                scroll = 0;
                searchText = "";
                ColorComponent.opened = null;
                ThemeComponent.selected = null;
                typing = false;
            }
        }

        // *** Конфиги кликабельны только если homeMode == true и категория MAIN ***
        if (current == Category.MAIN && homeMode) {
            for (ConfigComponent component : config) {
                component.parent = this;
                if (MathUtil.isInRegion((float) mouseX, (float) mouseY, component.x + component.width - 35 - 2, component.y + 2, 35 - 2, 32 / 2f))
                    selectedCfg = component;
                component.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        // Кнопки сохранения/обновления конфигов обрабатываем в любом режиме
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            MainClass.getInstance().getConfigStorage().saveConfiguration(configName);
            configName = "";
            configTyping = false;
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 35 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }

        // *** Модули кликабельны только если homeMode == true ***
        if (homeMode && MathUtil.isInRegion((float) mouseX, (float) mouseY, x, y + 64 / 2f, width, height - 64 / 2f)) {
            for (ModuleComponent m : objects) {
                if (searchText.isEmpty()) {
                    if (m.function.getCategory() != current) continue;
                } else {
                    if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
                }
                m.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - ((64 / 2f) * 2) / 2f - 1, y + (64 / 2f) / 2f - 5, 10, 10)) {
            try {
                Runtime.getRuntime().exec("explorer " + MainClass.getInstance().getConfigStorage().CONFIG_DIR);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + leftPanel + 6 + ((width - leftPanel - 12 - (64 / 2f) / 2f) / 2f) * (1 - seacrh), y + 7, (width - leftPanel - 12 - (64 / 2f) / 2f) * (seacrh), 64 / 2f - 14)) {
            typing = !typing;
        } else {
            typing = false;
        }

        // Кнопки переключения Home / Minigames — без изменений
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = true;
            return true;
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX + buttonWidth + spacing, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = false;
            initSnakeGame(); // старт игры при переключении
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

}

есть chat gpt код
давайте теперь скит
 
хотите могу сурсы ликнуть
ss
Посмотреть вложение 310599

code
code:
Expand Collapse Copy
package club.monolith.chuppachups.other.render.midnight;

import club.monolith.chuppachups.main.MainClass;
import club.monolith.chuppachups.main.functions.api.Category;
import club.monolith.chuppachups.main.functions.api.Function;
import club.monolith.chuppachups.other.render.midnight.component.impl.*;
import club.monolith.chuppachups.other.render.midnight.component.impl.Component;
import club.monolith.chuppachups.other.render.styles.Style;
import club.monolith.chuppachups.other.utility.client.ClientUtil;
import club.monolith.chuppachups.other.utility.client.Vec2i;
import club.monolith.chuppachups.other.utility.font.Fonts;
import club.monolith.chuppachups.other.utility.math.MathUtil;
import club.monolith.chuppachups.other.utility.render.DisplayUtils;
import club.monolith.chuppachups.other.utility.render.Scissor;
import club.monolith.chuppachups.other.utility.render.Stencil;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.util.text.StringTextComponent;
import org.lwjgl.glfw.GLFW;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import static club.monolith.chuppachups.other.render.midnight.component.impl.ModuleComponent.binding;
import static club.monolith.chuppachups.other.utility.client.IMinecraft.mc;

public class ClickGui extends Screen {
    private final float gameX = 40;
    private final float gameY = 105;
    private final float gameWidth =  36.8f;;
    private final float gameHeight =  23.8f;
    private List<Vec2i> snake = new ArrayList<>();
    private Vec2i food;
    private int dirX = 1;
    private int dirY = 0;
    private long lastUpdateTime = 0;
    private final long updateInterval = 200; // обновлять игру каждые 200 мс

    private boolean homeMode = true;

    public ClickGui() {
        super(new StringTextComponent("GUI"));
        for (Function function : MainClass.getInstance().getFunctionRegistry().getList()) {
            objects.add(new ModuleComponent(function));
        }
        for (Style style : MainClass.getInstance().getStyleManager().getStyleList()) {
            this.theme.add(new ThemeComponent(style));
        }
        cfg.clear();
        for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
        }
    }
    private void initSnakeGame() {
        snake.clear();
        snake.add(new Vec2i(20, 15));
        snake.add(new Vec2i(19, 15));
        snake.add(new Vec2i(18, 15));
        dirX = 1;
        dirY = 0;
        placeFood();
    }
    private void updateSnake() {
        Vec2i head = snake.get(0);
        Vec2i newHead = new Vec2i(head.getX() + dirX, head.getY() + dirY);


        if (newHead.getX() < 0 || newHead.getX() >= (int)gameWidth || newHead.getY() < 0 || newHead.getY() >= (int)gameHeight) {
            initSnakeGame();
            return;
        }


        if (snake.contains(newHead)) {
            initSnakeGame();
            return;
        }

        snake.add(0, newHead);

        if (newHead.equals(food)) {
            placeFood();
        } else {
            snake.remove(snake.size() - 1);
        }
    }

    private void placeFood() {
        Random rand = new Random();
        int x, y;
        do {
            x = rand.nextInt((int) gameWidth);
            y = rand.nextInt((int) gameHeight);
        } while (snake.contains(new Vec2i(x, y)));
        food = new Vec2i(x, y);
    }
    double xPanel, yPanel;
    Category current = Category.COMBAT;

    float animation;

    public ArrayList<ModuleComponent> objects = new ArrayList<>();

    private CopyOnWriteArrayList<ConfigComponent> config = new CopyOnWriteArrayList<>();

    public List<ThemeComponent> theme = new ArrayList<>();

    public float scroll = 0;
    public float animateScroll = 0;

    @Override
    public void onClose() {
        super.onClose();
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        scroll += delta * 15;
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

    @Override
    public void closeScreen() {
        if (typing || !searchText.isEmpty()) {
            typing = false;
            searchText = "";
        }
        if (configTyping || !configName.isEmpty()) {
            configTyping = false;
            configName = "";
        }
    }
    @Override
    public boolean isPauseScreen() {
        return false;
    }

    boolean searchOpened;
    float seacrh;

    private String searchText = "";
    public static boolean typing;

    @Override
    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
        super.render(matrixStack, mouseX, mouseY, partialTicks);
        this.minecraft.keyboardListener.enableRepeatEvents(true);
        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        xPanel = x;
        yPanel = y;
        animation = MathUtil.lerp(animation, 0, 5);

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        int finalMouseX = mouseX;
        int finalMouseY = mouseY;

        mc.gameRenderer.setupOverlayRendering(2);
        renderBackground(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderCategories(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY, 12.0f);
        renderComponents(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderColorPicker(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderSearchBar(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        mc.gameRenderer.setupOverlayRendering();


    }

    void renderColorPicker(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        if (ColorComponent.opened != null) {
            ColorComponent.opened.draw(matrixStack, mouseX, mouseY);
        }
        if (ThemeComponent.selected != null) {
            ThemeComponent.selected.draw(matrixStack, mouseX, mouseY);
        }
    }

    void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        int gameX = (int) (x + 40);
        int gameY = (int) (y + 105);
        int tileSize = 10;
        float gameWidth =  36.8f;
        float gameHeight =  23.8f;

        DisplayUtils.drawShadow(x, y - 17, width - 42, height + 35, 20, new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
           DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());


        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        if (current == Category.MAIN) {
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(22, 24, 28).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21).getRGB());
            DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());
            // Кнопка Home
            DisplayUtils.drawRoundedRect(
                    buttonsX + 2,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Home",
                    buttonsX + buttonWidth / 2f + 2,
                    buttonsY + 6,
                    -1
            );

            // Кнопка Minigames
            DisplayUtils.drawRoundedRect(
                    buttonsX + 76,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    !homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Minigames",
                    buttonsX + 111,
                    buttonsY + 6,
                    -1
            );

            if (homeMode) {
                // Отрисовка юзера и подписки (Home)
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );
            } else {
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );


                // Обновляем змейку по времени
                long now = System.currentTimeMillis();
                if (now - lastUpdateTime > updateInterval) {
                    updateSnake();
                    lastUpdateTime = now;
                }

                // Фон игрового поля
                DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());

                // Рисуем еду (красный квадрат)
                int foodX = gameX + food.getX() * tileSize;
                int foodY = gameY + food.getY() * tileSize;
                DisplayUtils.drawRoundedRect(foodX, foodY, tileSize, tileSize, 2f, new Color(255, 0, 0).getRGB());

                // Рисуем тело змейки зелёным
                for (int i = 1; i < snake.size(); i++) {
                    Vec2i part = snake.get(i);
                    int partX = gameX + part.getX() * tileSize;
                    int partY = gameY + part.getY() * tileSize;
                    DisplayUtils.drawRoundedRect(partX, partY, tileSize, tileSize, 2f, new Color(0, 200, 0).getRGB());
                }

                // Голова — ярко-зеленая
                Vec2i head = snake.get(0);
                int headX = gameX + head.getX() * tileSize;
                int headY = gameY + head.getY() * tileSize;
                DisplayUtils.drawRoundedRect(headX, headY, tileSize, tileSize, 2f, new Color(0, 255, 0).getRGB());
            }
        }
        DisplayUtils.drawImage(
                new ResourceLocation("expensive/images/ui/ava.png"),
                572 ,
                81,
                20,
                20,
                new Color(255, 255, 255).getRGB()
        );
        Fonts.quicksand_medium[15].drawCenteredString(
                matrixStack,
                "ChuppaChups",
                x + (width + 290) / 2f,
                y -3,
                -1
        );
    }









    void renderCategories(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel,
                          int mouseX, int mouseY, float iconOffsetY) {
        float heightCategory = 38 / 2f;
        float mainXOffset = 4f;

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (t == current) {
                // Прямоугольник для активной категории
                DisplayUtils.drawRoundedRect(
                        x + 0.8f, // отступ слева
                        yOffset + 2,
                        leftPanel - 97, // ширина, с отступами
                        heightCategory + 3,
                        new Vector4f(0, 0, 0, 0), // закругления
                        new Color(74, 166, 218).getRGB() // цвет фона
                );
            }
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/logo.png"),
                    248 ,
                    84,
                    60,
                    30,
                    new Color(255, 255, 255).getRGB()
            );


            // Иконка категории
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/" + t.name().toLowerCase() + ".png"),
                    (float) (x + 16 + t.anim),
                    (float) (yOffset + 5.5f),
                    10f,
                    10f,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );

            float textXOffset = (float) (x + 8 + t.anim + (t == Category.MAIN ? mainXOffset : 0f));

            // Название категории
            Fonts.mrubik[13].drawString(
                    matrixStack,
                    t.name(),
                    textXOffset,
                    yOffset + 20,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );
        }
    }




    void renderComponents(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        Scissor.push();
        Scissor.setFromComponentCoordinates(x, y + 64 / 2f, width, height - 64 / 2f);
        drawComponents(matrixStack, mouseX, mouseY);
        Scissor.unset();
        Scissor.pop();
        DisplayUtils.drawRoundedRect(x + leftPanel, y + 64 / 2f, width - leftPanel, height - 64 / 2f, new Vector4f(0, 0, 6, 6), new Color(22, 24, 28, ((int) (255 * animation))).getRGB());
    }

    void renderSearchBar(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (220 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        DisplayUtils.drawRoundedRect(barX, y - 10, barWidth, barHeight, 0, new Color(17, 18, 21, 255).brighter().getRGB());

        matrixStack.push();
        matrixStack.translate(barX, y + 14, 0);
        matrixStack.scale(1.0f, 1.0f, 1.0f);
        matrixStack.translate(-barX, -y - 14, 0);

        float xOffset = 0;
        float fontTextWidth = Fonts.gilroy[16].getWidth(searchText);

        if (fontTextWidth > barWidth) {
            xOffset = fontTextWidth - barWidth;
        }


        Fonts.gilroy[16].drawString(
                matrixStack,
                searchText + (typing ? (System.currentTimeMillis() % 1000 > 500 ? "|" : "") : ""),
                barX + 25    - xOffset,
                y - 3,
                -1
        );

        Stencil.uninitStencilBuffer();
        matrixStack.pop();

        // Иконки справа
        Fonts.icons[16].drawString(matrixStack, "B", x + width - (1600 / 2f) / 2f, y + (-4 / 2f) / 2f - 1, -1);
    }








    public CopyOnWriteArrayList<ConfigComponent> cfg = new CopyOnWriteArrayList<>();

    private String configName = "";
    private boolean configTyping;
    public static String confign;

    void drawComponents(MatrixStack stack, int mouseX, int mouseY) {

        List<ModuleComponent> moduleComponentList = objects.stream()
                .filter(moduleObject -> {
                    if (!searchText.isEmpty()) {
                        return true;
                    } else {
                        return moduleObject.function.getCategory() == current;
                    }
                }).toList();

        List<ModuleComponent> first = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 == 0)
                .toList();

        List<ModuleComponent> second = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 != 0)
                .toList();

        for (ConfigComponent c : config) {
            if (c.config.getFile().getName().equalsIgnoreCase(confign)) {
                selectedCfg = c;
            }
        }

        float scale = 2f;
        animateScroll = MathUtil.lerp(animateScroll, scroll, 10);
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);

        if (current == Category.MAIN) {
            if (homeMode) {
                DisplayUtils.drawRoundedRect(x + leftPanel - 56, y + 64 / 2F + 120,
                        355, height - 64 / 2F - 80, 0, new Color(12, 17, 21, 160).getRGB());
            }

            float fontTextWidth = Fonts.gilroy[16].getWidth(configName);
            float xOffset = 0;
            float availableWidth = width - leftPanel - 35 - 35 * 2;

            if (fontTextWidth > availableWidth) {
                xOffset = fontTextWidth - (availableWidth - 8);
            }

            Stencil.uninitStencilBuffer();
            config = cfg;

            float scissorX = x + leftPanel - 100;
            float scissorY = y + 64 / 2F + 120;
            float scissorWidth = 500;
            float scissorHeight = height - 64 / 2F - 80;

            Scissor.push();
            Scissor.setFromComponentCoordinates(scissorX, scissorY, scissorWidth, scissorHeight);

            float offset = scissorY + 8 + animateScroll;

            if (homeMode) {
                for (ConfigComponent component : config) {
                    component.parent = this;
                    component.selected = component == selectedCfg;
                    component.setPosition((float) (xPanel + 45), offset - 5, 352, 20);
                    component.drawComponent(stack, mouseX, mouseY);
                    offset += component.height + 2;
                }
            }

            Scissor.unset();
            Scissor.pop();

            scroll = Math.min(scroll, 0);
        }

        float offset = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size1 = 0;
        for (ModuleComponent component : first) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (35 + 12)), offset, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset + component.height -8;
                float descX = component.x + 5;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset += Fonts.gilroy[12].getFontHeight() + 2;
                size1 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset += settingComp.height;
                        size1 += settingComp.height;
                    }
                }
            }

            offset += component.height + 8;
            size1 += component.height + 8;
        }

        float offset2 = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size2 = 0;
        for (ModuleComponent component : second) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (45 + 12) + 314 / 2f + 10), offset2, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset2 + component.height - 9;
                float descX = component.x + 5   ;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset2 += Fonts.gilroy[12].getFontHeight() + 2;
                size2 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset2 += settingComp.height;
                        size2 += settingComp.height;
                    }
                }
            }

            offset2 += component.height + 8;
            size2 += component.height + 8;
        }

        float max = Math.max(size1, size2);
        if (max < height) {
            scroll = 0;
        } else {
            scroll = MathHelper.clamp(scroll, -(max - height + 50), 0);
        }
    }


    @Override
    public void init(Minecraft minecraft, int width, int height) {
        super.init(minecraft, width, height);
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        typing = false;
        configTyping = false;
        configOpened = false;
        configName = "";

        // ⬇️ Загрузка конфигов при входе в меню
        cfg.clear();
        for (String configName : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(configName)));
        }
        config = cfg;
    }


    @Override
    public boolean mouseReleased(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.mouseReleased((int) mouseX, (int) mouseY, button);
        }
//        for (ThemeComponent component : theme) {
//            if (current != Category.Theme) continue;
//            component.parent = this;
//            component.mouseReleased((int) mouseX, (int) mouseY, button);
//        }
        if (ColorComponent.opened != null) {
            ColorComponent.opened.unclick((int) mouseX, (int) mouseY);
        }
        return super.mouseReleased(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
            mc.displayGuiScreen(null);
            this.minecraft.keyboardListener.enableRepeatEvents(false);
        }

        boolean ctrlDown = Screen.hasControlDown();

        // Управление змейкой (WASD), только если в Minigames (категория MAIN и homeMode == false)
        if (current == Category.MAIN && !homeMode) {
            switch (keyCode) {
                case GLFW.GLFW_KEY_W:
                    if (dirY != 1) { // не даём змейке развернуться на 180°
                        dirX = 0;
                        dirY = -1;
                    }
                    return true;
                case GLFW.GLFW_KEY_S:
                    if (dirY != -1) {
                        dirX = 0;
                        dirY = 1;
                    }
                    return true;
                case GLFW.GLFW_KEY_A:
                    if (dirX != 1) {
                        dirX = -1;
                        dirY = 0;
                    }
                    return true;
                case GLFW.GLFW_KEY_D:
                    if (dirX != -1) {
                        dirX = 1;
                        dirY = 0;
                    }
                    return true;
            }
        }

        if (typing) {
            if (!(current == Category.MAIN)) {
                if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                    String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                    searchText += pasteText;
                }
                if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                    if (!searchText.isEmpty()) {
                        searchText = searchText.substring(0, searchText.length() - 1);
                    }
                }
                if (keyCode == GLFW.GLFW_KEY_DELETE) {
                    searchText = "";
                }
                if (keyCode == GLFW.GLFW_KEY_ENTER) {
                    typing = false;
                }
            }
        }

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.keyTyped(keyCode, scanCode, modifiers);
        }

        if (binding != null) {
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                binding.function.setBind(0);
            } else {
                binding.function.setBind(keyCode);
            }
            binding = null;
        }

        if (configTyping) {
            if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                configName += pasteText;
            }
            if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                if (!configName.isEmpty()) {
                    configName = configName.substring(0, configName.length() - 1);
                }
            }
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                configName = "";
            }
            if (keyCode == GLFW.GLFW_KEY_ENTER) {
                configTyping = false;
            }
        }

        return super.keyPressed(keyCode, scanCode, modifiers);
    }


    @Override
    public boolean charTyped(char codePoint, int modifiers) {
        if (typing)
            searchText += codePoint;
        if (configTyping)
            configName += codePoint;

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.charTyped(codePoint, modifiers);
        }
        return super.charTyped(codePoint, modifiers);
    }



    private boolean configOpened;

    private ConfigComponent selectedCfg;

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);

        mouseX = fixed.getX();
        mouseY = fixed.getY();

        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 199 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        float heightCategory = 45 / 2f;
        float iconOffsetY = 10.0f;
        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (64 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        float barY = y - 15;



        if (ColorComponent.opened != null) {
            if (!ColorComponent.opened.click((int) mouseX, (int) mouseY))
                return super.mouseClicked(mouseX, mouseY, button);
        }

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x, yOffset, 44, heightCategory)) {
                if (current == t) continue;

                current = t;
                animation = 1;
                scroll = 0;
                searchText = "";
                ColorComponent.opened = null;
                ThemeComponent.selected = null;
                typing = false;
            }
        }

        // *** Конфиги кликабельны только если homeMode == true и категория MAIN ***
        if (current == Category.MAIN && homeMode) {
            for (ConfigComponent component : config) {
                component.parent = this;
                if (MathUtil.isInRegion((float) mouseX, (float) mouseY, component.x + component.width - 35 - 2, component.y + 2, 35 - 2, 32 / 2f))
                    selectedCfg = component;
                component.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        // Кнопки сохранения/обновления конфигов обрабатываем в любом режиме
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            MainClass.getInstance().getConfigStorage().saveConfiguration(configName);
            configName = "";
            configTyping = false;
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 35 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }

        // *** Модули кликабельны только если homeMode == true ***
        if (homeMode && MathUtil.isInRegion((float) mouseX, (float) mouseY, x, y + 64 / 2f, width, height - 64 / 2f)) {
            for (ModuleComponent m : objects) {
                if (searchText.isEmpty()) {
                    if (m.function.getCategory() != current) continue;
                } else {
                    if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
                }
                m.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - ((64 / 2f) * 2) / 2f - 1, y + (64 / 2f) / 2f - 5, 10, 10)) {
            try {
                Runtime.getRuntime().exec("explorer " + MainClass.getInstance().getConfigStorage().CONFIG_DIR);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + leftPanel + 6 + ((width - leftPanel - 12 - (64 / 2f) / 2f) / 2f) * (1 - seacrh), y + 7, (width - leftPanel - 12 - (64 / 2f) / 2f) * (seacrh), 64 / 2f - 14)) {
            typing = !typing;
        } else {
            typing = false;
        }

        // Кнопки переключения Home / Minigames — без изменений
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = true;
            return true;
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX + buttonWidth + spacing, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = false;
            initSnakeGame(); // старт игры при переключении
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

}

есть chat gpt код
ку напиши мне в тг @skypefear4ik
 
жду сурсы
 
хотите могу сурсы ликнуть
ss
Посмотреть вложение 310599

code
code:
Expand Collapse Copy
package club.monolith.chuppachups.other.render.midnight;

import club.monolith.chuppachups.main.MainClass;
import club.monolith.chuppachups.main.functions.api.Category;
import club.monolith.chuppachups.main.functions.api.Function;
import club.monolith.chuppachups.other.render.midnight.component.impl.*;
import club.monolith.chuppachups.other.render.midnight.component.impl.Component;
import club.monolith.chuppachups.other.render.styles.Style;
import club.monolith.chuppachups.other.utility.client.ClientUtil;
import club.monolith.chuppachups.other.utility.client.Vec2i;
import club.monolith.chuppachups.other.utility.font.Fonts;
import club.monolith.chuppachups.other.utility.math.MathUtil;
import club.monolith.chuppachups.other.utility.render.DisplayUtils;
import club.monolith.chuppachups.other.utility.render.Scissor;
import club.monolith.chuppachups.other.utility.render.Stencil;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.util.text.StringTextComponent;
import org.lwjgl.glfw.GLFW;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import static club.monolith.chuppachups.other.render.midnight.component.impl.ModuleComponent.binding;
import static club.monolith.chuppachups.other.utility.client.IMinecraft.mc;

public class ClickGui extends Screen {
    private final float gameX = 40;
    private final float gameY = 105;
    private final float gameWidth =  36.8f;;
    private final float gameHeight =  23.8f;
    private List<Vec2i> snake = new ArrayList<>();
    private Vec2i food;
    private int dirX = 1;
    private int dirY = 0;
    private long lastUpdateTime = 0;
    private final long updateInterval = 200; // обновлять игру каждые 200 мс

    private boolean homeMode = true;

    public ClickGui() {
        super(new StringTextComponent("GUI"));
        for (Function function : MainClass.getInstance().getFunctionRegistry().getList()) {
            objects.add(new ModuleComponent(function));
        }
        for (Style style : MainClass.getInstance().getStyleManager().getStyleList()) {
            this.theme.add(new ThemeComponent(style));
        }
        cfg.clear();
        for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
        }
    }
    private void initSnakeGame() {
        snake.clear();
        snake.add(new Vec2i(20, 15));
        snake.add(new Vec2i(19, 15));
        snake.add(new Vec2i(18, 15));
        dirX = 1;
        dirY = 0;
        placeFood();
    }
    private void updateSnake() {
        Vec2i head = snake.get(0);
        Vec2i newHead = new Vec2i(head.getX() + dirX, head.getY() + dirY);


        if (newHead.getX() < 0 || newHead.getX() >= (int)gameWidth || newHead.getY() < 0 || newHead.getY() >= (int)gameHeight) {
            initSnakeGame();
            return;
        }


        if (snake.contains(newHead)) {
            initSnakeGame();
            return;
        }

        snake.add(0, newHead);

        if (newHead.equals(food)) {
            placeFood();
        } else {
            snake.remove(snake.size() - 1);
        }
    }

    private void placeFood() {
        Random rand = new Random();
        int x, y;
        do {
            x = rand.nextInt((int) gameWidth);
            y = rand.nextInt((int) gameHeight);
        } while (snake.contains(new Vec2i(x, y)));
        food = new Vec2i(x, y);
    }
    double xPanel, yPanel;
    Category current = Category.COMBAT;

    float animation;

    public ArrayList<ModuleComponent> objects = new ArrayList<>();

    private CopyOnWriteArrayList<ConfigComponent> config = new CopyOnWriteArrayList<>();

    public List<ThemeComponent> theme = new ArrayList<>();

    public float scroll = 0;
    public float animateScroll = 0;

    @Override
    public void onClose() {
        super.onClose();
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        scroll += delta * 15;
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

    @Override
    public void closeScreen() {
        if (typing || !searchText.isEmpty()) {
            typing = false;
            searchText = "";
        }
        if (configTyping || !configName.isEmpty()) {
            configTyping = false;
            configName = "";
        }
    }
    @Override
    public boolean isPauseScreen() {
        return false;
    }

    boolean searchOpened;
    float seacrh;

    private String searchText = "";
    public static boolean typing;

    @Override
    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
        super.render(matrixStack, mouseX, mouseY, partialTicks);
        this.minecraft.keyboardListener.enableRepeatEvents(true);
        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        xPanel = x;
        yPanel = y;
        animation = MathUtil.lerp(animation, 0, 5);

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        int finalMouseX = mouseX;
        int finalMouseY = mouseY;

        mc.gameRenderer.setupOverlayRendering(2);
        renderBackground(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderCategories(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY, 12.0f);
        renderComponents(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderColorPicker(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        renderSearchBar(matrixStack, x, y, width, height, leftPanel, finalMouseX, finalMouseY);
        mc.gameRenderer.setupOverlayRendering();


    }

    void renderColorPicker(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        if (ColorComponent.opened != null) {
            ColorComponent.opened.draw(matrixStack, mouseX, mouseY);
        }
        if (ThemeComponent.selected != null) {
            ThemeComponent.selected.draw(matrixStack, mouseX, mouseY);
        }
    }

    void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        int gameX = (int) (x + 40);
        int gameY = (int) (y + 105);
        int tileSize = 10;
        float gameWidth =  36.8f;
        float gameHeight =  23.8f;

        DisplayUtils.drawShadow(x, y - 17, width - 42, height + 35, 20, new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
           DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
        DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());


        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        if (current == Category.MAIN) {
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, height + 35, new Vector4f(0, 0, 0, 0), new Color(22, 24, 28).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, width - 42, 65 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 255).getRGB());
            DisplayUtils.drawRoundedRect(x, y - 17, leftPanel - 55, height + 35, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21).getRGB());
            DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());
            // Кнопка Home
            DisplayUtils.drawRoundedRect(
                    buttonsX + 2,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Home",
                    buttonsX + buttonWidth / 2f + 2,
                    buttonsY + 6,
                    -1
            );

            // Кнопка Minigames
            DisplayUtils.drawRoundedRect(
                    buttonsX + 76,
                    buttonsY,
                    buttonWidth,
                    buttonHeight,
                    2f,
                    !homeMode ? new Color(74, 166, 218).getRGB() : new Color(30, 32, 36).getRGB()
            );
            Fonts.quicksand_medium[16].drawCenteredString(
                    matrixStack,
                    "Minigames",
                    buttonsX + 111,
                    buttonsY + 6,
                    -1
            );

            if (homeMode) {
                // Отрисовка юзера и подписки (Home)
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );
            } else {
                DisplayUtils.drawRoundedRect(x, y + 15, width - 42, 180 / 2f, new Vector4f(0, 0, 0, 0), new Color(17, 18, 21, 120).getRGB());

                Fonts.quicksand_medium[21].drawCenteredString(
                        matrixStack,
                        "Hello, ChuppaChups",
                        x + (width - 245) / 2f,
                        y + 27,
                        -1
                );

                Fonts.quicksand_medium[15].drawCenteredString(
                        matrixStack,
                        "Subscription till: lifetime",
                        x + (width - 256) / 2f,
                        y + 40,
                        -1
                );


                // Обновляем змейку по времени
                long now = System.currentTimeMillis();
                if (now - lastUpdateTime > updateInterval) {
                    updateSnake();
                    lastUpdateTime = now;
                }

                // Фон игрового поля
                DisplayUtils.drawRoundedRect(gameX, gameY, gameWidth * tileSize, gameHeight * tileSize, 0f, new Color(17, 18, 21, 255).getRGB());

                // Рисуем еду (красный квадрат)
                int foodX = gameX + food.getX() * tileSize;
                int foodY = gameY + food.getY() * tileSize;
                DisplayUtils.drawRoundedRect(foodX, foodY, tileSize, tileSize, 2f, new Color(255, 0, 0).getRGB());

                // Рисуем тело змейки зелёным
                for (int i = 1; i < snake.size(); i++) {
                    Vec2i part = snake.get(i);
                    int partX = gameX + part.getX() * tileSize;
                    int partY = gameY + part.getY() * tileSize;
                    DisplayUtils.drawRoundedRect(partX, partY, tileSize, tileSize, 2f, new Color(0, 200, 0).getRGB());
                }

                // Голова — ярко-зеленая
                Vec2i head = snake.get(0);
                int headX = gameX + head.getX() * tileSize;
                int headY = gameY + head.getY() * tileSize;
                DisplayUtils.drawRoundedRect(headX, headY, tileSize, tileSize, 2f, new Color(0, 255, 0).getRGB());
            }
        }
        DisplayUtils.drawImage(
                new ResourceLocation("expensive/images/ui/ava.png"),
                572 ,
                81,
                20,
                20,
                new Color(255, 255, 255).getRGB()
        );
        Fonts.quicksand_medium[15].drawCenteredString(
                matrixStack,
                "ChuppaChups",
                x + (width + 290) / 2f,
                y -3,
                -1
        );
    }









    void renderCategories(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel,
                          int mouseX, int mouseY, float iconOffsetY) {
        float heightCategory = 38 / 2f;
        float mainXOffset = 4f;

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (t == current) {
                // Прямоугольник для активной категории
                DisplayUtils.drawRoundedRect(
                        x + 0.8f, // отступ слева
                        yOffset + 2,
                        leftPanel - 97, // ширина, с отступами
                        heightCategory + 3,
                        new Vector4f(0, 0, 0, 0), // закругления
                        new Color(74, 166, 218).getRGB() // цвет фона
                );
            }
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/logo.png"),
                    248 ,
                    84,
                    60,
                    30,
                    new Color(255, 255, 255).getRGB()
            );


            // Иконка категории
            DisplayUtils.drawImage(
                    new ResourceLocation("expensive/images/ui/" + t.name().toLowerCase() + ".png"),
                    (float) (x + 16 + t.anim),
                    (float) (yOffset + 5.5f),
                    10f,
                    10f,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );

            float textXOffset = (float) (x + 8 + t.anim + (t == Category.MAIN ? mainXOffset : 0f));

            // Название категории
            Fonts.mrubik[13].drawString(
                    matrixStack,
                    t.name(),
                    textXOffset,
                    yOffset + 20,
                    t == current ? new Color(74, 166, 218).getRGB() : new Color(163, 176, 188).getRGB()
            );
        }
    }




    void renderComponents(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {
        Scissor.push();
        Scissor.setFromComponentCoordinates(x, y + 64 / 2f, width, height - 64 / 2f);
        drawComponents(matrixStack, mouseX, mouseY);
        Scissor.unset();
        Scissor.pop();
        DisplayUtils.drawRoundedRect(x + leftPanel, y + 64 / 2f, width - leftPanel, height - 64 / 2f, new Vector4f(0, 0, 6, 6), new Color(22, 24, 28, ((int) (255 * animation))).getRGB());
    }

    void renderSearchBar(MatrixStack matrixStack, float x, float y, float width, float height, float leftPanel, int mouseX, int mouseY) {

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (220 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        DisplayUtils.drawRoundedRect(barX, y - 10, barWidth, barHeight, 0, new Color(17, 18, 21, 255).brighter().getRGB());

        matrixStack.push();
        matrixStack.translate(barX, y + 14, 0);
        matrixStack.scale(1.0f, 1.0f, 1.0f);
        matrixStack.translate(-barX, -y - 14, 0);

        float xOffset = 0;
        float fontTextWidth = Fonts.gilroy[16].getWidth(searchText);

        if (fontTextWidth > barWidth) {
            xOffset = fontTextWidth - barWidth;
        }


        Fonts.gilroy[16].drawString(
                matrixStack,
                searchText + (typing ? (System.currentTimeMillis() % 1000 > 500 ? "|" : "") : ""),
                barX + 25    - xOffset,
                y - 3,
                -1
        );

        Stencil.uninitStencilBuffer();
        matrixStack.pop();

        // Иконки справа
        Fonts.icons[16].drawString(matrixStack, "B", x + width - (1600 / 2f) / 2f, y + (-4 / 2f) / 2f - 1, -1);
    }








    public CopyOnWriteArrayList<ConfigComponent> cfg = new CopyOnWriteArrayList<>();

    private String configName = "";
    private boolean configTyping;
    public static String confign;

    void drawComponents(MatrixStack stack, int mouseX, int mouseY) {

        List<ModuleComponent> moduleComponentList = objects.stream()
                .filter(moduleObject -> {
                    if (!searchText.isEmpty()) {
                        return true;
                    } else {
                        return moduleObject.function.getCategory() == current;
                    }
                }).toList();

        List<ModuleComponent> first = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 == 0)
                .toList();

        List<ModuleComponent> second = moduleComponentList
                .stream()
                .filter(moduleObject -> objects.indexOf(moduleObject) % 2 != 0)
                .toList();

        for (ConfigComponent c : config) {
            if (c.config.getFile().getName().equalsIgnoreCase(confign)) {
                selectedCfg = c;
            }
        }

        float scale = 2f;
        animateScroll = MathUtil.lerp(animateScroll, scroll, 10);
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 200 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);

        if (current == Category.MAIN) {
            if (homeMode) {
                DisplayUtils.drawRoundedRect(x + leftPanel - 56, y + 64 / 2F + 120,
                        355, height - 64 / 2F - 80, 0, new Color(12, 17, 21, 160).getRGB());
            }

            float fontTextWidth = Fonts.gilroy[16].getWidth(configName);
            float xOffset = 0;
            float availableWidth = width - leftPanel - 35 - 35 * 2;

            if (fontTextWidth > availableWidth) {
                xOffset = fontTextWidth - (availableWidth - 8);
            }

            Stencil.uninitStencilBuffer();
            config = cfg;

            float scissorX = x + leftPanel - 100;
            float scissorY = y + 64 / 2F + 120;
            float scissorWidth = 500;
            float scissorHeight = height - 64 / 2F - 80;

            Scissor.push();
            Scissor.setFromComponentCoordinates(scissorX, scissorY, scissorWidth, scissorHeight);

            float offset = scissorY + 8 + animateScroll;

            if (homeMode) {
                for (ConfigComponent component : config) {
                    component.parent = this;
                    component.selected = component == selectedCfg;
                    component.setPosition((float) (xPanel + 45), offset - 5, 352, 20);
                    component.drawComponent(stack, mouseX, mouseY);
                    offset += component.height + 2;
                }
            }

            Scissor.unset();
            Scissor.pop();

            scroll = Math.min(scroll, 0);
        }

        float offset = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size1 = 0;
        for (ModuleComponent component : first) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (35 + 12)), offset, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset + component.height -8;
                float descX = component.x + 5;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset += Fonts.gilroy[12].getFontHeight() + 2;
                size1 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset += settingComp.height;
                        size1 += settingComp.height;
                    }
                }
            }

            offset += component.height + 8;
            size1 += component.height + 8;
        }

        float offset2 = (float) (yPanel + (48 / 2f) + 12) + animateScroll;
        float size2 = 0;
        for (ModuleComponent component : second) {
            if (searchText.isEmpty()) {
                if (component.function.getCategory() != current) continue;
            } else {
                if (!component.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }

            component.parent = this;
            component.setPosition((float) (xPanel + (45 + 12) + 314 / 2f + 10), offset2, 314 / 2f, 37);
            component.drawComponent(stack, mouseX, mouseY);

            // Отрисовка описания
            String desc = component.function.getDescription();
            if (desc != null && !desc.isEmpty()) {
                float descY = offset2 + component.height - 9;
                float descX = component.x + 5   ;
                Fonts.gilroy[12].drawString(stack, desc, descX, descY, new Color(150, 150, 150).getRGB());
                offset2 += Fonts.gilroy[12].getFontHeight() + 2;
                size2 += Fonts.gilroy[12].getFontHeight() + 2;
            }

            if (!component.components.isEmpty()) {
                for (Component settingComp : component.components) {
                    if (settingComp.setting != null && settingComp.setting.visible.get()) {
                        offset2 += settingComp.height;
                        size2 += settingComp.height;
                    }
                }
            }

            offset2 += component.height + 8;
            size2 += component.height + 8;
        }

        float max = Math.max(size1, size2);
        if (max < height) {
            scroll = 0;
        } else {
            scroll = MathHelper.clamp(scroll, -(max - height + 50), 0);
        }
    }


    @Override
    public void init(Minecraft minecraft, int width, int height) {
        super.init(minecraft, width, height);
        ColorComponent.opened = null;
        ThemeComponent.selected = null;
        typing = false;
        configTyping = false;
        configOpened = false;
        configName = "";

        // ⬇️ Загрузка конфигов при входе в меню
        cfg.clear();
        for (String configName : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
            cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(configName)));
        }
        config = cfg;
    }


    @Override
    public boolean mouseReleased(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
        mouseX = fixed.getX();
        mouseY = fixed.getY();

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.mouseReleased((int) mouseX, (int) mouseY, button);
        }
//        for (ThemeComponent component : theme) {
//            if (current != Category.Theme) continue;
//            component.parent = this;
//            component.mouseReleased((int) mouseX, (int) mouseY, button);
//        }
        if (ColorComponent.opened != null) {
            ColorComponent.opened.unclick((int) mouseX, (int) mouseY);
        }
        return super.mouseReleased(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
            mc.displayGuiScreen(null);
            this.minecraft.keyboardListener.enableRepeatEvents(false);
        }

        boolean ctrlDown = Screen.hasControlDown();

        // Управление змейкой (WASD), только если в Minigames (категория MAIN и homeMode == false)
        if (current == Category.MAIN && !homeMode) {
            switch (keyCode) {
                case GLFW.GLFW_KEY_W:
                    if (dirY != 1) { // не даём змейке развернуться на 180°
                        dirX = 0;
                        dirY = -1;
                    }
                    return true;
                case GLFW.GLFW_KEY_S:
                    if (dirY != -1) {
                        dirX = 0;
                        dirY = 1;
                    }
                    return true;
                case GLFW.GLFW_KEY_A:
                    if (dirX != 1) {
                        dirX = -1;
                        dirY = 0;
                    }
                    return true;
                case GLFW.GLFW_KEY_D:
                    if (dirX != -1) {
                        dirX = 1;
                        dirY = 0;
                    }
                    return true;
            }
        }

        if (typing) {
            if (!(current == Category.MAIN)) {
                if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                    String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                    searchText += pasteText;
                }
                if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                    if (!searchText.isEmpty()) {
                        searchText = searchText.substring(0, searchText.length() - 1);
                    }
                }
                if (keyCode == GLFW.GLFW_KEY_DELETE) {
                    searchText = "";
                }
                if (keyCode == GLFW.GLFW_KEY_ENTER) {
                    typing = false;
                }
            }
        }

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.keyTyped(keyCode, scanCode, modifiers);
        }

        if (binding != null) {
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                binding.function.setBind(0);
            } else {
                binding.function.setBind(keyCode);
            }
            binding = null;
        }

        if (configTyping) {
            if (ctrlDown && keyCode == GLFW.GLFW_KEY_V) {
                String pasteText = GLFW.glfwGetClipboardString(Minecraft.getInstance().getMainWindow().getHandle());
                configName += pasteText;
            }
            if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
                if (!configName.isEmpty()) {
                    configName = configName.substring(0, configName.length() - 1);
                }
            }
            if (keyCode == GLFW.GLFW_KEY_DELETE) {
                configName = "";
            }
            if (keyCode == GLFW.GLFW_KEY_ENTER) {
                configTyping = false;
            }
        }

        return super.keyPressed(keyCode, scanCode, modifiers);
    }


    @Override
    public boolean charTyped(char codePoint, int modifiers) {
        if (typing)
            searchText += codePoint;
        if (configTyping)
            configName += codePoint;

        for (ModuleComponent m : objects) {
            if (searchText.isEmpty()) {
                if (m.function.getCategory() != current) continue;
            } else {
                if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
            }
            m.charTyped(codePoint, modifiers);
        }
        return super.charTyped(codePoint, modifiers);
    }



    private boolean configOpened;

    private ConfigComponent selectedCfg;

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {

        Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);

        mouseX = fixed.getX();
        mouseY = fixed.getY();

        float scale = 2f;
        float width = 900 / scale;
        float height = 650 / scale;
        float leftPanel = 199 / scale;
        float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
        float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
        float heightCategory = 45 / 2f;
        float iconOffsetY = 10.0f;
        float buttonWidth = 70;
        float buttonHeight = 17;
        float spacing = 10;
        float buttonsX = x + (width - buttonWidth) / 2f - 140;
        float buttonsY = y + 82;

        float barX = x + leftPanel + 6 + ((width - leftPanel - 12 - (1836 / 2f) / 2f) / 2f);
        float barWidth = (width - leftPanel - 28 - (64 / 2f) / 2f);
        float barHeight = 64 / 2f - 14;
        float barY = y - 15;



        if (ColorComponent.opened != null) {
            if (!ColorComponent.opened.click((int) mouseX, (int) mouseY))
                return super.mouseClicked(mouseX, mouseY, button);
        }

        for (Category t : Category.values()) {
            float yOffset = y + 32.5f + t.ordinal() * (heightCategory + iconOffsetY);

            if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x, yOffset, 44, heightCategory)) {
                if (current == t) continue;

                current = t;
                animation = 1;
                scroll = 0;
                searchText = "";
                ColorComponent.opened = null;
                ThemeComponent.selected = null;
                typing = false;
            }
        }

        // *** Конфиги кликабельны только если homeMode == true и категория MAIN ***
        if (current == Category.MAIN && homeMode) {
            for (ConfigComponent component : config) {
                component.parent = this;
                if (MathUtil.isInRegion((float) mouseX, (float) mouseY, component.x + component.width - 35 - 2, component.y + 2, 35 - 2, 32 / 2f))
                    selectedCfg = component;
                component.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        // Кнопки сохранения/обновления конфигов обрабатываем в любом режиме
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            MainClass.getInstance().getConfigStorage().saveConfiguration(configName);
            configName = "";
            configTyping = false;
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - 45 - 35 - 2, y + 64 / 2F + 15, 35 - 2, 32 / 2f)) {
            cfg.clear();
            for (String config : MainClass.getInstance().getConfigStorage().getConfigsByName()) {
                cfg.add(new ConfigComponent(MainClass.getInstance().getConfigStorage().findConfig(config)));
            }
        }

        // *** Модули кликабельны только если homeMode == true ***
        if (homeMode && MathUtil.isInRegion((float) mouseX, (float) mouseY, x, y + 64 / 2f, width, height - 64 / 2f)) {
            for (ModuleComponent m : objects) {
                if (searchText.isEmpty()) {
                    if (m.function.getCategory() != current) continue;
                } else {
                    if (!m.function.getName().toLowerCase().contains(searchText.toLowerCase())) continue;
                }
                m.mouseClicked((int) mouseX, (int) mouseY, button);
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + width - ((64 / 2f) * 2) / 2f - 1, y + (64 / 2f) / 2f - 5, 10, 10)) {
            try {
                Runtime.getRuntime().exec("explorer " + MainClass.getInstance().getConfigStorage().CONFIG_DIR);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, x + leftPanel + 6 + ((width - leftPanel - 12 - (64 / 2f) / 2f) / 2f) * (1 - seacrh), y + 7, (width - leftPanel - 12 - (64 / 2f) / 2f) * (seacrh), 64 / 2f - 14)) {
            typing = !typing;
        } else {
            typing = false;
        }

        // Кнопки переключения Home / Minigames — без изменений
        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = true;
            return true;
        }

        if (MathUtil.isInRegion((float) mouseX, (float) mouseY, buttonsX + buttonWidth + spacing, buttonsY, buttonWidth, buttonHeight)) {
            homeMode = false;
            initSnakeGame(); // старт игры при переключении
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

}

есть chat gpt код
ждём кряк чита
 
Назад
Сверху Снизу