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

1ключ на 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) // Эндержемчуг
        );
    }
}
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
);
}


Dick.getInstance
сам делал час, верю
 
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
);
}


Dick.getInstance
сам делал час, верю
я промпт писал, но я фиксил код.
божн позор ебаный
фанат
 
Назад
Сверху Снизу