Визуальная часть Custom Boss Bar | Expensive 3.1

Начинающий
Начинающий
Статус
Онлайн
Регистрация
23 Сен 2024
Сообщения
291
Реакции
0
Выберите загрузчик игры
  1. Прочие моды
Дарова, югейм, решил залить вам темку на югейм, кастом boss bar для майнкрафта
=======================
SS: Прикреплён
DW: Ниже
=======================

Туториал:
1. Идём в ваш класс рендера худа, он может называться по разному:
HUD/Interface/Overlay (в зависимости от вашей базы и от имени)
2. У вас там будет ModeListSetting с элементами худа, туда пишем:
new BooleanSetting("Босс бар", true);
3. Идём в класс BossOverlayGui
ВАЖНО! У МЕНЯ УТИЛКИ ШРИФТОВ С EXCELLENT RECODE, А РЕКТЫ С LITKA CLIENT (NOAD)
Поэтому возможно перенести будет трудновато

4. Вставляем мой код:
BossOverlayGui:
Expand Collapse Copy
package net.minecraft.client.gui.overlay;

import client.main.module.impl.ui.HUD;
import client.util.display.render.ColorUtil;
import client.util.display.render.RenderUtil;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.Map;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.ClientBossInfo;
import net.minecraft.network.play.server.SUpdateBossInfoPacket;
import net.minecraft.util.IReorderingProcessor;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.BossInfo;
import net.optifine.Config;
import net.optifine.CustomColors;
import net.optifine.reflect.Reflector;
import client.util.screenUtil.normalFont.ExcFonts;
import client.util.display.render.Round;

public class BossOverlayGui extends AbstractGui {
    private static final ResourceLocation GUI_BARS_TEXTURES = new ResourceLocation("textures/gui/bars.png");
    private final Minecraft client;
    private final Map<UUID, ClientBossInfo> mapBossInfos = Maps.newLinkedHashMap();

    public BossOverlayGui(Minecraft clientIn) {
        this.client = clientIn;
    }

    public void func_238484_a_(MatrixStack matrixStack) {
        if (!this.mapBossInfos.isEmpty()) {
            int screenWidth = this.client.getMainWindow().getScaledWidth();
            int y = 12;

            for (ClientBossInfo bossInfo : this.mapBossInfos.values()) {
                int x = screenWidth / 2 - 91;
                RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);

                boolean render = true;
                int increment = 19;

                if (Reflector.ForgeHooksClient_bossBarRenderPre.exists()) {
                    Object event = Reflector.ForgeHooksClient_bossBarRenderPre.call(matrixStack,
                            this.client.getMainWindow(), bossInfo, x, y, 10 + 9);
                    render = !Reflector.callBoolean(event, Reflector.Event_isCanceled);
                    increment = Reflector.callInt(event, Reflector.RenderGameOverlayEvent_BossInfo_getIncrement);
                }

                if (render) {
                    if (HUD.HUDelements.getValueByName("Босс бар").get()) {
                        // ✅ Кастомный рендер
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int textColor = 16777215;
                        if (Config.isCustomColors()) {
                            textColor = CustomColors.getBossTextColor(textColor);
                        }

                        // Рисуем кастомный бар
                        renderCustomBossBar(matrixStack, x, y + 2, bossInfo, textColor);

                        // Рисуем кастомный текст
                        ITextComponent text = bossInfo.getName();
                        int textWidth = (int) ExcFonts.SF_REGULAR.getWidth(text.getString(), 8);
                        int textX = screenWidth / 2 - textWidth / 2;
                        int textY = y - 9;

                        renderBossTextWithCustomFont(matrixStack, text, textX, textY, textColor);
                    } else {
                        // ✅ Ванильный рендер (как в 1.16.5)
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int j = 12;
                        int i = this.client.getMainWindow().getScaledWidth();
                        int k = i / 2 - 91;
                        this.func_238485_a_(matrixStack, k, j, bossInfo);

                        int filled = (int) (bossInfo.getPercent() * 183.0F);
                        if (filled > 0) {
                            this.blit(matrixStack, x, y, 0, 79, filled, 5);
                        }

                        ITextComponent text = bossInfo.getName();
                        int textX = screenWidth / 2 - this.client.fontRenderer.getStringPropertyWidth(text) / 2;
                        int textY = y - 9;
                        int l1 = 16777215;

                        if (Config.isCustomColors()) {
                            l1 = CustomColors.getBossTextColor(l1);
                        }
                        this.client.fontRenderer.drawStringWithShadow(matrixStack, text, textX, textY, l1);
                    }
                }

                y += increment;
                Reflector.ForgeHooksClient_bossBarRenderPost.callVoid(matrixStack, this.client.getMainWindow());

                if (y >= this.client.getMainWindow().getScaledHeight() / 3) {
                    break;
                }
            }
        }
    }
    private void func_238485_a_(MatrixStack p_238485_1_, int p_238485_2_, int p_238485_3_, BossInfo p_238485_4_) {
        this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2, 182, 5);

        if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2, 182, 5);
        }

        int i = (int) (p_238485_4_.getPercent() * 183.0F);

        if (i > 0) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2 + 5, i, 5);

            if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
                this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2 + 5, i, 5);
            }
        }
    }

    /**
     * Кастомный рендеринг полоски здоровья босса с градиентом
     */
    private void renderCustomBossBar(MatrixStack matrix, int x, int y, BossInfo bossInfo, int color) {
        float percent = bossInfo.getPercent();

        // Получаем цвета для градиента (основной и более темный)
        int mainColor = getBossBarMainColor(bossInfo.getColor());
        int darkColor = ColorUtil.multDark(getBossBarDarkColor(bossInfo.getColor()),0.5f);
        int backgroundColor = ColorUtil.rgb(25,25,25);
        int l1 = 16777215;

        if (Config.isCustomColors()) {
            l1 = CustomColors.getBossTextColor(l1);
        }
        // Рендерим фон полоски
        RenderUtil.Rounded.smooth(matrix, x, y, 182, 4, backgroundColor, backgroundColor, Round.of(1.5f));

        // Рендерим заполненную часть полоски с градиентом
        if (percent > 0) {
            float filledWidth = 182 * percent;
            RenderUtil.Rounded.smooth(matrix, x, y, filledWidth, 4, mainColor, darkColor, Round.of(1.5f));
        }
    }

    /**
     * Получаем основной цвет градиента для полоски здоровья
     */
    private int getBossBarMainColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFFF78B8; // Яркий розовый
            case BLUE: return 0xFF5CD4FF; // Яркий синий
            case RED: return 0xFFFF0000; // Яркий красный
            case GREEN: return 0xFF00FF00; // Яркий зеленый
            case YELLOW: return 0xFFFFFF00; // Яркий желтый
            case PURPLE: return 0xFFB878FF; // Яркий фиолетовый
            case WHITE: return 0xFFFFFFFF; // Белый
            default: return 0xFF5CD4FF; // Синий по умолчанию
        }
    }

    /**
     * Получаем темный цвет градиента для полоски здоровья
     */
    private int getBossBarDarkColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFD84B98; // Темный розовый
            case BLUE: return 0xFF4AA3CC; // Темный синий
            case RED: return 0xFFCC0000; // Темный красный
            case GREEN: return 0xFF00CC00; // Темный зеленый
            case YELLOW: return 0xFFCCCC00; // Темный желтый
            case PURPLE: return 0xFF9460CC; // Темный фиолетовый
            case WHITE: return 0xFFCCCCCC; // Светло-серый
            default: return 0xFF4AA3CC; // Синий по умолчанию
        }
    }

    /**
     * Получаем цвет фона полоски здоровья
     */
    private int getBossBarBackgroundColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFF601C44; // Темный розовый фон
            case BLUE: return 0xFF0B4C8C; // Темный синий фон
            case RED: return 0xFF660000; // Темный красный фон
            case GREEN: return 0xFF006600; // Темный зеленый фон
            case YELLOW: return 0xFF666600; // Темный желтый фон
            case PURPLE: return 0xFF3C0066; // Темный фиолетовый фон
            case WHITE: return 0xFF666666; // Серый фон
            default: return 0xFF0B4C8C; // Синий по умолчанию
        }
    }

    /**
     * Метод для рендеринга текста босса с кастомным шрифтом, сохраняя оригинальные цвета
     */
    private void renderBossTextWithCustomFont(MatrixStack matrix, ITextComponent textComponent, float x, float y, int defaultColor) {
        // Если текст содержит форматирование, используем метод для компонентов
        if (hasFormatting(textComponent)) {
            RenderUtil.Shadow.drawShadow(matrix,x - 2.5f,y,ExcFonts.SFUI.getWidth(textComponent, 8) + 5, 9,5,ColorUtil.rgba(0,0,0,85));
            ExcFonts.SFUI.drawTextComponent(matrix, textComponent, x, y, -1, false, 8);
        } else {
            // Если нет форматирования, просто рисуем обычный текст
            ExcFonts.SFUI.drawCenter(matrix, textComponent.getString(), x + ExcFonts.SF_REGULAR.getWidth(textComponent.getString(), 8) / 2, y, -1, 8);
        }
    }

    /**
     * Проверяет, содержит ли текстовый компонент какое-либо форматирование
     */
    private boolean hasFormatting(ITextComponent component) {
        // Проверяем основной стиль
        if (component.getStyle().getColor() != null ||
                component.getStyle().getBold() ||
                component.getStyle().getItalic() ||
                component.getStyle().getStrikethrough() ||
                component.getStyle().getUnderlined()) {
            return true;
        }

        // Проверяем дочерние компоненты
        for (ITextComponent sibling : component.getSiblings()) {
            if (hasFormatting(sibling)) {
                return true;
            }
        }

        return false;
    }

    public void read(SUpdateBossInfoPacket packetIn) {
        if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.ADD) {
            this.mapBossInfos.put(packetIn.getUniqueId(), new ClientBossInfo(packetIn));
        } else if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.REMOVE) {
            this.mapBossInfos.remove(packetIn.getUniqueId());
        } else {
            this.mapBossInfos.get(packetIn.getUniqueId()).updateFromPacket(packetIn);
        }
    }

    public void clearBossInfos() {
        this.mapBossInfos.clear();
    }

    public boolean shouldPlayEndBossMusic() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldPlayEndBossMusic()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldDarkenSky() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldDarkenSky()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldCreateFog() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldCreateFog()) {
                    return true;
                }
            }
        }

        return false;
    }
}
5. Заходим в игру и проверяем, работает ли всё у вас
============================
всем удачки
 

Вложения

  • 1758111585381.png
    1758111585381.png
    4.7 KB · Просмотры: 504
Последнее редактирование модератором:
мне понравилось
 
Гавно я лучше могу
 
Дарова, югейм, решил залить вам темку на югейм, кастом boss bar для майнкрафта
=======================
SS: Прикреплён
DW: Ниже
=======================

Туториал:
1. Идём в ваш класс рендера худа, он может называться по разному:
HUD/Interface/Overlay (в зависимости от вашей базы и от имени)
2. У вас там будет ModeListSetting с элементами худа, туда пишем:
new BooleanSetting("Босс бар", true);
3. Идём в класс BossOverlayGui
ВАЖНО! У МЕНЯ УТИЛКИ ШРИФТОВ С EXCELLENT RECODE, А РЕКТЫ С LITKA CLIENT (NOAD)
Поэтому возможно перенести будет трудновато

4. Вставляем мой код:
BossOverlayGui:
Expand Collapse Copy
package net.minecraft.client.gui.overlay;

import client.main.module.impl.ui.HUD;
import client.util.display.render.ColorUtil;
import client.util.display.render.RenderUtil;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.Map;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.ClientBossInfo;
import net.minecraft.network.play.server.SUpdateBossInfoPacket;
import net.minecraft.util.IReorderingProcessor;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.BossInfo;
import net.optifine.Config;
import net.optifine.CustomColors;
import net.optifine.reflect.Reflector;
import client.util.screenUtil.normalFont.ExcFonts;
import client.util.display.render.Round;

public class BossOverlayGui extends AbstractGui {
    private static final ResourceLocation GUI_BARS_TEXTURES = new ResourceLocation("textures/gui/bars.png");
    private final Minecraft client;
    private final Map<UUID, ClientBossInfo> mapBossInfos = Maps.newLinkedHashMap();

    public BossOverlayGui(Minecraft clientIn) {
        this.client = clientIn;
    }

    public void func_238484_a_(MatrixStack matrixStack) {
        if (!this.mapBossInfos.isEmpty()) {
            int screenWidth = this.client.getMainWindow().getScaledWidth();
            int y = 12;

            for (ClientBossInfo bossInfo : this.mapBossInfos.values()) {
                int x = screenWidth / 2 - 91;
                RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);

                boolean render = true;
                int increment = 19;

                if (Reflector.ForgeHooksClient_bossBarRenderPre.exists()) {
                    Object event = Reflector.ForgeHooksClient_bossBarRenderPre.call(matrixStack,
                            this.client.getMainWindow(), bossInfo, x, y, 10 + 9);
                    render = !Reflector.callBoolean(event, Reflector.Event_isCanceled);
                    increment = Reflector.callInt(event, Reflector.RenderGameOverlayEvent_BossInfo_getIncrement);
                }

                if (render) {
                    if (HUD.HUDelements.getValueByName("Босс бар").get()) {
                        // ✅ Кастомный рендер
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int textColor = 16777215;
                        if (Config.isCustomColors()) {
                            textColor = CustomColors.getBossTextColor(textColor);
                        }

                        // Рисуем кастомный бар
                        renderCustomBossBar(matrixStack, x, y + 2, bossInfo, textColor);

                        // Рисуем кастомный текст
                        ITextComponent text = bossInfo.getName();
                        int textWidth = (int) ExcFonts.SF_REGULAR.getWidth(text.getString(), 8);
                        int textX = screenWidth / 2 - textWidth / 2;
                        int textY = y - 9;

                        renderBossTextWithCustomFont(matrixStack, text, textX, textY, textColor);
                    } else {
                        // ✅ Ванильный рендер (как в 1.16.5)
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int j = 12;
                        int i = this.client.getMainWindow().getScaledWidth();
                        int k = i / 2 - 91;
                        this.func_238485_a_(matrixStack, k, j, bossInfo);

                        int filled = (int) (bossInfo.getPercent() * 183.0F);
                        if (filled > 0) {
                            this.blit(matrixStack, x, y, 0, 79, filled, 5);
                        }

                        ITextComponent text = bossInfo.getName();
                        int textX = screenWidth / 2 - this.client.fontRenderer.getStringPropertyWidth(text) / 2;
                        int textY = y - 9;
                        int l1 = 16777215;

                        if (Config.isCustomColors()) {
                            l1 = CustomColors.getBossTextColor(l1);
                        }
                        this.client.fontRenderer.drawStringWithShadow(matrixStack, text, textX, textY, l1);
                    }
                }

                y += increment;
                Reflector.ForgeHooksClient_bossBarRenderPost.callVoid(matrixStack, this.client.getMainWindow());

                if (y >= this.client.getMainWindow().getScaledHeight() / 3) {
                    break;
                }
            }
        }
    }
    private void func_238485_a_(MatrixStack p_238485_1_, int p_238485_2_, int p_238485_3_, BossInfo p_238485_4_) {
        this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2, 182, 5);

        if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2, 182, 5);
        }

        int i = (int) (p_238485_4_.getPercent() * 183.0F);

        if (i > 0) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2 + 5, i, 5);

            if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
                this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2 + 5, i, 5);
            }
        }
    }

    /**
     * Кастомный рендеринг полоски здоровья босса с градиентом
     */
    private void renderCustomBossBar(MatrixStack matrix, int x, int y, BossInfo bossInfo, int color) {
        float percent = bossInfo.getPercent();

        // Получаем цвета для градиента (основной и более темный)
        int mainColor = getBossBarMainColor(bossInfo.getColor());
        int darkColor = ColorUtil.multDark(getBossBarDarkColor(bossInfo.getColor()),0.5f);
        int backgroundColor = ColorUtil.rgb(25,25,25);
        int l1 = 16777215;

        if (Config.isCustomColors()) {
            l1 = CustomColors.getBossTextColor(l1);
        }
        // Рендерим фон полоски
        RenderUtil.Rounded.smooth(matrix, x, y, 182, 4, backgroundColor, backgroundColor, Round.of(1.5f));

        // Рендерим заполненную часть полоски с градиентом
        if (percent > 0) {
            float filledWidth = 182 * percent;
            RenderUtil.Rounded.smooth(matrix, x, y, filledWidth, 4, mainColor, darkColor, Round.of(1.5f));
        }
    }

    /**
     * Получаем основной цвет градиента для полоски здоровья
     */
    private int getBossBarMainColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFFF78B8; // Яркий розовый
            case BLUE: return 0xFF5CD4FF; // Яркий синий
            case RED: return 0xFFFF0000; // Яркий красный
            case GREEN: return 0xFF00FF00; // Яркий зеленый
            case YELLOW: return 0xFFFFFF00; // Яркий желтый
            case PURPLE: return 0xFFB878FF; // Яркий фиолетовый
            case WHITE: return 0xFFFFFFFF; // Белый
            default: return 0xFF5CD4FF; // Синий по умолчанию
        }
    }

    /**
     * Получаем темный цвет градиента для полоски здоровья
     */
    private int getBossBarDarkColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFD84B98; // Темный розовый
            case BLUE: return 0xFF4AA3CC; // Темный синий
            case RED: return 0xFFCC0000; // Темный красный
            case GREEN: return 0xFF00CC00; // Темный зеленый
            case YELLOW: return 0xFFCCCC00; // Темный желтый
            case PURPLE: return 0xFF9460CC; // Темный фиолетовый
            case WHITE: return 0xFFCCCCCC; // Светло-серый
            default: return 0xFF4AA3CC; // Синий по умолчанию
        }
    }

    /**
     * Получаем цвет фона полоски здоровья
     */
    private int getBossBarBackgroundColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFF601C44; // Темный розовый фон
            case BLUE: return 0xFF0B4C8C; // Темный синий фон
            case RED: return 0xFF660000; // Темный красный фон
            case GREEN: return 0xFF006600; // Темный зеленый фон
            case YELLOW: return 0xFF666600; // Темный желтый фон
            case PURPLE: return 0xFF3C0066; // Темный фиолетовый фон
            case WHITE: return 0xFF666666; // Серый фон
            default: return 0xFF0B4C8C; // Синий по умолчанию
        }
    }

    /**
     * Метод для рендеринга текста босса с кастомным шрифтом, сохраняя оригинальные цвета
     */
    private void renderBossTextWithCustomFont(MatrixStack matrix, ITextComponent textComponent, float x, float y, int defaultColor) {
        // Если текст содержит форматирование, используем метод для компонентов
        if (hasFormatting(textComponent)) {
            RenderUtil.Shadow.drawShadow(matrix,x - 2.5f,y,ExcFonts.SFUI.getWidth(textComponent, 8) + 5, 9,5,ColorUtil.rgba(0,0,0,85));
            ExcFonts.SFUI.drawTextComponent(matrix, textComponent, x, y, -1, false, 8);
        } else {
            // Если нет форматирования, просто рисуем обычный текст
            ExcFonts.SFUI.drawCenter(matrix, textComponent.getString(), x + ExcFonts.SF_REGULAR.getWidth(textComponent.getString(), 8) / 2, y, -1, 8);
        }
    }

    /**
     * Проверяет, содержит ли текстовый компонент какое-либо форматирование
     */
    private boolean hasFormatting(ITextComponent component) {
        // Проверяем основной стиль
        if (component.getStyle().getColor() != null ||
                component.getStyle().getBold() ||
                component.getStyle().getItalic() ||
                component.getStyle().getStrikethrough() ||
                component.getStyle().getUnderlined()) {
            return true;
        }

        // Проверяем дочерние компоненты
        for (ITextComponent sibling : component.getSiblings()) {
            if (hasFormatting(sibling)) {
                return true;
            }
        }

        return false;
    }

    public void read(SUpdateBossInfoPacket packetIn) {
        if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.ADD) {
            this.mapBossInfos.put(packetIn.getUniqueId(), new ClientBossInfo(packetIn));
        } else if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.REMOVE) {
            this.mapBossInfos.remove(packetIn.getUniqueId());
        } else {
            this.mapBossInfos.get(packetIn.getUniqueId()).updateFromPacket(packetIn);
        }
    }

    public void clearBossInfos() {
        this.mapBossInfos.clear();
    }

    public boolean shouldPlayEndBossMusic() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldPlayEndBossMusic()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldDarkenSky() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldDarkenSky()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldCreateFog() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldCreateFog()) {
                    return true;
                }
            }
        }

        return false;
    }
}
5. Заходим в игру и проверяем, работает ли всё у вас
============================
всем удачки
спаст. илданк!
 
Дарова, югейм, решил залить вам темку на югейм, кастом boss bar для майнкрафта
=======================
SS: Прикреплён
DW: Ниже
=======================

Туториал:
1. Идём в ваш класс рендера худа, он может называться по разному:
HUD/Interface/Overlay (в зависимости от вашей базы и от имени)
2. У вас там будет ModeListSetting с элементами худа, туда пишем:
new BooleanSetting("Босс бар", true);
3. Идём в класс BossOverlayGui
ВАЖНО! У МЕНЯ УТИЛКИ ШРИФТОВ С EXCELLENT RECODE, А РЕКТЫ С LITKA CLIENT (NOAD)
Поэтому возможно перенести будет трудновато

4. Вставляем мой код:
BossOverlayGui:
Expand Collapse Copy
package net.minecraft.client.gui.overlay;

import client.main.module.impl.ui.HUD;
import client.util.display.render.ColorUtil;
import client.util.display.render.RenderUtil;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.Map;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.ClientBossInfo;
import net.minecraft.network.play.server.SUpdateBossInfoPacket;
import net.minecraft.util.IReorderingProcessor;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.BossInfo;
import net.optifine.Config;
import net.optifine.CustomColors;
import net.optifine.reflect.Reflector;
import client.util.screenUtil.normalFont.ExcFonts;
import client.util.display.render.Round;

public class BossOverlayGui extends AbstractGui {
    private static final ResourceLocation GUI_BARS_TEXTURES = new ResourceLocation("textures/gui/bars.png");
    private final Minecraft client;
    private final Map<UUID, ClientBossInfo> mapBossInfos = Maps.newLinkedHashMap();

    public BossOverlayGui(Minecraft clientIn) {
        this.client = clientIn;
    }

    public void func_238484_a_(MatrixStack matrixStack) {
        if (!this.mapBossInfos.isEmpty()) {
            int screenWidth = this.client.getMainWindow().getScaledWidth();
            int y = 12;

            for (ClientBossInfo bossInfo : this.mapBossInfos.values()) {
                int x = screenWidth / 2 - 91;
                RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);

                boolean render = true;
                int increment = 19;

                if (Reflector.ForgeHooksClient_bossBarRenderPre.exists()) {
                    Object event = Reflector.ForgeHooksClient_bossBarRenderPre.call(matrixStack,
                            this.client.getMainWindow(), bossInfo, x, y, 10 + 9);
                    render = !Reflector.callBoolean(event, Reflector.Event_isCanceled);
                    increment = Reflector.callInt(event, Reflector.RenderGameOverlayEvent_BossInfo_getIncrement);
                }

                if (render) {
                    if (HUD.HUDelements.getValueByName("Босс бар").get()) {
                        // ✅ Кастомный рендер
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int textColor = 16777215;
                        if (Config.isCustomColors()) {
                            textColor = CustomColors.getBossTextColor(textColor);
                        }

                        // Рисуем кастомный бар
                        renderCustomBossBar(matrixStack, x, y + 2, bossInfo, textColor);

                        // Рисуем кастомный текст
                        ITextComponent text = bossInfo.getName();
                        int textWidth = (int) ExcFonts.SF_REGULAR.getWidth(text.getString(), 8);
                        int textX = screenWidth / 2 - textWidth / 2;
                        int textY = y - 9;

                        renderBossTextWithCustomFont(matrixStack, text, textX, textY, textColor);
                    } else {
                        // ✅ Ванильный рендер (как в 1.16.5)
                        this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
                        int j = 12;
                        int i = this.client.getMainWindow().getScaledWidth();
                        int k = i / 2 - 91;
                        this.func_238485_a_(matrixStack, k, j, bossInfo);

                        int filled = (int) (bossInfo.getPercent() * 183.0F);
                        if (filled > 0) {
                            this.blit(matrixStack, x, y, 0, 79, filled, 5);
                        }

                        ITextComponent text = bossInfo.getName();
                        int textX = screenWidth / 2 - this.client.fontRenderer.getStringPropertyWidth(text) / 2;
                        int textY = y - 9;
                        int l1 = 16777215;

                        if (Config.isCustomColors()) {
                            l1 = CustomColors.getBossTextColor(l1);
                        }
                        this.client.fontRenderer.drawStringWithShadow(matrixStack, text, textX, textY, l1);
                    }
                }

                y += increment;
                Reflector.ForgeHooksClient_bossBarRenderPost.callVoid(matrixStack, this.client.getMainWindow());

                if (y >= this.client.getMainWindow().getScaledHeight() / 3) {
                    break;
                }
            }
        }
    }
    private void func_238485_a_(MatrixStack p_238485_1_, int p_238485_2_, int p_238485_3_, BossInfo p_238485_4_) {
        this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2, 182, 5);

        if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2, 182, 5);
        }

        int i = (int) (p_238485_4_.getPercent() * 183.0F);

        if (i > 0) {
            this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, p_238485_4_.getColor().ordinal() * 5 * 2 + 5, i, 5);

            if (p_238485_4_.getOverlay() != BossInfo.Overlay.PROGRESS) {
                this.blit(p_238485_1_, p_238485_2_, p_238485_3_, 0, 80 + (p_238485_4_.getOverlay().ordinal() - 1) * 5 * 2 + 5, i, 5);
            }
        }
    }

    /**
     * Кастомный рендеринг полоски здоровья босса с градиентом
     */
    private void renderCustomBossBar(MatrixStack matrix, int x, int y, BossInfo bossInfo, int color) {
        float percent = bossInfo.getPercent();

        // Получаем цвета для градиента (основной и более темный)
        int mainColor = getBossBarMainColor(bossInfo.getColor());
        int darkColor = ColorUtil.multDark(getBossBarDarkColor(bossInfo.getColor()),0.5f);
        int backgroundColor = ColorUtil.rgb(25,25,25);
        int l1 = 16777215;

        if (Config.isCustomColors()) {
            l1 = CustomColors.getBossTextColor(l1);
        }
        // Рендерим фон полоски
        RenderUtil.Rounded.smooth(matrix, x, y, 182, 4, backgroundColor, backgroundColor, Round.of(1.5f));

        // Рендерим заполненную часть полоски с градиентом
        if (percent > 0) {
            float filledWidth = 182 * percent;
            RenderUtil.Rounded.smooth(matrix, x, y, filledWidth, 4, mainColor, darkColor, Round.of(1.5f));
        }
    }

    /**
     * Получаем основной цвет градиента для полоски здоровья
     */
    private int getBossBarMainColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFFF78B8; // Яркий розовый
            case BLUE: return 0xFF5CD4FF; // Яркий синий
            case RED: return 0xFFFF0000; // Яркий красный
            case GREEN: return 0xFF00FF00; // Яркий зеленый
            case YELLOW: return 0xFFFFFF00; // Яркий желтый
            case PURPLE: return 0xFFB878FF; // Яркий фиолетовый
            case WHITE: return 0xFFFFFFFF; // Белый
            default: return 0xFF5CD4FF; // Синий по умолчанию
        }
    }

    /**
     * Получаем темный цвет градиента для полоски здоровья
     */
    private int getBossBarDarkColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFFD84B98; // Темный розовый
            case BLUE: return 0xFF4AA3CC; // Темный синий
            case RED: return 0xFFCC0000; // Темный красный
            case GREEN: return 0xFF00CC00; // Темный зеленый
            case YELLOW: return 0xFFCCCC00; // Темный желтый
            case PURPLE: return 0xFF9460CC; // Темный фиолетовый
            case WHITE: return 0xFFCCCCCC; // Светло-серый
            default: return 0xFF4AA3CC; // Синий по умолчанию
        }
    }

    /**
     * Получаем цвет фона полоски здоровья
     */
    private int getBossBarBackgroundColor(BossInfo.Color color) {
        switch (color) {
            case PINK: return 0xFF601C44; // Темный розовый фон
            case BLUE: return 0xFF0B4C8C; // Темный синий фон
            case RED: return 0xFF660000; // Темный красный фон
            case GREEN: return 0xFF006600; // Темный зеленый фон
            case YELLOW: return 0xFF666600; // Темный желтый фон
            case PURPLE: return 0xFF3C0066; // Темный фиолетовый фон
            case WHITE: return 0xFF666666; // Серый фон
            default: return 0xFF0B4C8C; // Синий по умолчанию
        }
    }

    /**
     * Метод для рендеринга текста босса с кастомным шрифтом, сохраняя оригинальные цвета
     */
    private void renderBossTextWithCustomFont(MatrixStack matrix, ITextComponent textComponent, float x, float y, int defaultColor) {
        // Если текст содержит форматирование, используем метод для компонентов
        if (hasFormatting(textComponent)) {
            RenderUtil.Shadow.drawShadow(matrix,x - 2.5f,y,ExcFonts.SFUI.getWidth(textComponent, 8) + 5, 9,5,ColorUtil.rgba(0,0,0,85));
            ExcFonts.SFUI.drawTextComponent(matrix, textComponent, x, y, -1, false, 8);
        } else {
            // Если нет форматирования, просто рисуем обычный текст
            ExcFonts.SFUI.drawCenter(matrix, textComponent.getString(), x + ExcFonts.SF_REGULAR.getWidth(textComponent.getString(), 8) / 2, y, -1, 8);
        }
    }

    /**
     * Проверяет, содержит ли текстовый компонент какое-либо форматирование
     */
    private boolean hasFormatting(ITextComponent component) {
        // Проверяем основной стиль
        if (component.getStyle().getColor() != null ||
                component.getStyle().getBold() ||
                component.getStyle().getItalic() ||
                component.getStyle().getStrikethrough() ||
                component.getStyle().getUnderlined()) {
            return true;
        }

        // Проверяем дочерние компоненты
        for (ITextComponent sibling : component.getSiblings()) {
            if (hasFormatting(sibling)) {
                return true;
            }
        }

        return false;
    }

    public void read(SUpdateBossInfoPacket packetIn) {
        if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.ADD) {
            this.mapBossInfos.put(packetIn.getUniqueId(), new ClientBossInfo(packetIn));
        } else if (packetIn.getOperation() == SUpdateBossInfoPacket.Operation.REMOVE) {
            this.mapBossInfos.remove(packetIn.getUniqueId());
        } else {
            this.mapBossInfos.get(packetIn.getUniqueId()).updateFromPacket(packetIn);
        }
    }

    public void clearBossInfos() {
        this.mapBossInfos.clear();
    }

    public boolean shouldPlayEndBossMusic() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldPlayEndBossMusic()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldDarkenSky() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldDarkenSky()) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean shouldCreateFog() {
        if (!this.mapBossInfos.isEmpty()) {
            for (BossInfo bossinfo : this.mapBossInfos.values()) {
                if (bossinfo.shouldCreateFog()) {
                    return true;
                }
            }
        }

        return false;
    }
}
5. Заходим в игру и проверяем, работает ли всё у вас
============================
всем удачки
8 gpt из 10
 
Назад
Сверху Снизу