Визуальная часть FuntimeHelper | exp 3.1

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
8 Авг 2025
Сообщения
25
Реакции
0
Выберите загрузчик игры
  1. Vanilla
  2. Forge
  3. Fabric
  4. NeoForge
  5. OptiFine
  6. ForgeOptiFine
  7. Прочие моды
Всем привет медвед. Сливаю полезную функцию для всех серверов, пастерам сойдёт.
Увидел данные 2 темы: https://yougame.biz/threads/362214, https://yougame.biz/threads/362451.
И решил их доработать и сделать общий хороший элемент худа, который подойдёт как и для нн паст, так и для популярных читов. Надеюсь не будет /del и так далее, ведь я реально по тратил на это 1час. P.S. Вторая моя тема на югейме

Cделано читом: SpookyClient.fun(noad)
Автор произведения: Rastyshka1337 AKA defByrniy

SS:
код:

О великий Rastyshka спасибо тебе!!!:
Expand Collapse Copy
package SpookyRecode.functions.impl.render;

import SpookyRecode.Spooky;
import SpookyRecode.events.EventDisplay;
import SpookyRecode.events.EventKey;
import SpookyRecode.events.EventMouseButtonPress;
import SpookyRecode.events.EventTarget;
import SpookyRecode.events.EventUpdate;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerTryUseItemPacket;
import net.minecraft.util.Hand;
import SpookyRecode.functions.api.Category;
import SpookyRecode.functions.api.Function;
import SpookyRecode.functions.api.FunctionRegister;
import SpookyRecode.functions.settings.impl.BindSetting;
import SpookyRecode.functions.settings.impl.BooleanSetting;
import SpookyRecode.ui.display.ElementRenderer;
import SpookyRecode.utils.client.KeyStorage;
import SpookyRecode.utils.drag.Dragging;
import SpookyRecode.utils.render.DisplayUtils;
import SpookyRecode.utils.render.font.Fonts;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;

import java.util.*;
/*
Данный код сделан Rastyshka1337 by SpookyClient.fun
        */

@FunctionRegister(
    name = "FTItemRender",
    description = "Отображает предметы с привязками клавиш",
    type = Category.Render,
    key = 0
)

public class FTItemRender extends Function implements ElementRenderer {

    private final Dragging dragging;
    private float width;
    private float height;

    private static final float alphaSpeed = 10.0F;
    private float currentAlpha = 0.0F;
    private static final List<FunItemType> FUN_ITEM_TYPES;
  
    // ТЕСТ: Переменные для тестового кулдауна
    private long testCooldownStartTime = 0;
    private boolean testCooldownActive = false;

    // Настройки для привязок клавиш
    public BindSetting disorientationKey = new BindSetting("Дезориентация", -1);
    public BindSetting trapKey = new BindSetting("Трапка", -1);
    public BindSetting blatantKey = new BindSetting("Явная пыль", -1);
    public BindSetting snegKey = new BindSetting("Снежок", -1);
    public BindSetting plastKey = new BindSetting("Пласт", -1);
    public BindSetting auraKey = new BindSetting("Божья аура", -1);
    public BindSetting chorusKey = new BindSetting("Хорус", -1);
    public BindSetting enderPearlKey = new BindSetting("Эндержемчуг", -1);

    public BooleanSetting showOnlyBound = new BooleanSetting("Показывать только привязанные", false);
    public BooleanSetting showBackground = new BooleanSetting("Показывать фон", true);
    public BooleanSetting showKeyBinds = new BooleanSetting("Показывать клавиши", true);
    public BooleanSetting showCooldowns = new BooleanSetting("Показывать кулдауны", true);

    public FTItemRender() {
        this.dragging = Dick.getInstance().createDrag(this, "FTItemRender", 10.0F, 10.0F);
        this.addSettings(
            disorientationKey,
            trapKey,
            blatantKey,
            snegKey,
            plastKey,
            auraKey,
            chorusKey,
            enderPearlKey,
            showOnlyBound,
            showBackground,
            showKeyBinds,
            showCooldowns
        );
    }

    @EventTarget
    private void onDisplay(EventDisplay e) {
        if (e.getType() == EventDisplay.Type.POST) {
            render(e);
        }
    }

    @EventTarget
    private void onUpdate(EventUpdate e) {
        // ТЕСТ: Обработка тестового кулдауна
        if (mc.isSingleplayer() && testCooldownActive) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - testCooldownStartTime;
          
            // Если прошло 60 секунд, завершаем кулдаун
            if (elapsedTime >= 60000) { // 60 секунд = 60000 миллисекунд
                testCooldownActive = false;
            }
        }
      
        // ТЕСТ: Активация кулдауна по нажатию клавиши Z
        // if (mc.isSingleplayer() && mc.gameSettings.keyBindSneak.isKeyDown()) {
        //     activateTestCooldown();
        // }
    }

    @EventTarget
    private void onKey(EventKey e) {
        if (mc.player == null || mc.world == null) return;

        int key = e.getKey();
        Item targetItem = null;
      
        // Проверяем бинды для всех предметов
        if (key == (Integer) disorientationKey.get()) targetItem = Items.ENDER_EYE;
        if (key == (Integer) trapKey.get()) targetItem = Items.NETHERITE_SCRAP;
        if (key == (Integer) blatantKey.get()) targetItem = Items.SUGAR;
        if (key == (Integer) snegKey.get()) targetItem = Items.SNOWBALL;
        if (key == (Integer) plastKey.get()) targetItem = Items.DRIED_KELP;
        if (key == (Integer) auraKey.get()) targetItem = Items.PHANTOM_MEMBRANE;
        if (key == (Integer) chorusKey.get()) targetItem = Items.CHORUS_FRUIT;
        if (key == (Integer) enderPearlKey.get()) targetItem = Items.ENDER_PEARL;
      
        if (targetItem == null) return;

        // Try fast select in hotbar first
        int hotbarSlot = -1;
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                hotbarSlot = i;
                break;
            }
        }

        if (hotbarSlot != -1) {
            int prev = mc.player.inventory.currentItem;
            // switch to slot (client + server), then use
            mc.player.inventory.currentItem = hotbarSlot;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(hotbarSlot));
            mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
            mc.player.swingArm(Hand.MAIN_HAND);
            // switch back
            mc.player.inventory.currentItem = prev;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(prev));
            return;
        }

        // Not in hotbar: pick from inventory (9..35) into hand and use
        for (int i = 9; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                // Pick item from inventory into current hotbar slot, then use
                mc.playerController.pickItem(i);
                mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
                mc.player.swingArm(Hand.MAIN_HAND);
                break;
            }
        }
    }



    @Override
    public void render(EventDisplay eventDisplay) {
        if (mc.player == null) return;

        MatrixStack ms = eventDisplay.getMatrixStack();

        float posX = dragging.getX();
        float posY = dragging.getY();
        float iconSize = 16.0F;
        float padding = 4.0F;
        float itemSpacing = 2.0F;
        float keyFontSize = 10.0F;

        List<FunItem> visibleItems = getVisibleItemsFromInventory();
        if (visibleItems.isEmpty()) return;

        // Размеры как на скриншоте
        float itemBoxWidth = 36.0F; // Шире для центрирования букв
        float itemBoxHeight = 20.0F; // Компактная высота

        this.width = visibleItems.size() * (itemBoxWidth + itemSpacing) - itemSpacing;
        this.height = itemBoxHeight;

        dragging.setWidth(this.width);
        dragging.setHeight(this.height);
      

        float currentX = posX;

        int backgroundColor = 0x80000000; // Полупрозрачный черный фон
        int textColor = 0xFFFFFFFF; // Белый цвет текста

        for (FunItem item : visibleItems) {
            // Рисуем белую обводку (сначала, чтобы она была под фоном)
            DisplayUtils.drawRoundedRect(currentX - 0.5f, posY - 0.5f, itemBoxWidth + 1.0f, itemBoxHeight + 1.0f, 4.5f, 1.0f, 0xFFFFFFFF);
          
            // Рисуем фон для предмета с закругленными углами (поверх обводки)
            DisplayUtils.drawRoundedRect(currentX, posY, itemBoxWidth, itemBoxHeight, 4.0f, 1.0f, backgroundColor);

            // Рендерим иконку предмета слева
            float iconX = currentX + 2.0F;
            float iconY = posY + 2.0F;
            mc.getItemRenderer().renderItemAndEffectIntoGUI(item.itemStack, (int) iconX, (int) iconY);

            // Определяем, что показывать: кулдаун или бинд
            String displayText = "-";
            int displayColor = textColor;
            boolean showCooldown = false;
          
            if (showCooldowns.get() && hasCooldown(item.itemStack.getItem())) {
                // Показываем кулдаун
                String cooldownText = getCooldownText(item.itemStack.getItem());
                if (cooldownText != null) {
                    displayText = cooldownText;
                    displayColor = 0xFFFF0000; // Красный цвет для кулдауна
                    showCooldown = true;
                }
            } else if (showKeyBinds.get()) {
                // Показываем бинд
                BindSetting bindSetting = getBindSettingForItem(item.itemType);
                if (bindSetting != null) {
                    int keyCode = (Integer) bindSetting.get();
                    displayText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                }
            }

            // Рендерим текст
            if (showCooldown) {
                // Кулдаун под иконкой предмета с градиентом от красного к зеленому
                float cooldown = getItemCooldown(item.itemStack.getItem());
                float progress = cooldown / 60.0f; // Прогресс от 1.0 (начало) до 0.0 (конец)
                progress = Math.max(0.0f, Math.min(1.0f, progress)); // Ограничиваем от 0 до 1
              
                // Интерполяция цвета от красного к зеленому
                int red = (int)(255 * progress); // От 255 до 0
                int green = (int)(255 * (1.0f - progress)); // От 0 до 255
                int cooldownColor = 0xFF000000 | (red << 16) | (green << 8); // RGB
              
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + (itemBoxWidth - textWidth) / 2.0F; // По центру
                float textY = posY + 24.0F; // Под иконкой, сдвинуто вверх
                Fonts.sfui.drawText(ms, displayText, textX, textY, cooldownColor, keyFontSize, 0.05F);
              
                // Показываем бинд справа, если есть
                if (showKeyBinds.get()) {
                    BindSetting bindSetting = getBindSettingForItem(item.itemType);
                    if (bindSetting != null) {
                        int keyCode = (Integer) bindSetting.get();
                        String bindText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                        float bindWidth = Fonts.sfui.getWidth(bindText, keyFontSize);
                        float bindX = currentX + itemBoxWidth - bindWidth - 4.0F;
                        float bindY = posY + 6.0F;
                        Fonts.sfui.drawText(ms, bindText, bindX, bindY, textColor, keyFontSize, 0.05F);
                    }
                }
            } else {
                // Бинд справа
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + itemBoxWidth - textWidth - 4.0F; // Отступ от правого края
                float textY = posY + 6.0F;
                Fonts.sfui.drawText(ms, displayText, textX, textY, displayColor, keyFontSize, 0.05F);
            }

            currentX += itemBoxWidth + itemSpacing;
        }
    }

    private List<FunItem> getVisibleItemsFromInventory() {
        List<FunItem> visibleItems = new ArrayList<>();
        if (mc.player == null) return visibleItems;

        Set<Item> alreadyAdded = new HashSet<>();
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); ++i) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty()) {
                for (FunItemType itemType : FUN_ITEM_TYPES) {
                    if (stack.getItem() == itemType.item && !alreadyAdded.contains(itemType.item) && shouldShowItem(itemType, stack)) {
                        visibleItems.add(new FunItem(itemType.name, stack, i));
                        alreadyAdded.add(itemType.item);
                        break;
                    }
                }
            }
        }
        return visibleItems;
    }

    private boolean shouldShowItem(FunItemType itemType, ItemStack stack) {
        // Показываем все найденные FT предметы, независимо от кулдауна и привязок
        return true;
    }

    private boolean hasCooldown(Item item) {
        // ТЕСТ: Для локального мира проверяем тестовый кулдаун
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
          
            if (isFTItem && testCooldownActive) {
                return true;
            }
        }
      
        return mc.player.getCooldownTracker().hasCooldown(item);
    }

    private float getItemCooldown(Item item) {
        // ТЕСТ: Для локального мира возвращаем оставшееся время кулдауна
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
          
            if (isFTItem && testCooldownActive) {
                long currentTime = System.currentTimeMillis();
                long elapsedTime = currentTime - testCooldownStartTime;
                float remainingTime = (60000 - elapsedTime) / 1000.0f; // Конвертируем в секунды
                return Math.max(0, remainingTime);
            }
        }
      
        return mc.player.getCooldownTracker().getCooldown(item, 0);
    }

    private String getCooldownText(Item item) {
        if (!hasCooldown(item)) return null;
      
        float cooldown = getItemCooldown(item);
      
        if (cooldown >= 1.0f) {
            return String.format("%.0fs", cooldown);
        } else {
            return String.format("%.1fs", cooldown);
        }
    }

    // ТЕСТ: Метод для активации тестового кулдауна (вызывать при использовании предмета)
    public void activateTestCooldown() {
        if (mc.isSingleplayer()) {
            testCooldownStartTime = System.currentTimeMillis();
            testCooldownActive = true;
        }
    }

    private boolean isItemBound(FunItemType itemType) {
        BindSetting bindSetting = getBindSettingForItem(itemType);
        return bindSetting != null && (Integer) bindSetting.get() != -1;
    }

    private BindSetting getBindSettingForItem(FunItemType itemType) {
        return switch (itemType.name) {
            case "Дезориентация" -> disorientationKey;
            case "Трапка" -> trapKey;
            case "Явная пыль" -> blatantKey;
            case "Снежок" -> snegKey;
            case "Пласт" -> plastKey;
            case "Божья аура" -> auraKey;
            case "Хорус" -> chorusKey;
            case "Эндержемчуг" -> enderPearlKey;
            default -> null;
        };
    }

    // Вспомогательные классы
    private static class FunItem {
        public final String name;
        public final ItemStack itemStack;
        public final int slot;
        public final FunItemType itemType;

        public FunItem(String name, ItemStack itemStack, int slot) {
            this.name = name;
            this.itemStack = itemStack;
            this.slot = slot;
            this.itemType = FUN_ITEM_TYPES.stream()
                .filter(type -> type.name.equals(name))
                .findFirst()
                .orElse(null);
        }
    }

    private static class FunItemType {
        public final String name;
        public final Item item;

        public FunItemType(String name, Item item) {
            this.name = name;
            this.item = item;
        }
    }

    static {
        FUN_ITEM_TYPES = Arrays.asList(
            new FunItemType("Дезориентация", Items.ENDER_EYE), // Око эндера
            new FunItemType("Явная пыль", Items.SUGAR), // Сахар
            new FunItemType("Снежок", Items.SNOWBALL), // Снежок
            new FunItemType("Пласт", Items.DRIED_KELP), // Сушёная ламинария
            new FunItemType("Трапка", Items.NETHERITE_SCRAP), // Незеритовый лом
            new FunItemType("Божья аура", Items.PHANTOM_MEMBRANE), // Мембрана фантома
            new FunItemType("Хорус", Items.CHORUS_FRUIT), // Хорус
            new FunItemType("Эндержемчуг", Items.ENDER_PEARL) // Эндержемчуг
        );
    }
}
 
Последнее редактирование:
Если че его надо элементом худа делать, а не функцией, позор /del
это FuntimeHelper.
Ужасно реализовано так ещё и гпт код 🙄/del
как раз таки реализовано нормально, а так да половину гпт
Ужасно реализовано так ещё и гпт код 🙄/del
да и я написал что это больше подходит пастерочкам
 
это FuntimeHelper.

как раз таки реализовано нормально, а так да половину гпт

да и я написал что это больше подходит пастерочкам
богу стыдно уже за клиенты в которых хелперы находятся не в одной функции
 
так ты сам пастер/лгбт юзер и что-то хочешь сказать? XD
бро с такими темами даже юг не открывай
богу стыдно уже за клиенты в которых хелперы находятся не в одной функции
это идёт одной функцией алё
 
бро с такими темами даже юг не открывай

это идёт одной функцией алё
я те говорю про хв хелперы фт хелперы и т.д,у меня в клиенте они просто все в одном модуле находятся) и так у всех нормальных клиентов
 
бро с такими темами даже юг не открывай

это идёт одной функцией алё
не называй меня бро, тип меня разбанили 14 октября, про старое не говори мне)
ты делаешь через гпт и пытаешься сказать что функция нормальная xD
 
Всем привет медвед. Сливаю полезную функцию для всех серверов, пастерам сойдёт.
Увидел данные 2 темы: https://yougame.biz/threads/362214, https://yougame.biz/threads/362451.
И решил их доработать и сделать общий хороший элемент худа, который подойдёт как и для нн паст, так и для популярных читов. Надеюсь не будет /del и так далее, ведь я реально по тратил на это 1час. P.S. Вторая моя тема на югейме

Cделано читом: SpookyClient.fun(noad)
Автор произведения: Rastyshka1337 AKA defByrniy

SS:
код:

О великий Rastyshka спасибо тебе!!!:
Expand Collapse Copy
package SpookyRecode.functions.impl.render;

import SpookyRecode.Spooky;
import SpookyRecode.events.EventDisplay;
import SpookyRecode.events.EventKey;
import SpookyRecode.events.EventMouseButtonPress;
import SpookyRecode.events.EventTarget;
import SpookyRecode.events.EventUpdate;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerTryUseItemPacket;
import net.minecraft.util.Hand;
import SpookyRecode.functions.api.Category;
import SpookyRecode.functions.api.Function;
import SpookyRecode.functions.api.FunctionRegister;
import SpookyRecode.functions.settings.impl.BindSetting;
import SpookyRecode.functions.settings.impl.BooleanSetting;
import SpookyRecode.ui.display.ElementRenderer;
import SpookyRecode.utils.client.KeyStorage;
import SpookyRecode.utils.drag.Dragging;
import SpookyRecode.utils.render.DisplayUtils;
import SpookyRecode.utils.render.font.Fonts;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;

import java.util.*;
/*
Данный код сделан Rastyshka1337 by SpookyClient.fun
        */

@FunctionRegister(
    name = "FTItemRender",
    description = "Отображает предметы с привязками клавиш",
    type = Category.Render,
    key = 0
)

public class FTItemRender extends Function implements ElementRenderer {

    private final Dragging dragging;
    private float width;
    private float height;

    private static final float alphaSpeed = 10.0F;
    private float currentAlpha = 0.0F;
    private static final List<FunItemType> FUN_ITEM_TYPES;
 
    // ТЕСТ: Переменные для тестового кулдауна
    private long testCooldownStartTime = 0;
    private boolean testCooldownActive = false;

    // Настройки для привязок клавиш
    public BindSetting disorientationKey = new BindSetting("Дезориентация", -1);
    public BindSetting trapKey = new BindSetting("Трапка", -1);
    public BindSetting blatantKey = new BindSetting("Явная пыль", -1);
    public BindSetting snegKey = new BindSetting("Снежок", -1);
    public BindSetting plastKey = new BindSetting("Пласт", -1);
    public BindSetting auraKey = new BindSetting("Божья аура", -1);
    public BindSetting chorusKey = new BindSetting("Хорус", -1);
    public BindSetting enderPearlKey = new BindSetting("Эндержемчуг", -1);

    public BooleanSetting showOnlyBound = new BooleanSetting("Показывать только привязанные", false);
    public BooleanSetting showBackground = new BooleanSetting("Показывать фон", true);
    public BooleanSetting showKeyBinds = new BooleanSetting("Показывать клавиши", true);
    public BooleanSetting showCooldowns = new BooleanSetting("Показывать кулдауны", true);

    public FTItemRender() {
        this.dragging = Dick.getInstance().createDrag(this, "FTItemRender", 10.0F, 10.0F);
        this.addSettings(
            disorientationKey,
            trapKey,
            blatantKey,
            snegKey,
            plastKey,
            auraKey,
            chorusKey,
            enderPearlKey,
            showOnlyBound,
            showBackground,
            showKeyBinds,
            showCooldowns
        );
    }

    @EventTarget
    private void onDisplay(EventDisplay e) {
        if (e.getType() == EventDisplay.Type.POST) {
            render(e);
        }
    }

    @EventTarget
    private void onUpdate(EventUpdate e) {
        // ТЕСТ: Обработка тестового кулдауна
        if (mc.isSingleplayer() && testCooldownActive) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - testCooldownStartTime;
         
            // Если прошло 60 секунд, завершаем кулдаун
            if (elapsedTime >= 60000) { // 60 секунд = 60000 миллисекунд
                testCooldownActive = false;
            }
        }
     
        // ТЕСТ: Активация кулдауна по нажатию клавиши Z
        // if (mc.isSingleplayer() && mc.gameSettings.keyBindSneak.isKeyDown()) {
        //     activateTestCooldown();
        // }
    }

    @EventTarget
    private void onKey(EventKey e) {
        if (mc.player == null || mc.world == null) return;

        int key = e.getKey();
        Item targetItem = null;
     
        // Проверяем бинды для всех предметов
        if (key == (Integer) disorientationKey.get()) targetItem = Items.ENDER_EYE;
        if (key == (Integer) trapKey.get()) targetItem = Items.NETHERITE_SCRAP;
        if (key == (Integer) blatantKey.get()) targetItem = Items.SUGAR;
        if (key == (Integer) snegKey.get()) targetItem = Items.SNOWBALL;
        if (key == (Integer) plastKey.get()) targetItem = Items.DRIED_KELP;
        if (key == (Integer) auraKey.get()) targetItem = Items.PHANTOM_MEMBRANE;
        if (key == (Integer) chorusKey.get()) targetItem = Items.CHORUS_FRUIT;
        if (key == (Integer) enderPearlKey.get()) targetItem = Items.ENDER_PEARL;
     
        if (targetItem == null) return;

        // Try fast select in hotbar first
        int hotbarSlot = -1;
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                hotbarSlot = i;
                break;
            }
        }

        if (hotbarSlot != -1) {
            int prev = mc.player.inventory.currentItem;
            // switch to slot (client + server), then use
            mc.player.inventory.currentItem = hotbarSlot;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(hotbarSlot));
            mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
            mc.player.swingArm(Hand.MAIN_HAND);
            // switch back
            mc.player.inventory.currentItem = prev;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(prev));
            return;
        }

        // Not in hotbar: pick from inventory (9..35) into hand and use
        for (int i = 9; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                // Pick item from inventory into current hotbar slot, then use
                mc.playerController.pickItem(i);
                mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
                mc.player.swingArm(Hand.MAIN_HAND);
                break;
            }
        }
    }



    @Override
    public void render(EventDisplay eventDisplay) {
        if (mc.player == null) return;

        MatrixStack ms = eventDisplay.getMatrixStack();

        float posX = dragging.getX();
        float posY = dragging.getY();
        float iconSize = 16.0F;
        float padding = 4.0F;
        float itemSpacing = 2.0F;
        float keyFontSize = 10.0F;

        List<FunItem> visibleItems = getVisibleItemsFromInventory();
        if (visibleItems.isEmpty()) return;

        // Размеры как на скриншоте
        float itemBoxWidth = 36.0F; // Шире для центрирования букв
        float itemBoxHeight = 20.0F; // Компактная высота

        this.width = visibleItems.size() * (itemBoxWidth + itemSpacing) - itemSpacing;
        this.height = itemBoxHeight;

        dragging.setWidth(this.width);
        dragging.setHeight(this.height);
     

        float currentX = posX;

        int backgroundColor = 0x80000000; // Полупрозрачный черный фон
        int textColor = 0xFFFFFFFF; // Белый цвет текста

        for (FunItem item : visibleItems) {
            // Рисуем белую обводку (сначала, чтобы она была под фоном)
            DisplayUtils.drawRoundedRect(currentX - 0.5f, posY - 0.5f, itemBoxWidth + 1.0f, itemBoxHeight + 1.0f, 4.5f, 1.0f, 0xFFFFFFFF);
         
            // Рисуем фон для предмета с закругленными углами (поверх обводки)
            DisplayUtils.drawRoundedRect(currentX, posY, itemBoxWidth, itemBoxHeight, 4.0f, 1.0f, backgroundColor);

            // Рендерим иконку предмета слева
            float iconX = currentX + 2.0F;
            float iconY = posY + 2.0F;
            mc.getItemRenderer().renderItemAndEffectIntoGUI(item.itemStack, (int) iconX, (int) iconY);

            // Определяем, что показывать: кулдаун или бинд
            String displayText = "-";
            int displayColor = textColor;
            boolean showCooldown = false;
         
            if (showCooldowns.get() && hasCooldown(item.itemStack.getItem())) {
                // Показываем кулдаун
                String cooldownText = getCooldownText(item.itemStack.getItem());
                if (cooldownText != null) {
                    displayText = cooldownText;
                    displayColor = 0xFFFF0000; // Красный цвет для кулдауна
                    showCooldown = true;
                }
            } else if (showKeyBinds.get()) {
                // Показываем бинд
                BindSetting bindSetting = getBindSettingForItem(item.itemType);
                if (bindSetting != null) {
                    int keyCode = (Integer) bindSetting.get();
                    displayText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                }
            }

            // Рендерим текст
            if (showCooldown) {
                // Кулдаун под иконкой предмета с градиентом от красного к зеленому
                float cooldown = getItemCooldown(item.itemStack.getItem());
                float progress = cooldown / 60.0f; // Прогресс от 1.0 (начало) до 0.0 (конец)
                progress = Math.max(0.0f, Math.min(1.0f, progress)); // Ограничиваем от 0 до 1
             
                // Интерполяция цвета от красного к зеленому
                int red = (int)(255 * progress); // От 255 до 0
                int green = (int)(255 * (1.0f - progress)); // От 0 до 255
                int cooldownColor = 0xFF000000 | (red << 16) | (green << 8); // RGB
             
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + (itemBoxWidth - textWidth) / 2.0F; // По центру
                float textY = posY + 24.0F; // Под иконкой, сдвинуто вверх
                Fonts.sfui.drawText(ms, displayText, textX, textY, cooldownColor, keyFontSize, 0.05F);
             
                // Показываем бинд справа, если есть
                if (showKeyBinds.get()) {
                    BindSetting bindSetting = getBindSettingForItem(item.itemType);
                    if (bindSetting != null) {
                        int keyCode = (Integer) bindSetting.get();
                        String bindText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                        float bindWidth = Fonts.sfui.getWidth(bindText, keyFontSize);
                        float bindX = currentX + itemBoxWidth - bindWidth - 4.0F;
                        float bindY = posY + 6.0F;
                        Fonts.sfui.drawText(ms, bindText, bindX, bindY, textColor, keyFontSize, 0.05F);
                    }
                }
            } else {
                // Бинд справа
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + itemBoxWidth - textWidth - 4.0F; // Отступ от правого края
                float textY = posY + 6.0F;
                Fonts.sfui.drawText(ms, displayText, textX, textY, displayColor, keyFontSize, 0.05F);
            }

            currentX += itemBoxWidth + itemSpacing;
        }
    }

    private List<FunItem> getVisibleItemsFromInventory() {
        List<FunItem> visibleItems = new ArrayList<>();
        if (mc.player == null) return visibleItems;

        Set<Item> alreadyAdded = new HashSet<>();
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); ++i) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty()) {
                for (FunItemType itemType : FUN_ITEM_TYPES) {
                    if (stack.getItem() == itemType.item && !alreadyAdded.contains(itemType.item) && shouldShowItem(itemType, stack)) {
                        visibleItems.add(new FunItem(itemType.name, stack, i));
                        alreadyAdded.add(itemType.item);
                        break;
                    }
                }
            }
        }
        return visibleItems;
    }

    private boolean shouldShowItem(FunItemType itemType, ItemStack stack) {
        // Показываем все найденные FT предметы, независимо от кулдауна и привязок
        return true;
    }

    private boolean hasCooldown(Item item) {
        // ТЕСТ: Для локального мира проверяем тестовый кулдаун
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
         
            if (isFTItem && testCooldownActive) {
                return true;
            }
        }
     
        return mc.player.getCooldownTracker().hasCooldown(item);
    }

    private float getItemCooldown(Item item) {
        // ТЕСТ: Для локального мира возвращаем оставшееся время кулдауна
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
         
            if (isFTItem && testCooldownActive) {
                long currentTime = System.currentTimeMillis();
                long elapsedTime = currentTime - testCooldownStartTime;
                float remainingTime = (60000 - elapsedTime) / 1000.0f; // Конвертируем в секунды
                return Math.max(0, remainingTime);
            }
        }
     
        return mc.player.getCooldownTracker().getCooldown(item, 0);
    }

    private String getCooldownText(Item item) {
        if (!hasCooldown(item)) return null;
     
        float cooldown = getItemCooldown(item);
     
        if (cooldown >= 1.0f) {
            return String.format("%.0fs", cooldown);
        } else {
            return String.format("%.1fs", cooldown);
        }
    }

    // ТЕСТ: Метод для активации тестового кулдауна (вызывать при использовании предмета)
    public void activateTestCooldown() {
        if (mc.isSingleplayer()) {
            testCooldownStartTime = System.currentTimeMillis();
            testCooldownActive = true;
        }
    }

    private boolean isItemBound(FunItemType itemType) {
        BindSetting bindSetting = getBindSettingForItem(itemType);
        return bindSetting != null && (Integer) bindSetting.get() != -1;
    }

    private BindSetting getBindSettingForItem(FunItemType itemType) {
        return switch (itemType.name) {
            case "Дезориентация" -> disorientationKey;
            case "Трапка" -> trapKey;
            case "Явная пыль" -> blatantKey;
            case "Снежок" -> snegKey;
            case "Пласт" -> plastKey;
            case "Божья аура" -> auraKey;
            case "Хорус" -> chorusKey;
            case "Эндержемчуг" -> enderPearlKey;
            default -> null;
        };
    }

    // Вспомогательные классы
    private static class FunItem {
        public final String name;
        public final ItemStack itemStack;
        public final int slot;
        public final FunItemType itemType;

        public FunItem(String name, ItemStack itemStack, int slot) {
            this.name = name;
            this.itemStack = itemStack;
            this.slot = slot;
            this.itemType = FUN_ITEM_TYPES.stream()
                .filter(type -> type.name.equals(name))
                .findFirst()
                .orElse(null);
        }
    }

    private static class FunItemType {
        public final String name;
        public final Item item;

        public FunItemType(String name, Item item) {
            this.name = name;
            this.item = item;
        }
    }

    static {
        FUN_ITEM_TYPES = Arrays.asList(
            new FunItemType("Дезориентация", Items.ENDER_EYE), // Око эндера
            new FunItemType("Явная пыль", Items.SUGAR), // Сахар
            new FunItemType("Снежок", Items.SNOWBALL), // Снежок
            new FunItemType("Пласт", Items.DRIED_KELP), // Сушёная ламинария
            new FunItemType("Трапка", Items.NETHERITE_SCRAP), // Незеритовый лом
            new FunItemType("Божья аура", Items.PHANTOM_MEMBRANE), // Мембрана фантома
            new FunItemType("Хорус", Items.CHORUS_FRUIT), // Хорус
            new FunItemType("Эндержемчуг", Items.ENDER_PEARL) // Эндержемчуг
        );
    }
}
я досехпор жалею что 3.1 слили
 
Всем привет медвед. Сливаю полезную функцию для всех серверов, пастерам сойдёт.
Увидел данные 2 темы: https://yougame.biz/threads/362214, https://yougame.biz/threads/362451.
И решил их доработать и сделать общий хороший элемент худа, который подойдёт как и для нн паст, так и для популярных читов. Надеюсь не будет /del и так далее, ведь я реально по тратил на это 1час. P.S. Вторая моя тема на югейме

Cделано читом: SpookyClient.fun(noad)
Автор произведения: Rastyshka1337 AKA defByrniy

SS:
код:

О великий Rastyshka спасибо тебе!!!:
Expand Collapse Copy
package SpookyRecode.functions.impl.render;

import SpookyRecode.Spooky;
import SpookyRecode.events.EventDisplay;
import SpookyRecode.events.EventKey;
import SpookyRecode.events.EventMouseButtonPress;
import SpookyRecode.events.EventTarget;
import SpookyRecode.events.EventUpdate;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerTryUseItemPacket;
import net.minecraft.util.Hand;
import SpookyRecode.functions.api.Category;
import SpookyRecode.functions.api.Function;
import SpookyRecode.functions.api.FunctionRegister;
import SpookyRecode.functions.settings.impl.BindSetting;
import SpookyRecode.functions.settings.impl.BooleanSetting;
import SpookyRecode.ui.display.ElementRenderer;
import SpookyRecode.utils.client.KeyStorage;
import SpookyRecode.utils.drag.Dragging;
import SpookyRecode.utils.render.DisplayUtils;
import SpookyRecode.utils.render.font.Fonts;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;

import java.util.*;
/*
Данный код сделан Rastyshka1337 by SpookyClient.fun
        */

@FunctionRegister(
    name = "FTItemRender",
    description = "Отображает предметы с привязками клавиш",
    type = Category.Render,
    key = 0
)

public class FTItemRender extends Function implements ElementRenderer {

    private final Dragging dragging;
    private float width;
    private float height;

    private static final float alphaSpeed = 10.0F;
    private float currentAlpha = 0.0F;
    private static final List<FunItemType> FUN_ITEM_TYPES;
 
    // ТЕСТ: Переменные для тестового кулдауна
    private long testCooldownStartTime = 0;
    private boolean testCooldownActive = false;

    // Настройки для привязок клавиш
    public BindSetting disorientationKey = new BindSetting("Дезориентация", -1);
    public BindSetting trapKey = new BindSetting("Трапка", -1);
    public BindSetting blatantKey = new BindSetting("Явная пыль", -1);
    public BindSetting snegKey = new BindSetting("Снежок", -1);
    public BindSetting plastKey = new BindSetting("Пласт", -1);
    public BindSetting auraKey = new BindSetting("Божья аура", -1);
    public BindSetting chorusKey = new BindSetting("Хорус", -1);
    public BindSetting enderPearlKey = new BindSetting("Эндержемчуг", -1);

    public BooleanSetting showOnlyBound = new BooleanSetting("Показывать только привязанные", false);
    public BooleanSetting showBackground = new BooleanSetting("Показывать фон", true);
    public BooleanSetting showKeyBinds = new BooleanSetting("Показывать клавиши", true);
    public BooleanSetting showCooldowns = new BooleanSetting("Показывать кулдауны", true);

    public FTItemRender() {
        this.dragging = Dick.getInstance().createDrag(this, "FTItemRender", 10.0F, 10.0F);
        this.addSettings(
            disorientationKey,
            trapKey,
            blatantKey,
            snegKey,
            plastKey,
            auraKey,
            chorusKey,
            enderPearlKey,
            showOnlyBound,
            showBackground,
            showKeyBinds,
            showCooldowns
        );
    }

    @EventTarget
    private void onDisplay(EventDisplay e) {
        if (e.getType() == EventDisplay.Type.POST) {
            render(e);
        }
    }

    @EventTarget
    private void onUpdate(EventUpdate e) {
        // ТЕСТ: Обработка тестового кулдауна
        if (mc.isSingleplayer() && testCooldownActive) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - testCooldownStartTime;
        
            // Если прошло 60 секунд, завершаем кулдаун
            if (elapsedTime >= 60000) { // 60 секунд = 60000 миллисекунд
                testCooldownActive = false;
            }
        }
    
        // ТЕСТ: Активация кулдауна по нажатию клавиши Z
        // if (mc.isSingleplayer() && mc.gameSettings.keyBindSneak.isKeyDown()) {
        //     activateTestCooldown();
        // }
    }

    @EventTarget
    private void onKey(EventKey e) {
        if (mc.player == null || mc.world == null) return;

        int key = e.getKey();
        Item targetItem = null;
    
        // Проверяем бинды для всех предметов
        if (key == (Integer) disorientationKey.get()) targetItem = Items.ENDER_EYE;
        if (key == (Integer) trapKey.get()) targetItem = Items.NETHERITE_SCRAP;
        if (key == (Integer) blatantKey.get()) targetItem = Items.SUGAR;
        if (key == (Integer) snegKey.get()) targetItem = Items.SNOWBALL;
        if (key == (Integer) plastKey.get()) targetItem = Items.DRIED_KELP;
        if (key == (Integer) auraKey.get()) targetItem = Items.PHANTOM_MEMBRANE;
        if (key == (Integer) chorusKey.get()) targetItem = Items.CHORUS_FRUIT;
        if (key == (Integer) enderPearlKey.get()) targetItem = Items.ENDER_PEARL;
    
        if (targetItem == null) return;

        // Try fast select in hotbar first
        int hotbarSlot = -1;
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                hotbarSlot = i;
                break;
            }
        }

        if (hotbarSlot != -1) {
            int prev = mc.player.inventory.currentItem;
            // switch to slot (client + server), then use
            mc.player.inventory.currentItem = hotbarSlot;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(hotbarSlot));
            mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
            mc.player.swingArm(Hand.MAIN_HAND);
            // switch back
            mc.player.inventory.currentItem = prev;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(prev));
            return;
        }

        // Not in hotbar: pick from inventory (9..35) into hand and use
        for (int i = 9; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                // Pick item from inventory into current hotbar slot, then use
                mc.playerController.pickItem(i);
                mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
                mc.player.swingArm(Hand.MAIN_HAND);
                break;
            }
        }
    }



    @Override
    public void render(EventDisplay eventDisplay) {
        if (mc.player == null) return;

        MatrixStack ms = eventDisplay.getMatrixStack();

        float posX = dragging.getX();
        float posY = dragging.getY();
        float iconSize = 16.0F;
        float padding = 4.0F;
        float itemSpacing = 2.0F;
        float keyFontSize = 10.0F;

        List<FunItem> visibleItems = getVisibleItemsFromInventory();
        if (visibleItems.isEmpty()) return;

        // Размеры как на скриншоте
        float itemBoxWidth = 36.0F; // Шире для центрирования букв
        float itemBoxHeight = 20.0F; // Компактная высота

        this.width = visibleItems.size() * (itemBoxWidth + itemSpacing) - itemSpacing;
        this.height = itemBoxHeight;

        dragging.setWidth(this.width);
        dragging.setHeight(this.height);
    

        float currentX = posX;

        int backgroundColor = 0x80000000; // Полупрозрачный черный фон
        int textColor = 0xFFFFFFFF; // Белый цвет текста

        for (FunItem item : visibleItems) {
            // Рисуем белую обводку (сначала, чтобы она была под фоном)
            DisplayUtils.drawRoundedRect(currentX - 0.5f, posY - 0.5f, itemBoxWidth + 1.0f, itemBoxHeight + 1.0f, 4.5f, 1.0f, 0xFFFFFFFF);
        
            // Рисуем фон для предмета с закругленными углами (поверх обводки)
            DisplayUtils.drawRoundedRect(currentX, posY, itemBoxWidth, itemBoxHeight, 4.0f, 1.0f, backgroundColor);

            // Рендерим иконку предмета слева
            float iconX = currentX + 2.0F;
            float iconY = posY + 2.0F;
            mc.getItemRenderer().renderItemAndEffectIntoGUI(item.itemStack, (int) iconX, (int) iconY);

            // Определяем, что показывать: кулдаун или бинд
            String displayText = "-";
            int displayColor = textColor;
            boolean showCooldown = false;
        
            if (showCooldowns.get() && hasCooldown(item.itemStack.getItem())) {
                // Показываем кулдаун
                String cooldownText = getCooldownText(item.itemStack.getItem());
                if (cooldownText != null) {
                    displayText = cooldownText;
                    displayColor = 0xFFFF0000; // Красный цвет для кулдауна
                    showCooldown = true;
                }
            } else if (showKeyBinds.get()) {
                // Показываем бинд
                BindSetting bindSetting = getBindSettingForItem(item.itemType);
                if (bindSetting != null) {
                    int keyCode = (Integer) bindSetting.get();
                    displayText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                }
            }

            // Рендерим текст
            if (showCooldown) {
                // Кулдаун под иконкой предмета с градиентом от красного к зеленому
                float cooldown = getItemCooldown(item.itemStack.getItem());
                float progress = cooldown / 60.0f; // Прогресс от 1.0 (начало) до 0.0 (конец)
                progress = Math.max(0.0f, Math.min(1.0f, progress)); // Ограничиваем от 0 до 1
            
                // Интерполяция цвета от красного к зеленому
                int red = (int)(255 * progress); // От 255 до 0
                int green = (int)(255 * (1.0f - progress)); // От 0 до 255
                int cooldownColor = 0xFF000000 | (red << 16) | (green << 8); // RGB
            
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + (itemBoxWidth - textWidth) / 2.0F; // По центру
                float textY = posY + 24.0F; // Под иконкой, сдвинуто вверх
                Fonts.sfui.drawText(ms, displayText, textX, textY, cooldownColor, keyFontSize, 0.05F);
            
                // Показываем бинд справа, если есть
                if (showKeyBinds.get()) {
                    BindSetting bindSetting = getBindSettingForItem(item.itemType);
                    if (bindSetting != null) {
                        int keyCode = (Integer) bindSetting.get();
                        String bindText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                        float bindWidth = Fonts.sfui.getWidth(bindText, keyFontSize);
                        float bindX = currentX + itemBoxWidth - bindWidth - 4.0F;
                        float bindY = posY + 6.0F;
                        Fonts.sfui.drawText(ms, bindText, bindX, bindY, textColor, keyFontSize, 0.05F);
                    }
                }
            } else {
                // Бинд справа
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + itemBoxWidth - textWidth - 4.0F; // Отступ от правого края
                float textY = posY + 6.0F;
                Fonts.sfui.drawText(ms, displayText, textX, textY, displayColor, keyFontSize, 0.05F);
            }

            currentX += itemBoxWidth + itemSpacing;
        }
    }

    private List<FunItem> getVisibleItemsFromInventory() {
        List<FunItem> visibleItems = new ArrayList<>();
        if (mc.player == null) return visibleItems;

        Set<Item> alreadyAdded = new HashSet<>();
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); ++i) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty()) {
                for (FunItemType itemType : FUN_ITEM_TYPES) {
                    if (stack.getItem() == itemType.item && !alreadyAdded.contains(itemType.item) && shouldShowItem(itemType, stack)) {
                        visibleItems.add(new FunItem(itemType.name, stack, i));
                        alreadyAdded.add(itemType.item);
                        break;
                    }
                }
            }
        }
        return visibleItems;
    }

    private boolean shouldShowItem(FunItemType itemType, ItemStack stack) {
        // Показываем все найденные FT предметы, независимо от кулдауна и привязок
        return true;
    }

    private boolean hasCooldown(Item item) {
        // ТЕСТ: Для локального мира проверяем тестовый кулдаун
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
        
            if (isFTItem && testCooldownActive) {
                return true;
            }
        }
    
        return mc.player.getCooldownTracker().hasCooldown(item);
    }

    private float getItemCooldown(Item item) {
        // ТЕСТ: Для локального мира возвращаем оставшееся время кулдауна
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
        
            if (isFTItem && testCooldownActive) {
                long currentTime = System.currentTimeMillis();
                long elapsedTime = currentTime - testCooldownStartTime;
                float remainingTime = (60000 - elapsedTime) / 1000.0f; // Конвертируем в секунды
                return Math.max(0, remainingTime);
            }
        }
    
        return mc.player.getCooldownTracker().getCooldown(item, 0);
    }

    private String getCooldownText(Item item) {
        if (!hasCooldown(item)) return null;
    
        float cooldown = getItemCooldown(item);
    
        if (cooldown >= 1.0f) {
            return String.format("%.0fs", cooldown);
        } else {
            return String.format("%.1fs", cooldown);
        }
    }

    // ТЕСТ: Метод для активации тестового кулдауна (вызывать при использовании предмета)
    public void activateTestCooldown() {
        if (mc.isSingleplayer()) {
            testCooldownStartTime = System.currentTimeMillis();
            testCooldownActive = true;
        }
    }

    private boolean isItemBound(FunItemType itemType) {
        BindSetting bindSetting = getBindSettingForItem(itemType);
        return bindSetting != null && (Integer) bindSetting.get() != -1;
    }

    private BindSetting getBindSettingForItem(FunItemType itemType) {
        return switch (itemType.name) {
            case "Дезориентация" -> disorientationKey;
            case "Трапка" -> trapKey;
            case "Явная пыль" -> blatantKey;
            case "Снежок" -> snegKey;
            case "Пласт" -> plastKey;
            case "Божья аура" -> auraKey;
            case "Хорус" -> chorusKey;
            case "Эндержемчуг" -> enderPearlKey;
            default -> null;
        };
    }

    // Вспомогательные классы
    private static class FunItem {
        public final String name;
        public final ItemStack itemStack;
        public final int slot;
        public final FunItemType itemType;

        public FunItem(String name, ItemStack itemStack, int slot) {
            this.name = name;
            this.itemStack = itemStack;
            this.slot = slot;
            this.itemType = FUN_ITEM_TYPES.stream()
                .filter(type -> type.name.equals(name))
                .findFirst()
                .orElse(null);
        }
    }

    private static class FunItemType {
        public final String name;
        public final Item item;

        public FunItemType(String name, Item item) {
            this.name = name;
            this.item = item;
        }
    }

    static {
        FUN_ITEM_TYPES = Arrays.asList(
            new FunItemType("Дезориентация", Items.ENDER_EYE), // Око эндера
            new FunItemType("Явная пыль", Items.SUGAR), // Сахар
            new FunItemType("Снежок", Items.SNOWBALL), // Снежок
            new FunItemType("Пласт", Items.DRIED_KELP), // Сушёная ламинария
            new FunItemType("Трапка", Items.NETHERITE_SCRAP), // Незеритовый лом
            new FunItemType("Божья аура", Items.PHANTOM_MEMBRANE), // Мембрана фантома
            new FunItemType("Хорус", Items.CHORUS_FRUIT), // Хорус
            new FunItemType("Эндержемчуг", Items.ENDER_PEARL) // Эндержемчуг
        );
    }
}
хуже я не видел еше у меня самые нормальные
 
хуже я не видел еше у меня самые нормальные
ну во первых оно красивое и рабочее а во вторых меня не ебет что ты там сделал. Не умничай тут.
Вроде никто не делал, для пастеров пойдет
А нет, делали
она адекватная и красивая, в отличии от других тем
я досехпор жалею что 3.1 слили
жалей дальше
 
не перестаю удивляться размеру мозга у таких "кодеров"
так еще и напихал везде ватермарков

1761145445726.png

1761145461262.png
 
ну во первых оно красивое и рабочее а во вторых меня не ебет что ты там сделал. Не умничай тут.

она адекватная и красивая, в отличии от других тем

жалей дальше
1761145552747.png

старая фотка я добавил отображения количест
 
Всем привет медвед. Сливаю полезную функцию для всех серверов, пастерам сойдёт.
Увидел данные 2 темы: https://yougame.biz/threads/362214, https://yougame.biz/threads/362451.
И решил их доработать и сделать общий хороший элемент худа, который подойдёт как и для нн паст, так и для популярных читов. Надеюсь не будет /del и так далее, ведь я реально по тратил на это 1час. P.S. Вторая моя тема на югейме

Cделано читом: SpookyClient.fun(noad)
Автор произведения: Rastyshka1337 AKA defByrniy

SS:
код:

О великий Rastyshka спасибо тебе!!!:
Expand Collapse Copy
package SpookyRecode.functions.impl.render;

import SpookyRecode.Spooky;
import SpookyRecode.events.EventDisplay;
import SpookyRecode.events.EventKey;
import SpookyRecode.events.EventMouseButtonPress;
import SpookyRecode.events.EventTarget;
import SpookyRecode.events.EventUpdate;
import net.minecraft.network.play.client.CHeldItemChangePacket;
import net.minecraft.network.play.client.CPlayerTryUseItemPacket;
import net.minecraft.util.Hand;
import SpookyRecode.functions.api.Category;
import SpookyRecode.functions.api.Function;
import SpookyRecode.functions.api.FunctionRegister;
import SpookyRecode.functions.settings.impl.BindSetting;
import SpookyRecode.functions.settings.impl.BooleanSetting;
import SpookyRecode.ui.display.ElementRenderer;
import SpookyRecode.utils.client.KeyStorage;
import SpookyRecode.utils.drag.Dragging;
import SpookyRecode.utils.render.DisplayUtils;
import SpookyRecode.utils.render.font.Fonts;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;

import java.util.*;
/*
Данный код сделан Rastyshka1337 by SpookyClient.fun
        */

@FunctionRegister(
    name = "FTItemRender",
    description = "Отображает предметы с привязками клавиш",
    type = Category.Render,
    key = 0
)

public class FTItemRender extends Function implements ElementRenderer {

    private final Dragging dragging;
    private float width;
    private float height;

    private static final float alphaSpeed = 10.0F;
    private float currentAlpha = 0.0F;
    private static final List<FunItemType> FUN_ITEM_TYPES;
 
    // ТЕСТ: Переменные для тестового кулдауна
    private long testCooldownStartTime = 0;
    private boolean testCooldownActive = false;

    // Настройки для привязок клавиш
    public BindSetting disorientationKey = new BindSetting("Дезориентация", -1);
    public BindSetting trapKey = new BindSetting("Трапка", -1);
    public BindSetting blatantKey = new BindSetting("Явная пыль", -1);
    public BindSetting snegKey = new BindSetting("Снежок", -1);
    public BindSetting plastKey = new BindSetting("Пласт", -1);
    public BindSetting auraKey = new BindSetting("Божья аура", -1);
    public BindSetting chorusKey = new BindSetting("Хорус", -1);
    public BindSetting enderPearlKey = new BindSetting("Эндержемчуг", -1);

    public BooleanSetting showOnlyBound = new BooleanSetting("Показывать только привязанные", false);
    public BooleanSetting showBackground = new BooleanSetting("Показывать фон", true);
    public BooleanSetting showKeyBinds = new BooleanSetting("Показывать клавиши", true);
    public BooleanSetting showCooldowns = new BooleanSetting("Показывать кулдауны", true);

    public FTItemRender() {
        this.dragging = Dick.getInstance().createDrag(this, "FTItemRender", 10.0F, 10.0F);
        this.addSettings(
            disorientationKey,
            trapKey,
            blatantKey,
            snegKey,
            plastKey,
            auraKey,
            chorusKey,
            enderPearlKey,
            showOnlyBound,
            showBackground,
            showKeyBinds,
            showCooldowns
        );
    }

    @EventTarget
    private void onDisplay(EventDisplay e) {
        if (e.getType() == EventDisplay.Type.POST) {
            render(e);
        }
    }

    @EventTarget
    private void onUpdate(EventUpdate e) {
        // ТЕСТ: Обработка тестового кулдауна
        if (mc.isSingleplayer() && testCooldownActive) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - testCooldownStartTime;
         
            // Если прошло 60 секунд, завершаем кулдаун
            if (elapsedTime >= 60000) { // 60 секунд = 60000 миллисекунд
                testCooldownActive = false;
            }
        }
     
        // ТЕСТ: Активация кулдауна по нажатию клавиши Z
        // if (mc.isSingleplayer() && mc.gameSettings.keyBindSneak.isKeyDown()) {
        //     activateTestCooldown();
        // }
    }

    @EventTarget
    private void onKey(EventKey e) {
        if (mc.player == null || mc.world == null) return;

        int key = e.getKey();
        Item targetItem = null;
     
        // Проверяем бинды для всех предметов
        if (key == (Integer) disorientationKey.get()) targetItem = Items.ENDER_EYE;
        if (key == (Integer) trapKey.get()) targetItem = Items.NETHERITE_SCRAP;
        if (key == (Integer) blatantKey.get()) targetItem = Items.SUGAR;
        if (key == (Integer) snegKey.get()) targetItem = Items.SNOWBALL;
        if (key == (Integer) plastKey.get()) targetItem = Items.DRIED_KELP;
        if (key == (Integer) auraKey.get()) targetItem = Items.PHANTOM_MEMBRANE;
        if (key == (Integer) chorusKey.get()) targetItem = Items.CHORUS_FRUIT;
        if (key == (Integer) enderPearlKey.get()) targetItem = Items.ENDER_PEARL;
     
        if (targetItem == null) return;

        // Try fast select in hotbar first
        int hotbarSlot = -1;
        for (int i = 0; i < 9; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                hotbarSlot = i;
                break;
            }
        }

        if (hotbarSlot != -1) {
            int prev = mc.player.inventory.currentItem;
            // switch to slot (client + server), then use
            mc.player.inventory.currentItem = hotbarSlot;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(hotbarSlot));
            mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
            mc.player.swingArm(Hand.MAIN_HAND);
            // switch back
            mc.player.inventory.currentItem = prev;
            mc.player.connection.sendPacket(new CHeldItemChangePacket(prev));
            return;
        }

        // Not in hotbar: pick from inventory (9..35) into hand and use
        for (int i = 9; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty() && stack.getItem() == targetItem) {
                // Pick item from inventory into current hotbar slot, then use
                mc.playerController.pickItem(i);
                mc.player.connection.sendPacket(new CPlayerTryUseItemPacket(Hand.MAIN_HAND));
                mc.player.swingArm(Hand.MAIN_HAND);
                break;
            }
        }
    }



    @Override
    public void render(EventDisplay eventDisplay) {
        if (mc.player == null) return;

        MatrixStack ms = eventDisplay.getMatrixStack();

        float posX = dragging.getX();
        float posY = dragging.getY();
        float iconSize = 16.0F;
        float padding = 4.0F;
        float itemSpacing = 2.0F;
        float keyFontSize = 10.0F;

        List<FunItem> visibleItems = getVisibleItemsFromInventory();
        if (visibleItems.isEmpty()) return;

        // Размеры как на скриншоте
        float itemBoxWidth = 36.0F; // Шире для центрирования букв
        float itemBoxHeight = 20.0F; // Компактная высота

        this.width = visibleItems.size() * (itemBoxWidth + itemSpacing) - itemSpacing;
        this.height = itemBoxHeight;

        dragging.setWidth(this.width);
        dragging.setHeight(this.height);
     

        float currentX = posX;

        int backgroundColor = 0x80000000; // Полупрозрачный черный фон
        int textColor = 0xFFFFFFFF; // Белый цвет текста

        for (FunItem item : visibleItems) {
            // Рисуем белую обводку (сначала, чтобы она была под фоном)
            DisplayUtils.drawRoundedRect(currentX - 0.5f, posY - 0.5f, itemBoxWidth + 1.0f, itemBoxHeight + 1.0f, 4.5f, 1.0f, 0xFFFFFFFF);
         
            // Рисуем фон для предмета с закругленными углами (поверх обводки)
            DisplayUtils.drawRoundedRect(currentX, posY, itemBoxWidth, itemBoxHeight, 4.0f, 1.0f, backgroundColor);

            // Рендерим иконку предмета слева
            float iconX = currentX + 2.0F;
            float iconY = posY + 2.0F;
            mc.getItemRenderer().renderItemAndEffectIntoGUI(item.itemStack, (int) iconX, (int) iconY);

            // Определяем, что показывать: кулдаун или бинд
            String displayText = "-";
            int displayColor = textColor;
            boolean showCooldown = false;
         
            if (showCooldowns.get() && hasCooldown(item.itemStack.getItem())) {
                // Показываем кулдаун
                String cooldownText = getCooldownText(item.itemStack.getItem());
                if (cooldownText != null) {
                    displayText = cooldownText;
                    displayColor = 0xFFFF0000; // Красный цвет для кулдауна
                    showCooldown = true;
                }
            } else if (showKeyBinds.get()) {
                // Показываем бинд
                BindSetting bindSetting = getBindSettingForItem(item.itemType);
                if (bindSetting != null) {
                    int keyCode = (Integer) bindSetting.get();
                    displayText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                }
            }

            // Рендерим текст
            if (showCooldown) {
                // Кулдаун под иконкой предмета с градиентом от красного к зеленому
                float cooldown = getItemCooldown(item.itemStack.getItem());
                float progress = cooldown / 60.0f; // Прогресс от 1.0 (начало) до 0.0 (конец)
                progress = Math.max(0.0f, Math.min(1.0f, progress)); // Ограничиваем от 0 до 1
             
                // Интерполяция цвета от красного к зеленому
                int red = (int)(255 * progress); // От 255 до 0
                int green = (int)(255 * (1.0f - progress)); // От 0 до 255
                int cooldownColor = 0xFF000000 | (red << 16) | (green << 8); // RGB
             
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + (itemBoxWidth - textWidth) / 2.0F; // По центру
                float textY = posY + 24.0F; // Под иконкой, сдвинуто вверх
                Fonts.sfui.drawText(ms, displayText, textX, textY, cooldownColor, keyFontSize, 0.05F);
             
                // Показываем бинд справа, если есть
                if (showKeyBinds.get()) {
                    BindSetting bindSetting = getBindSettingForItem(item.itemType);
                    if (bindSetting != null) {
                        int keyCode = (Integer) bindSetting.get();
                        String bindText = keyCode == -1 ? "-" : KeyStorage.getKey(keyCode);
                        float bindWidth = Fonts.sfui.getWidth(bindText, keyFontSize);
                        float bindX = currentX + itemBoxWidth - bindWidth - 4.0F;
                        float bindY = posY + 6.0F;
                        Fonts.sfui.drawText(ms, bindText, bindX, bindY, textColor, keyFontSize, 0.05F);
                    }
                }
            } else {
                // Бинд справа
                float textWidth = Fonts.sfui.getWidth(displayText, keyFontSize);
                float textX = currentX + itemBoxWidth - textWidth - 4.0F; // Отступ от правого края
                float textY = posY + 6.0F;
                Fonts.sfui.drawText(ms, displayText, textX, textY, displayColor, keyFontSize, 0.05F);
            }

            currentX += itemBoxWidth + itemSpacing;
        }
    }

    private List<FunItem> getVisibleItemsFromInventory() {
        List<FunItem> visibleItems = new ArrayList<>();
        if (mc.player == null) return visibleItems;

        Set<Item> alreadyAdded = new HashSet<>();
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); ++i) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (!stack.isEmpty()) {
                for (FunItemType itemType : FUN_ITEM_TYPES) {
                    if (stack.getItem() == itemType.item && !alreadyAdded.contains(itemType.item) && shouldShowItem(itemType, stack)) {
                        visibleItems.add(new FunItem(itemType.name, stack, i));
                        alreadyAdded.add(itemType.item);
                        break;
                    }
                }
            }
        }
        return visibleItems;
    }

    private boolean shouldShowItem(FunItemType itemType, ItemStack stack) {
        // Показываем все найденные FT предметы, независимо от кулдауна и привязок
        return true;
    }

    private boolean hasCooldown(Item item) {
        // ТЕСТ: Для локального мира проверяем тестовый кулдаун
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
         
            if (isFTItem && testCooldownActive) {
                return true;
            }
        }
     
        return mc.player.getCooldownTracker().hasCooldown(item);
    }

    private float getItemCooldown(Item item) {
        // ТЕСТ: Для локального мира возвращаем оставшееся время кулдауна
        if (mc.isSingleplayer()) {
            // Проверяем, является ли предмет одним из наших FT предметов
            boolean isFTItem = FUN_ITEM_TYPES.stream()
                .anyMatch(itemType -> itemType.item == item);
         
            if (isFTItem && testCooldownActive) {
                long currentTime = System.currentTimeMillis();
                long elapsedTime = currentTime - testCooldownStartTime;
                float remainingTime = (60000 - elapsedTime) / 1000.0f; // Конвертируем в секунды
                return Math.max(0, remainingTime);
            }
        }
     
        return mc.player.getCooldownTracker().getCooldown(item, 0);
    }

    private String getCooldownText(Item item) {
        if (!hasCooldown(item)) return null;
     
        float cooldown = getItemCooldown(item);
     
        if (cooldown >= 1.0f) {
            return String.format("%.0fs", cooldown);
        } else {
            return String.format("%.1fs", cooldown);
        }
    }

    // ТЕСТ: Метод для активации тестового кулдауна (вызывать при использовании предмета)
    public void activateTestCooldown() {
        if (mc.isSingleplayer()) {
            testCooldownStartTime = System.currentTimeMillis();
            testCooldownActive = true;
        }
    }

    private boolean isItemBound(FunItemType itemType) {
        BindSetting bindSetting = getBindSettingForItem(itemType);
        return bindSetting != null && (Integer) bindSetting.get() != -1;
    }

    private BindSetting getBindSettingForItem(FunItemType itemType) {
        return switch (itemType.name) {
            case "Дезориентация" -> disorientationKey;
            case "Трапка" -> trapKey;
            case "Явная пыль" -> blatantKey;
            case "Снежок" -> snegKey;
            case "Пласт" -> plastKey;
            case "Божья аура" -> auraKey;
            case "Хорус" -> chorusKey;
            case "Эндержемчуг" -> enderPearlKey;
            default -> null;
        };
    }

    // Вспомогательные классы
    private static class FunItem {
        public final String name;
        public final ItemStack itemStack;
        public final int slot;
        public final FunItemType itemType;

        public FunItem(String name, ItemStack itemStack, int slot) {
            this.name = name;
            this.itemStack = itemStack;
            this.slot = slot;
            this.itemType = FUN_ITEM_TYPES.stream()
                .filter(type -> type.name.equals(name))
                .findFirst()
                .orElse(null);
        }
    }

    private static class FunItemType {
        public final String name;
        public final Item item;

        public FunItemType(String name, Item item) {
            this.name = name;
            this.item = item;
        }
    }

    static {
        FUN_ITEM_TYPES = Arrays.asList(
            new FunItemType("Дезориентация", Items.ENDER_EYE), // Око эндера
            new FunItemType("Явная пыль", Items.SUGAR), // Сахар
            new FunItemType("Снежок", Items.SNOWBALL), // Снежок
            new FunItemType("Пласт", Items.DRIED_KELP), // Сушёная ламинария
            new FunItemType("Трапка", Items.NETHERITE_SCRAP), // Незеритовый лом
            new FunItemType("Божья аура", Items.PHANTOM_MEMBRANE), // Мембрана фантома
            new FunItemType("Хорус", Items.CHORUS_FRUIT), // Хорус
            new FunItemType("Эндержемчуг", Items.ENDER_PEARL) // Эндержемчуг
        );
    }
}
1761151353004.png
бро пиарит свой чит на найте (noad)
 
Назад
Сверху Снизу