Гайд Expensive-like уведы 3.1 ready

Начинающий
Статус
Оффлайн
Регистрация
15 Ноя 2024
Сообщения
78
Реакции[?]
0
Поинты[?]
0

Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:

  • бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
  • маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
  • приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
  • обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.

Спасибо!

ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
 

Вложения

Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
30 Авг 2024
Сообщения
90
Реакции[?]
1
Поинты[?]
0
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
имба +rep
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
 
Начинающий
Статус
Онлайн
Регистрация
11 Окт 2024
Сообщения
219
Реакции[?]
0
Поинты[?]
0
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
 
Начинающий
Статус
Оффлайн
Регистрация
15 Ноя 2024
Сообщения
78
Реакции[?]
0
Поинты[?]
0
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
так а как по другому писать нотифки? добавить кучу разной херни + ещё чего нибудь, что бы мой код не был похож на другой? я пытался эти нотифки запастить, но после проеба я полетел в чат лбгт и начал чёт писать, я их написал за ~часа времени, взяв за основу стиль кейбиндов из 3.1
 
Начинающий
Статус
Оффлайн
Регистрация
27 Сен 2024
Сообщения
119
Реакции[?]
0
Поинты[?]
0
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
анимки есть?
 
Начинающий
Статус
Оффлайн
Регистрация
15 Ноя 2024
Сообщения
78
Реакции[?]
0
Поинты[?]
0
Начинающий
Статус
Оффлайн
Регистрация
10 Янв 2025
Сообщения
28
Реакции[?]
0
Поинты[?]
0
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
типочек просто перезалил тему, позор
нотифок мало вроде, если нет, то пусть будет ещё одна очередная нотифка.
смысл? чтобы сервера нагружало? /del
 
Начинающий
Статус
Оффлайн
Регистрация
20 Сен 2024
Сообщения
220
Реакции[?]
2
Поинты[?]
3K
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
Чел реально годно :seemsgood:
 
Начинающий
Статус
Оффлайн
Регистрация
17 Ноя 2023
Сообщения
248
Реакции[?]
2
Поинты[?]
3K
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
брат нет, он с евы их сдиздил ахазаахаххаахахаха в еве точно такие же
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
/del evaware opensource если что
 
Начинающий
Статус
Оффлайн
Регистрация
16 Июн 2023
Сообщения
33
Реакции[?]
0
Поинты[?]
0
Expensive.getInstance().getNotificationManager().getRenderer().render(e); куда вставлять? Не особо понял
 
Начинающий
Статус
Оффлайн
Регистрация
26 Сен 2024
Сообщения
30
Реакции[?]
0
Поинты[?]
0
так а как по другому писать нотифки? добавить кучу разной херни + ещё чего нибудь, что бы мой код не был похож на другой? я пытался эти нотифки запастить, но после проеба я полетел в чат лбгт и начал чёт писать, я их написал за ~часа времени, взяв за основу стиль кейбиндов из 3.1
слушай зделай тож самое но чтобы как в нурике тип посередине екрана + или же чтобы можно было передвигать их
 
Начинающий
Статус
Оффлайн
Регистрация
6 Дек 2023
Сообщения
439
Реакции[?]
2
Поинты[?]
2K
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
годно если первая тема
 
Начинающий
Статус
Оффлайн
Регистрация
25 Июл 2024
Сообщения
119
Реакции[?]
0
Поинты[?]
0
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

приступим к самому гайду.
создаем в папке с мейном клиента класс NotificationManager
код:

Java:
package im.expensive;

import im.expensive.ui.display.impl.NotificationsRenderer;

public class NotificationManager {

    private static NotificationManager instance;
    private final NotificationsRenderer renderer;

    private NotificationManager() {
        this.renderer = new NotificationsRenderer();
    }

    public static NotificationManager getInstance() {
        if (instance == null) {
            instance = new NotificationManager();
        }
        return instance;
    }

    public void addNotification(String message, boolean enabled) {
        renderer.addNotification(message, enabled);
    }

    public NotificationsRenderer getRenderer() {
        return renderer;
    }
}
дальше в самом мейне клиента:
в функции clientLoad()
перед регистером eventbus ставим:
notificationManager = NotificationManager.getInstance();

не забываем про обработчик
private NotificationManager notificationManager;

дальше идем в папку с рендерами кейбиндов и т.п
создаем класс NotificationsRenderer
код

Java:
package im.expensive.ui.display.impl;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import im.expensive.Expensive;
import im.expensive.events.EventDisplay;
import im.expensive.ui.display.ElementRenderer;
import im.expensive.ui.styles.Style;
import im.expensive.utils.animations.Animation;
import im.expensive.utils.animations.Direction;
import im.expensive.utils.animations.impl.EaseBackIn;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.Scissor;
import im.expensive.utils.render.font.Fonts;
import im.expensive.utils.text.GradientUtil;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

import java.util.concurrent.CopyOnWriteArrayList;

@FieldDefaults(level = AccessLevel.PRIVATE)
public class NotificationsRenderer implements ElementRenderer {

    final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList<>();
    final ResourceLocation icon = new ResourceLocation("expensive/images/hud/notification.png");

    static final float FONT_SIZE = 7f;
    static final float PADDING = 4f;
    static final float ROUNDING = 5f;
    static final float ICON_SIZE = 10f;
    static final float HEIGHT = FONT_SIZE + PADDING * 2;
    static final int MAX_NOTIFICATIONS = 5;
    static final int DISPLAY_TIME_MS = 3000;

    @Override
    public void render(EventDisplay eventDisplay) {
        if (eventDisplay.getType() != EventDisplay.Type.POST) return;

        MatrixStack matrixStack = eventDisplay.getMatrixStack();
        Style style = Expensive.getInstance().getStyleManager().getCurrentStyle();
        if (style == null) return;

        int screenWidth = mc.getMainWindow().getScaledWidth();
        int screenHeight = mc.getMainWindow().getScaledHeight();

        float posY = screenHeight - HEIGHT - PADDING;

        int notificationCount = Math.min(notifications.size(), MAX_NOTIFICATIONS);
        for (int i = 0; i < notificationCount; i++) {
            Notification notification = notifications.get(i);

            String status = notification.isEnabled ? "включен" : "выключен";
            ITextComponent message = GradientUtil.gradient("Модуль " + notification.moduleName + " был " + status);
            float textWidth = Fonts.sfui.getWidth(message, FONT_SIZE);
            float width = textWidth + ICON_SIZE + PADDING * 5;
            float posX = screenWidth - width - PADDING;

            boolean expired = notification.stopWatch.isReached(DISPLAY_TIME_MS);
            notification.animation.setDirection(expired ? Direction.BACKWARDS : Direction.FORWARDS);
            float animationValue = (float) notification.animation.getOutput();

            if (animationValue <= 0f && expired) {
                notifications.remove(notification);
                continue;
            }

            float halfAnimationValueRest = (1 - animationValue) / 2f;
            float animatedX = posX + (width * halfAnimationValueRest);
            float animatedY = posY + (HEIGHT * halfAnimationValueRest);
            float animatedWidth = width * animationValue;
            float animatedHeight = HEIGHT * animationValue;

            DisplayUtils.drawShadow(posX, posY, width, HEIGHT, 8, style.getFirstColor().getRGB(), style.getSecondColor().getRGB());
            drawStyledRect(posX, posY, width, HEIGHT, ROUNDING, 255);

            Scissor.push();
            Scissor.setFromComponentCoordinates(animatedX, animatedY, animatedWidth - PADDING * 2, animatedHeight);

            mc.getTextureManager().bindTexture(icon);
            RenderSystem.enableBlend();
            RenderSystem.color4f(1f, 1f, 1f, animationValue);
            AbstractGui.blit(matrixStack, (int) (posX + PADDING), (int) (posY + (HEIGHT - ICON_SIZE) / 2),
                    0, 0, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE, (int) ICON_SIZE);

            Fonts.sfui.drawText(matrixStack, message.getString(), posX + PADDING + ICON_SIZE + PADDING, posY + PADDING, -1, FONT_SIZE);

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

            posY -= HEIGHT + PADDING;
        }
    }

    private void drawStyledRect(float x, float y, float rectWidth, float rectHeight, float radius, int alpha) {
        DisplayUtils.drawRoundedRect(x - 0.5f, y - 0.5f, rectWidth + 1, rectHeight + 1, radius + 0.5f,
                ColorUtils.setAlpha(ColorUtils.getColor(0), alpha));
        DisplayUtils.drawRoundedRect(x, y, rectWidth, rectHeight, radius, ColorUtils.rgba(21, 21, 21, alpha)); // Фон
    }

    public void addNotification(String moduleName, boolean isEnabled) {
        notifications.add(0, new Notification(moduleName, isEnabled));
    }

    @FieldDefaults(level = AccessLevel.PRIVATE)
    private static class Notification {
        final String moduleName;
        final boolean isEnabled;
        final StopWatch stopWatch = new StopWatch();
        final Animation animation = new EaseBackIn(400, 1, 1);

        Notification(String moduleName, boolean isEnabled) {
            this.moduleName = moduleName;
            this.isEnabled = isEnabled;
            this.stopWatch.reset();
            this.animation.setDirection(Direction.FORWARDS);
        }
    }
}
дальше идем в im.expensive.functions.api.Function
и меняем setState на это
Java:
    public final void setState(boolean newState, boolean config) {
        if (state == newState) {
            return;
        }

        state = newState;

        try {
            if (state) {
                onEnable();
                Expensive.getInstance().getNotificationManager().addNotification(name, true);
            } else {
                onDisable();
                Expensive.getInstance().getNotificationManager().addNotification(name, false);
            }
            if (!config) {
                FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
                ClientSounds clientSounds = functionRegistry.getClientSounds();

                if (clientSounds != null && clientSounds.isState()) {
                    String fileName = clientSounds.getFileName(state);
                    float volume = clientSounds.volume.get();
                    ClientUtil.playSound(fileName, volume, false);
                }
            }
        } catch (Exception e) {
            handleException(state ? "onEnable" : "onDisable", e);
        }
    }
дальше идем в модуль худа и добавляем сеттинг уведомлений
и добавляем рендер уведов, если включены
кому лень писать вот этот микро код
Expensive.getInstance().getNotificationManager().getRenderer().render(e);


дальше ищем иконку нотифа (на размер все равно, он автоматический) и радуемся (если я и моя деменция что-то не забыла)
если столкнулись с ошибкой кроме моего присутсвия на форуме, пишите я постараюсь помочь.

SS: прикрепил
для пастерочка сойдет:seemsgood::seemsgood:
а так удачки
 
Начинающий
Статус
Оффлайн
Регистрация
15 Ноя 2024
Сообщения
78
Реакции[?]
0
Поинты[?]
0
слушай зделай тож самое но чтобы как в нурике тип посередине екрана + или же чтобы можно было передвигать их
драггинги не очень сложно и самому сделать, а по поводу уведомлений по центру норм идея
 
Сверху Снизу