Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Визуальная часть Potions hud sk3d wild 1.21.4

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
7 Мар 2025
Сообщения
97
Реакции
2
Выберите загрузчик игры
  1. Vanilla
шрифты говно

SS -
1773417552284.png


Code -
сарделька:
Expand Collapse Copy
package dev.sk3d.display.hud;

import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.EaseOut;
import dev.sk3d.features.impl.render.Hud;
import dev.sk3d.utils.display.render.post.KawaseBlur;
import dev.sk3d.utils.interactions.interact.PlayerInteractionHelper;
import dev.sk3d.utils.theme.ThemeManager;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
import net.minecraft.network.packet.s2c.play.RemoveEntityStatusEffectS2CPacket;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Formatting;
import dev.sk3d.utils.client.managers.api.draggable.AbstractDraggable;
import dev.sk3d.common.animation.Animation;
import dev.sk3d.common.animation.Direction;
import dev.sk3d.utils.display.render.font.FontRenderer;
import dev.sk3d.utils.display.render.font.Fonts;
import dev.sk3d.utils.display.render.shape.ShapeProperties;
import dev.sk3d.utils.display.color.ColorAssist;
import dev.sk3d.utils.math.calc.Calculate;
import dev.sk3d.utils.display.render.geometry.Render2D;
import dev.sk3d.events.packet.PacketEvent;
import dev.sk3d.utils.client.sound.SoundManager;
import net.minecraft.text.Text;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import org.joml.Vector4f;

import java.awt.*;

public class Potions extends AbstractDraggable {
    private final List<Potion> list = new ArrayList<>();
    private static final RegistryEntry<StatusEffect>[] NEGATIVE_EFFECTS = new RegistryEntry[] {
            StatusEffects.POISON, StatusEffects.WITHER, StatusEffects.NAUSEA, StatusEffects.BLINDNESS,
            StatusEffects.HUNGER, StatusEffects.SLOWNESS, StatusEffects.MINING_FATIGUE, StatusEffects.INSTANT_DAMAGE,
            StatusEffects.WEAKNESS, StatusEffects.LEVITATION, StatusEffects.UNLUCK, StatusEffects.BAD_OMEN
    };
    private long lastEffectChange = 0;
    private RegistryEntry<StatusEffect> currentRandomEffect = StatusEffects.SPEED;
    
    private final Map<String, StatusEffectInstance> activeEffects = new HashMap<>();
    private final Map<String, Boolean> warnedEffects = new HashMap<>();

    public Potions() {
        super("Potions", 200, 40, 80, 23, true);
        this.scaleAnimation = new EaseOut().setValue(1).setMs(100);
    }

    @Override
    public boolean visible() {
        return !list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0) {
            FontRenderer HAWENFont = Fonts.getSize(15, Fonts.Type.HAWEN);
            float pX = getX() + getWidth() - HAWENFont.getStringWidth("p") - 8;
            float pY = getY() + 9.5f;
            float pWidth = HAWENFont.getStringWidth("p");
            float pHeight = HAWENFont.getStringHeight("p");
            
            if (mouseX >= pX && mouseX <= pX + pWidth && mouseY >= pY && mouseY <= pY + pHeight) {
               List<String> selected = new ArrayList<>(Hud.getInstance().interfaceSettings.getSelected());
                selected.remove("Potions");
                Hud.getInstance().interfaceSettings.setSelected(selected);
                return true;
            }
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public void tick() {
        list.removeIf(p -> p.anim.isFinished(Direction.BACKWARDS));
        list.forEach(p -> p.effect.update(mc.player, null));
        
        if (Hud.getInstance().notificationSettings.isSelected("Заканчивающемся зелье") && !PlayerInteractionHelper.nullCheck()) {
            List<String> effectsToRemove = new ArrayList<>();
            for (Map.Entry<String, StatusEffectInstance> entry : activeEffects.entrySet()) {
                String effectKey = entry.getKey();
                StatusEffectInstance trackedEffect = entry.getValue();
                
                boolean stillActive = false;
                if (mc.player != null) {
                    for (StatusEffectInstance activeEffect : mc.player.getStatusEffects()) {
                        if (activeEffect.getEffectType().getIdAsString().equals(trackedEffect.getEffectType().getIdAsString())) {
                            stillActive = true;
                            activeEffects.put(effectKey, activeEffect);
                            
                            int remainingTicks = activeEffect.getDuration();
                            int warningTicks = 200;
                            boolean alreadyWarned = warnedEffects.getOrDefault(effectKey, false);
                            
                            if (remainingTicks <= warningTicks && remainingTicks > 0 && !alreadyWarned) {
                                sendPotionEndingSoonNotification(activeEffect);
                                warnedEffects.put(effectKey, true);
                            }
                            
                            if (remainingTicks > warningTicks) {
                                warnedEffects.remove(effectKey);
                            }
                            
                            break;
                        }
                    }
                }
                
                if (!stillActive) {
                    sendPotionEndedNotification(trackedEffect);
                    effectsToRemove.add(effectKey);
                    warnedEffects.remove(effectKey);
                }
            }
            effectsToRemove.forEach(activeEffects::remove);
        }
        
        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastEffectChange >= 1000) {
                List<RegistryEntry<StatusEffect>> effects = new ArrayList<>();
                for (Identifier id : Registries.STATUS_EFFECT.getIds()) {
                    Registries.STATUS_EFFECT.getEntry(id).ifPresent(effects::add);
                }
                if (!effects.isEmpty()) {
                    currentRandomEffect = effects.get(new Random().nextInt(effects.size()));
                    lastEffectChange = currentTime;
                }
            }
        }
    }

    @Override
    public void packet(PacketEvent e) {
        switch (e.getPacket()) {
            case EntityStatusEffectS2CPacket effect -> {
                if (!PlayerInteractionHelper.nullCheck() && effect.getEntityId() == Objects.requireNonNull(mc.player).getId()) {
                    RegistryEntry<StatusEffect> effectId = effect.getEffectId();
                    String effectKey = effectId.getIdAsString();
                    
                    
                    boolean isNewEffect = !activeEffects.containsKey(effectKey);
                    
                    list.stream().filter(p -> p.effect.getEffectType().getIdAsString().equals(effectKey)).forEach(s -> s.anim.setDirection(Direction.BACKWARDS));
                    StatusEffectInstance newEffect = new StatusEffectInstance(effectId, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.shouldShowParticles(), effect.shouldShowIcon());
                    list.add(new Potion(newEffect, new Decelerate().setMs(150).setValue(1.0F)));
                    
                    
                    activeEffects.put(effectKey, newEffect);
                    
                    
                    if (isNewEffect && Hud.getInstance().notificationSettings.isSelected("Полученном зелье")) {
                        sendPotionReceivedNotification(newEffect);
                    }
                }
            }
            case RemoveEntityStatusEffectS2CPacket effect -> {
                String effectKey = effect.effect().getIdAsString();
                list.stream().filter(s -> s.effect.getEffectType().getIdAsString().equals(effectKey)).forEach(s -> s.anim.setDirection(Direction.BACKWARDS));
                
                StatusEffectInstance removedEffect = activeEffects.remove(effectKey);
                if (removedEffect != null && Hud.getInstance().notificationSettings.isSelected("Заканчивающемся зелье")) {
                    sendPotionEndedNotification(removedEffect);
                }
                warnedEffects.remove(effectKey);
            }
            case PlayerRespawnS2CPacket p -> {
                list.clear();
                activeEffects.clear();
                warnedEffects.clear();
            }
            case GameJoinS2CPacket p -> {
                list.clear();
                activeEffects.clear();
                warnedEffects.clear();
            }
            default -> {}
        }
    }

    @Override
    public void drawDraggable(DrawContext context) {
        MatrixStack matrix = context.getMatrices();
        FontRenderer fontName = Fonts.getSize(13, Fonts.Type.SuisseIntlSemiBold);
        FontRenderer fontLevel = Fonts.getSize(12, Fonts.Type.BOLD);
        FontRenderer fontTime = Fonts.getSize(12, Fonts.Type.MontserratBlack);

        float iconSize = 16f;
        float iconPadding = 3f;
        float spacing = 3f;
        float panelHeight = 25f;
        float currentY = getY();
        float maxWidth = 0;
        
        float timeBoxWidth = 28f;

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            float namePanelWidth = calculateNamePanelWidth("Example", "lvl 1", fontName, fontLevel);
            float totalWidth = iconPadding + iconSize + 3f + namePanelWidth + 3f + timeBoxWidth + 4f;
            
            drawPotionPanel(matrix, getX(), currentY, totalWidth, panelHeight, iconSize, iconPadding,
                    currentRandomEffect, "Example", "lvl 1", "**:**", 1.0f, fontName, fontLevel, fontTime, false, namePanelWidth, timeBoxWidth);
            setWidth((int) totalWidth);
            setHeight((int) panelHeight);
        } else {
            int visibleCount = 0;
            for (Potion potion : list) {
                StatusEffectInstance effect = potion.effect;
                float animation = potion.anim.getOutput().floatValue();
                
                if (animation > 0.01f) {
                    int amplifier = effect.getAmplifier();
                    String name = effect.getEffectType().value().getName().getString();
                    String duration = getDuration(effect);
                    String level = amplifier > 0 ? "lvl " + (amplifier + 1) : "lvl 1";
                    boolean isBad = isBadEffect(effect.getEffectType());
                    
                    float namePanelWidth = calculateNamePanelWidth(name, level, fontName, fontLevel);
                    float totalWidth = iconPadding + iconSize + 3f + namePanelWidth + 3f + timeBoxWidth + 4f;
                    maxWidth = Math.max(maxWidth, totalWidth);
                    
                    drawPotionPanel(matrix, getX(), currentY, totalWidth, panelHeight, iconSize, iconPadding,
                            effect.getEffectType(), name, level, duration, animation, fontName, fontLevel, fontTime, isBad, namePanelWidth, timeBoxWidth);
                    
                    currentY += (panelHeight + spacing) * animation;
                    visibleCount++;
                }
            }
            
            setWidth((int) maxWidth);
            setHeight((int) (visibleCount * (panelHeight + spacing) - spacing));
        }
    }

    private float calculateNamePanelWidth(String name, String level, FontRenderer fontName, FontRenderer fontLevel) {
        float nameWidth = fontName.getStringWidth(name);
        float levelWidth = fontLevel.getStringWidth(level);
        float minWidth = 62f;
        float calculatedWidth = 10f + nameWidth + 6f + levelWidth + 10f;
        return Math.max(minWidth, calculatedWidth);
    }

    private void drawPotionPanel(MatrixStack matrix, float x, float y, float width, float height,
                                  float iconSize, float iconPadding, RegistryEntry<StatusEffect> effectType,
                                  String name, String level, String duration, float animation,
                                  FontRenderer fontName, FontRenderer fontLevel, FontRenderer fontTime, boolean isBad,
                                  float namePanelWidth, float timeBoxWidth) {
        
        float centerX = x + width / 2f;
        float centerY = y + height / 2f;
        
        Calculate.scale(matrix, centerX, centerY, animation, animation, () -> {
            if (Hud.blur.isValue()) {
                Render2D.rectangleWithMask(matrix.peek().getPositionMatrix(), x, y, width, height, 5f, 0,
                        KawaseBlur.INSTANCE.fbos.getFirst().getColorAttachment());
            }
            
            rectangle.render(ShapeProperties.create(matrix, x, y, width, height)
                    .round(5f)
                    .color(ThemeManager.BackgroundGui.getColor())
                    .build());
            
            float iconX = x + iconPadding;
            float iconY = y + (height - iconSize) / 2f;
            
            rectangle.render(ShapeProperties.create(matrix, iconX, iconY, iconSize, iconSize)
                    .round(new Vector4f(3f, 3f, 5f, 5f))
                    .color(ThemeManager.BackgroundSettings.getColor())
                    .build());
            

            Render2D.drawSprite(matrix, mc.getStatusEffectSpriteManager().getSprite(effectType),
                    iconX + 3.5f, iconY + 3.5f, 9, 9, -1);
            
            float timeBoxHeight = 16f;
            float timeBoxX = x + width - timeBoxWidth - 4f;
            float timeBoxY = y + (height - timeBoxHeight) / 2f;
            
            rectangle.render(ShapeProperties.create(matrix, timeBoxX, timeBoxY, timeBoxWidth, timeBoxHeight)
                    .round(new Vector4f(5f, 5f, 3f, 3f))
                    .color(ThemeManager.BackgroundSettings.getColor())
                    .build());
            
            float timeWidth = fontTime.getStringWidth(duration);
            int timeColor = ThemeManager.textColor.getColor();
            float timeTextHeight = fontTime.getStringHeight(duration);
            fontTime.drawString(matrix, duration, timeBoxX + (timeBoxWidth - timeWidth) / 2f, timeBoxY + (timeBoxHeight - timeTextHeight) / 2f + 6f, timeColor);
            

            float namePanelX = iconX + iconSize + 3f;
            float namePanelHeight = 16f;
            float namePanelY = y + (height - namePanelHeight) / 2f;
            
            rectangle.render(ShapeProperties.create(matrix, namePanelX, namePanelY, namePanelWidth, namePanelHeight)
                    .round(3f)
                    .color(ThemeManager.BackgroundSettings.getColor())
                    .build());
            
      
            float nameWidth = fontName.getStringWidth(name);
            float levelWidth = fontLevel.getStringWidth(level);
            float nameTextHeight = fontName.getStringHeight(name);
            float textStartX = namePanelX + 5f;
            float textY = namePanelY + (namePanelHeight - nameTextHeight) / 2f + 6f;
            
        
            int nameColor = isBad ? new Color(255, 85, 75, 255).getRGB() : ThemeManager.textColor.getColor();
            fontName.drawString(matrix, name, textStartX, textY, nameColor);
            
    
            float levelX = namePanelX + namePanelWidth - levelWidth - 5f;
            fontLevel.drawString(matrix, level, levelX, textY + 1f, ThemeManager.textColor.getColor());
        });
    }

    private String getDuration(StatusEffectInstance pe) {
        int var1 = pe.getDuration();
        int mins = var1 / 1200;
        return pe.isInfinite() || mins > 60 ? "**:**" : mins + ":" + String.format("%02d", (var1 % 1200) / 20);
    }

    private boolean isBadEffect(RegistryEntry<StatusEffect> effect) {
        for (RegistryEntry<StatusEffect> negativeEffect : NEGATIVE_EFFECTS) {
            if (effect == negativeEffect) {
                return true;
            }
        }
        return false;
    }

    private void sendPotionReceivedNotification(StatusEffectInstance effect) {
        String effectName = effect.getEffectType().value().getName().getString();
        String message = effectName + " получен!";
        Notifications.getInstance().addList(Text.literal(message), 1000, SoundManager.ENABLE_MODULE, false, null, effect.getEffectType());
        SoundManager.playSound(SoundManager.ENABLE_MODULE);
    }
    
    private void sendPotionEndedNotification(StatusEffectInstance effect) {
        String effectName = effect.getEffectType().value().getName().getString();
        String message = effectName + " закончился!";
        Notifications.getInstance().addList(Text.literal(message), 1000, SoundManager.DISABLE_MODULE, false, null, effect.getEffectType());
        SoundManager.playSound(SoundManager.DISABLE_MODULE);
    }
    
    private void sendPotionEndingSoonNotification(StatusEffectInstance effect) {
        String effectName = effect.getEffectType().value().getName().getString();
        String message = effectName + " закончится через 10 секунд!";
        Notifications.getInstance().addList(Text.literal(message), 1000, null, false, null, effect.getEffectType());
    }
    

    private record Potion(StatusEffectInstance effect, Animation anim) {}
}
 

Похожие темы

Назад
Сверху Снизу