Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

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

Забаненный
Забаненный
Статус
Оффлайн
Регистрация
15 Ноя 2024
Сообщения
217
Реакции
2
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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: прикрепил
 

Вложения

  • Jdk17.0.14_7 Screenshot 2025.02.21 - 21.13.43.05.png
    Jdk17.0.14_7 Screenshot 2025.02.21 - 21.13.43.05.png
    70.4 KB · Просмотры: 870
Последнее редактирование:
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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: прикрепил
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
 
1740164934419.png
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
так а как по другому писать нотифки? добавить кучу разной херни + ещё чего нибудь, что бы мой код не был похож на другой? я пытался эти нотифки запастить, но после проеба я полетел в чат лбгт и начал чёт писать, я их написал за ~часа времени, взяв за основу стиль кейбиндов из 3.1
 
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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: прикрепил
анимки есть?
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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
 
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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:
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
Бляя добнул 1 рект сзади и строку с "функция" поставил в одну строку, cringe
брат нет, он с евы их сдиздил ахазаахаххаахахаха в еве точно такие же
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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 если что
 
так а как по другому писать нотифки? добавить кучу разной херни + ещё чего нибудь, что бы мой код не был похож на другой? я пытался эти нотифки запастить, но после проеба я полетел в чат лбгт и начал чёт писать, я их написал за ~часа времени, взяв за основу стиль кейбиндов из 3.1
слушай зделай тож самое но чтобы как в нурике тип посередине екрана + или же чтобы можно было передвигать их
 
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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: прикрепил
годно если первая тема
 
ку гайс, моя первая тема на форуме, я нюгенчик и самый крутой на сайте чат лбгт
надеюсь больше ничего вы от меня тут не увидите, но сегодня исключение.

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

Java:
Expand Collapse Copy
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:
Expand Collapse Copy
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:
Expand Collapse Copy
    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:
а так удачки
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
слушай зделай тож самое но чтобы как в нурике тип посередине екрана + или же чтобы можно было передвигать их
драггинги не очень сложно и самому сделать, а по поводу уведомлений по центру норм идея
 
Назад
Сверху Снизу