Всем ку! Сегодня сливаю около-нурсултановские нотификейшны, вроде как никаких багов у них нет(по крайней мере я не обнаружил), подбирает размер бекграунда и положения иконки от текста (P.S. Да, основа нотифок это (noad) но у них было только 2 варианта рендера иконок, другой рендер и бла-бла-бла) SS = https://imgur.com/a/IfzMHs6 package im.expensive.ui; import com.mojang.blaze3d.matrix.MatrixStack; import java.awt.*; import java.util.concurrent.CopyOnWriteArrayList; import im.expensive.Expensive; import im.expensive.command.friends.FriendStorage; import im.expensive.functions.api.Notificpenus; import im.expensive.functions.impl.misc.SelfDestruct; import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.util.ResourceLocation; import im.expensive.utils.animations.Animation; import im.expensive.utils.animations.Direction; import im.expensive.utils.animations.impl.EaseBackIn; import im.expensive.utils.animations.impl.EaseInOutQuad; import im.expensive.utils.client.IMinecraft; import im.expensive.utils.math.MathUtil; import im.expensive.utils.render.ColorUtils; import im.expensive.utils.render.DisplayUtils; import im.expensive.utils.render.font.Fonts; import static im.expensive.utils.client.IMinecraft.mc; public class NotificationManager { public static final FriendStorage NOTIFICATION_MANAGER = null; private final CopyOnWriteArrayList<Notification> notifications = new CopyOnWriteArrayList(); private MathUtil AnimationMath; boolean state; public void add(String text, String content, int time) { this.notifications.add(new Notification(text, content, time)); } public void draw(MatrixStack stack) { int yOffset = 0; for (Notification notification : this.notifications) { if (System.currentTimeMillis() - notification.getTime() <= (long)notification.time2 * 1000L - 300L) { notification.yAnimation.setDirection(Direction.FORWARDS); } notification.alpha = (float)notification.animation.getOutput(); if (System.currentTimeMillis() - notification.getTime() > (long)notification.time2 * 1000L) { notification.yAnimation.setDirection(Direction.BACKWARDS); } if (notification.yAnimation.finished(Direction.BACKWARDS)) { this.notifications.remove(notification); continue; } float x = (float) mc.getMainWindow().scaledWidth() - (Fonts.sfMedium.getWidth(notification.getText(), 7.0f) + 8.0f) - 10.0f; float y = mc.getMainWindow().scaledHeight() - 40; notification.yAnimation.setEndPoint(yOffset); notification.yAnimation.setDuration(500); notification.setX(x); notification.setY(MathUtil.fast(notification.getY(), y -= (float)((double)notification.draw(stack) * notification.yAnimation.getOutput() + 3.0), 15.0f)); ++yOffset; } } private class Notification { private float x = 0.0f; private float y = mc.getMainWindow().scaledHeight() + 24; private String text; private String content; private long time = System.currentTimeMillis(); public Animation animation = new EaseInOutQuad(500, 1.0, Direction.FORWARDS); public Animation yAnimation = new EaseBackIn(500, 1.0, 1.0f); float alpha; int time2 = 3; private boolean isState; private boolean state; public Notification(String text, String content, int time) { this.text = text; this.content = content; this.time2 = time; } public float draw(MatrixStack stack) { mc.gameRenderer.setupOverlayRendering(2); float posX = mc.getMainWindow().getScaledWidth() / 2.0F; float posY = (float) mc.getMainWindow().getScaledHeight() + (float) mc.getMainWindow().getScaledHeight() / 2 - y - 20; float textWidth = im.expensive.utils.font.Fonts.mntsb[12].getWidth(this.text) + 28.0F + 15F; float XStart = posX - textWidth / 2.0F; DisplayUtils.drawRoundedRect(XStart, posY + 15.0F, textWidth, 11.0F, 4.0F, ColorUtils.rgba(0, 0, 0, 200)); Color style1 = Expensive.getInstance().getStyleManager().getCurrentStyle().getFirstColor(); DisplayUtils.drawRoundedRect(XStart, posY + 15.0F, textWidth, 11.0F, 4.0F, ColorUtils.rgba(style1.getRed(), style1.getGreen(), style1.getBlue(), 50)); float textX = posX - (im.expensive.utils.font.Fonts.mntsb[12].getWidth(this.text) / 2.0F); im.expensive.utils.font.Fonts.mntsb[12].drawString(stack, this.text, (double)(textX), (double)(posY + 19.0F), -1); //FUNCTIONS if (this.text.contains("включен")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack, "J", (double)(XStart + 4), (double)(posY + 20.0F), -1); } else if (this.text.contains("выключен")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack, "K", (double)(XStart + 4), (double)(posY + 20.0F), -1); } //FREELOOK if (this.text.contains("Отключите KillAura")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"M",(double)(XStart + 4), (double) (posY + 20.0F), -1); } //AUTOGPS if (this.text.contains("Добавили ГПС")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"F",(double)(XStart + 4), (double) (posY + 20.0F), -1); } //NOTIFICATIONS if (this.text.contains("высокий пинг")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"Q",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("просит спек")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"G",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("У вас мало хп!")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"M",(double)(XStart + 4), (double) (posY + 20.0F), -1); } //ELYTRAHELPER if (this.text.contains("Феерверки не найдены!")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"I",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("Свапнул на элитру!")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"G",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("Свапнул на нагрудник!")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"G",(double)(XStart + 4), (double) (posY + 20.0F), -1); } //FTHELPER if (this.text.contains("До следующего ивента")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"T",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("не найден")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"I",(double)(XStart + 4), (double) (posY + 20.0F), -1); } if (this.text.contains("Заюзал")) { im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"G",(double)(XStart + 4), (double) (posY + 20.0F), -1); } mc.gameRenderer.setupOverlayRendering(); return 12.0F; } public float getX() { return this.x; } public float getY() { return this.y; } public void setX(float x) { this.x = x; } public void setY(float y) { this.y = y; } public String getText() { return this.text; } public String getContent() { return this.content; } public long getTime() { return this.time; } } } После создаете класс package im.expensive.functions.api; import im.expensive.ui.NotificationManager; public class Notificpenus { public static NotificationManager NOTIFICATION_MANAGER; } Теперь в Expensive после File filesDir ставим код public NotificationManager notificationManager; в clientLoad() notificationManager = new NotificationManager(); и в конец метода Notificpenus.NOTIFICATION_MANAGER = new NotificationManager(); в Function ставим или заменяем boolean bl = this.state = !this.state; if (!this.state) { this.onDisable(); Notificpenus.NOTIFICATION_MANAGER.add(this.name + " выключен.", "", 2); } else { this.onEnable(); Notificpenus.NOTIFICATION_MANAGER.add(this.name + " включен.", "", 2); } UPDDDDDDD: Я не знаю надо оно 100% или нет, но что бы избежать вылетов и просьб помощи лучше поставлю В класс IngameGui ставим код +- на 427 строку Notificpenus.NOTIFICATION_MANAGER.draw(matrixStack); Скачиваем шрифты https://workupload.com/archive/Xjtcxj9zwF (noad) Кидаем их по пути src/assets/minecraft/expensive/font Если у вас есть класс Fonts по пути im.expensive.utils.font то просто вставляем этот код public static volatile StyledFont[] nurik = new StyledFont[131]; public static volatile StyledFont[] mntsb = new StyledFont[48]; //(строки после FONT_DIR) for (int i = 8; i < 48;i++) { mntsb[i] = new StyledFont("mntsb.ttf", i, 0.0f, 0.0f, 0.0f, true, Lang.ENG_RU); } for (int i = 8; i < 131;i++) { nurik[i] = new StyledFont("nurik.ttf", i, 0.0f, 0.0f, 0.0f, true, Lang.ENG_RU); } // Это ставим в метод init Если же у вас нет класса и его утилок: Качаем их с первого пункта отсюда (noad) (Из этой системы можете не ставить шрифты, если вы их не ставите уберите все из метода init и все public static volatile StyledFont[] над методом В NotificationManager я специально пометил FreeLook AutoGps что бы различать текст между друг другом, этот текст - иконка ставящаяся перед нотификейшном, если у вас их нет, код просто не будет работать, можете посмотреть сам шрифт, и по нему делать что то для своих нотификейшнов, Как использовать? Представим, что в функции GriefHelper вы хотите заменить текст через print на нотификейшн, для этого ищем строку с print, допустим это [CODE lang="java" title="FtHelper"] print("Заюзал дезориентацию!");[/CODE] Что бы заменить его на нотифку, вам надо написать [CODE lang="java" title="FtHelper"] Notificpenus.NOTIFICATION_MANAGER.add("Заюзал дезориентацию!","",2);[/CODE] 2 = Время, которое будет виден нотификейшн "Заюзал дезориентацию!" = текст который будет выводиться в нотифке Теперь нам нужно прописать наш нотификейшн, если вы хотите, что бы у вас была видна иконка Для этого в NotificationManager в методе draw пишем [CODE lang="java" title="Notifca"]if (this.text.contains("Заюзал")) { // "Заюзал" используется для установки иконки к нотифкам, в которых содержится этот текст im.expensive.utils.font.Fonts.nurik[16].drawString(stack,"G",(double)(XStart + 4), (double) (posY + 20.0F), -1); }[/CODE] После этого ваши нотифки будут рендериться с иконкой! Спасибо всем, кто полностью прочитал пост, жду ваших мега оценок под постом