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

Визуальная часть Targed ESP | Zenith recode

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
26 Окт 2024
Сообщения
10
Реакции
0
Выберите загрузчик игры
  1. Fabric
Салют югейм, сливаю вам Targed ESP на Zenith recode, чо то делал через клауд опус, чё-то сам.
Не бейте ногами пж первая тема.
SS: Прикреплён снизу
есп:
Expand Collapse Copy
package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import org.joml.Matrix4f;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ColorSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.modules.impl.combat.Aura;
import zenith.zov.Zenith;
import zenith.zov.utility.render.display.base.color.ColorRGBA;

import java.awt.*;

import static zenith.zov.utility.math.MathUtil.interpolate;

@ModuleAnnotation(name = "TargetESP", category = Category.RENDER, description = "Подсвечивает цель ауры")
public final class TargetESP extends Module {

    public static final TargetESP INSTANCE = new TargetESP();

    // Режим
    public final ModeSetting mode = new ModeSetting("Режим", "Души", "Кружок", "Призраки", "Кристаллы");
    public final BooleanSetting aimEsp = new BooleanSetting("При наведении", false);
    
    // Настройки для Душ
    private final ModeSetting soulsMovement = new ModeSetting("Движение душ", () -> mode.is("Души"), "Стандарт", "Волна", "Спираль", "Пульс", "Сквозь");
    private final NumberSetting soulsSpeed = new NumberSetting("Скорость", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsSize = new NumberSetting("Размер", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsDistance = new NumberSetting("Дистанция", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsCount = new NumberSetting("Количество", 4, 2, 8, 1, () -> mode.is("Души"));
    private final NumberSetting soulsLength = new NumberSetting("Длина хвоста", 10, 5, 20, 1, () -> mode.is("Души"));
    private final NumberSetting soulsVerticalSpeed = new NumberSetting("Вертикальная скорость", 1.0f, 0.1f, 3.0f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    private final NumberSetting soulsVerticalRange = new NumberSetting("Вертикальный диапазон", 0.5f, 0.1f, 1.5f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    
    // Настройки для Призраков (упрощённые - без разных движений)
    private final NumberSetting ghostSpeed = new NumberSetting("Скорость призраков", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostRadius = new NumberSetting("Радиус призраков", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostSize = new NumberSetting("Размер призраков", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostTrailLength = new NumberSetting("Длина хвоста призраков", 10, 5, 20, 1, () -> mode.is("Призраки"));
    private final NumberSetting ghostCount = new NumberSetting("Количество призраков", 3, 1, 6, 1, () -> mode.is("Призраки"));
    
    // Настройки для Кристаллов
    private final NumberSetting crystalSpeed = new NumberSetting("Скорость вращения", 0.5f, 0.1f, 2.0f, 0.1f, () -> mode.is("Кристаллы"));
    private final NumberSetting crystalSize = new NumberSetting("Размер кристаллов", 0.05f, 0.02f, 0.15f, 0.01f, () -> mode.is("Кристаллы"));
    
    // Цвета
    private final BooleanSetting useThemeColor = new BooleanSetting("Цвет из темы", true);
    private final ColorSetting mainColor = new ColorSetting("Основной цвет", new ColorRGBA(255, 100, 100, 255), () -> !useThemeColor.isEnabled());
    private final BooleanSetting hitColorEnabled = new BooleanSetting("Цвет при ударе", true, () -> !useThemeColor.isEnabled());
    private final ColorSetting hitColor = new ColorSetting("Цвет удара", new ColorRGBA(255, 0, 0, 255), () -> !useThemeColor.isEnabled() && hitColorEnabled.isEnabled());

    private final Identifier bloomTexture = Identifier.of("zenith", "textures/particles/bloom.png");
    private final Identifier sparkTexture = Identifier.of("zenith", "textures/particles/spark.png");
    
    private LivingEntity target;
    private LivingEntity lastTarget;
    private double scale = 0.0D;
    
    // Кэшированные объекты
    private final MatrixStack reusableMatrices = new MatrixStack();
    
    // Кристаллы
    private LivingEntity lastCrystalTarget = null;
    private final java.util.List<CrystalData> crystalList = new java.util.ArrayList<>();
    private float crystalRotationAngle = 0;
    
    private TargetESP() {
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (!this.isEnabled()) return;
            
        updateTarget();
        
        LivingEntity currentTarget = target != null ? target : lastTarget;
        if (currentTarget == null) return;
        
        if (target != null) {
            scale = Math.min(scale + 0.1, 1.0);
        } else {
            scale = Math.max(scale - 0.1, 0.0);
        }
        
        if (scale <= 0) return;
        
        float hitProgress = getHitProgress(currentTarget);
        float anim = (float) scale;
        
        switch (mode.get()) {
            case "Души" -> renderSouls(currentTarget, anim, hitProgress);
            case "Кружок" -> renderCircle(currentTarget, event.getMatrix(), event.getPartialTicks(), hitProgress);
            case "Призраки" -> renderGhosts(currentTarget, anim, hitProgress);
            case "Кристаллы" -> renderCrystals(currentTarget, event.getMatrix(), anim, hitProgress);
        }
    }
    
    private void updateTarget() {
        LivingEntity newTarget = Aura.INSTANCE.getTarget();
        if (aimEsp.isEnabled() && mc.crosshairTarget != null &&
            mc.crosshairTarget.getType() == HitResult.Type.ENTITY &&
            mc.crosshairTarget instanceof net.minecraft.util.hit.EntityHitResult entityHit &&
            entityHit.getEntity() instanceof LivingEntity living) {
            if (living.isAlive() && living != mc.player) {
                newTarget = living;
            }
        }
        this.target = newTarget;
        
        if (this.target != null) {
            this.lastTarget = this.target;
        }
    }
    
    private float getHitProgress(LivingEntity target) {
        return target.hurtTime > 0 ? Math.min(target.hurtTime / 10f, 1f) : 0f;
    }
    
    private int getColor(float hitProgress) {
        int base;
        if (useThemeColor.isEnabled()) {
            base = Zenith.getInstance().getThemeManager().getClientColor(0).getRGB();
        } else {
            base = mainColor.getColor().getRGB();
        }
        
        if (!useThemeColor.isEnabled() && hitColorEnabled.isEnabled() && hitProgress > 0) {
            return blendColors(base, hitColor.getColor().getRGB(), hitProgress);
        }
        return base;
    }
    
    private int getColorStyle(int hue) {
        return Color.getHSBColor(hue / 360f, 1.0f, 1.0f).getRGB();
    }


    // ============ SOULS (Души) ============
    private void renderSouls(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
        
        String movement = soulsMovement.get();
        
        // Режим "Сквозь" - души летают через игрока
        if (movement.equals("Сквозь")) {
            renderSoulsThrough(target, anim, hitProgress);
            return;
        }
        
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double tX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double tY = interpolate(target.prevY, target.getY(), delta) - camPos.y;
        double tZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
        
        boolean canSee = mc.player.canSee(target);
        double iAge = interpolate(mc.player.age - 1, mc.player.age, delta);
        float halfHeight = target.getHeight() / 2 + 0.2F;
        float baseWidth = target.getWidth() + 0.2f;
        float minY = 0.2f;
        float maxY = target.getHeight() - 0.2F;

        float hitEffect = Math.min(hitProgress * 2f, 2f);
        float acceleration = (float) Math.sin(hitEffect * Math.PI) * 0.18f;
        float bany = (float) Math.sin(hitEffect * Math.PI) * -0.04f;
        
        float speed = soulsSpeed.getCurrent();
        float size = soulsSize.getCurrent();
        float distance = soulsDistance.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int length = (int) soulsLength.getCurrent();
        float vertSpeed = soulsVerticalSpeed.getCurrent();
        float vertRange = soulsVerticalRange.getCurrent();

        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        
        if (canSee) {
            RenderSystem.enableDepthTest();
            RenderSystem.depthMask(false);
        } else {
            RenderSystem.disableDepthTest();
        }

        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();

        int baseColorCached = getColor(hitProgress);
        float sizeSpeedFactor = 0.6f + speed * 0.1f;
        
        for (int j = 0; j < count; j++) {
            double jAngleOffset = j * (360.0 / count);
            double spiralJ = iAge * vertSpeed * 0.5 + j;
            
            for (int i = 0; i <= length; i++) {
                double baseAngle = ((i / 2F + iAge * speed * 2.0f) * length + jAngleOffset) % (length * 180);
                double radians = Math.toRadians(baseAngle);

                float distanceMultiplier = 1.0f + acceleration;
                float offset = ((float) (i + length) / (length + length));

                double yOffset = calculateYOffset(movement, iAge, i, j, halfHeight, minY, maxY, vertSpeed, vertRange);
                
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));

                double finalWidth = baseWidth * distanceMultiplier * distance;
                
                if (movement.equals("Спираль")) {
                    double spiralFactor = 1.0 + Math.sin(spiralJ) * 0.3;
                    finalWidth *= spiralFactor;
                }
                
                reusableMatrices.translate(tX + Math.cos(radians) * finalWidth, tY + yOffset, tZ + Math.sin(radians) * finalWidth);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
                
                int blendedColor = blendColors(baseColorCached, getColorStyle((int) (180 * offset)), 0.3f);
                int color = applyOpacity(blendedColor, offset * anim);
                
                float particleSize = size * offset * sizeSpeedFactor + bany;
                float halfSize = particleSize / 2;
                
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(color);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(color);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(color);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(color);
            }
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());

        if (canSee) {
            RenderSystem.depthMask(true);
        }
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
    
    // ============ SOULS THROUGH (Души сквозь) - летают через игрока ============
    private void renderSoulsThrough(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
        
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
        
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
        
        float speed = soulsSpeed.getCurrent() * 50f;
        float radius = soulsDistance.getCurrent() * 0.55f;
        float size = soulsSize.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int trailLength = (int) soulsLength.getCurrent() * 15;
        double distanceStep = 1.5;
        
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture); // Используем bloom как обычные души
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
        
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
        
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
            
            double[][] points = new double[count][];
            for (int g = 0; g < count; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / count);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
            
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
            
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
            
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
                
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
                
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
                
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
        
        BufferRenderer.drawWithGlobalProgram(buffer.end());
        
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }

    
    // ============ GHOSTS (Призраки) - летают через игрока ============
    private void renderGhosts(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
        
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
        
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
        
        float speed = ghostSpeed.getCurrent() * 50f;
        float radius = ghostRadius.getCurrent() * 0.55f;
        float size = ghostSize.getCurrent();
        int trailLength = (int) ghostTrailLength.getCurrent() * 15;
        double distanceStep = 1.5;
        
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, sparkTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
        
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
        
        int numGhosts = (int) ghostCount.getCurrent();
        
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
            
            double[][] points = new double[numGhosts][];
            for (int g = 0; g < numGhosts; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / numGhosts);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
            
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
            
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
            
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
                
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
                
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
                
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
        
        BufferRenderer.drawWithGlobalProgram(buffer.end());
        
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
    
    private double calculateYOffset(String movement, double iAge, int i, int j, float halfHeight, float minY, float maxY, float vertSpeed, float vertRange) {
        double baseY = halfHeight;
        
        switch (movement) {
            case "Волна" -> {
                double wave = Math.sin(iAge * vertSpeed + j * Math.PI / 2 + i * 0.3) * vertRange;
                return baseY + wave;
            }
            case "Спираль" -> {
                double spiral = Math.sin(iAge * vertSpeed * 0.7 + j) * vertRange;
                double heightProgress = (Math.sin(iAge * vertSpeed * 0.3 + j * 0.5) + 1) / 2;
                return minY + (maxY - minY) * heightProgress + spiral * 0.5;
            }
            case "Пульс" -> {
                double pulse = Math.sin(iAge * vertSpeed) * vertRange;
                double individualOffset = Math.sin(j * Math.PI / 2) * 0.2;
                return baseY + pulse + individualOffset;
            }
            default -> {
                double sinQuad = Math.sin(Math.toRadians(iAge * 0.7 + i * (j + halfHeight)) * 1.1) / 2;
                double adjustedSin = (j % 2 == 0) ? sinQuad : -sinQuad;
                return minY + (adjustedSin + 0.5) * (maxY - minY);
            }
        }
    }
    
    // ============ CIRCLE (Кружок) ============
    private void renderCircle(LivingEntity target, MatrixStack matrices, float tickDelta, float hitProgress) {
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double x = MathHelper.lerp(tickDelta, target.lastRenderX, target.getX()) - camPos.x;
        double z = MathHelper.lerp(tickDelta, target.lastRenderZ, target.getZ()) - camPos.z;
        double y = MathHelper.lerp(tickDelta, target.lastRenderY, target.getY()) - camPos.y +
                   Math.min(Math.sin(System.currentTimeMillis() / 400.0) + 0.95, target.getHeight());

        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);

        int baseColor = getColor(hitProgress);
        float r = ((baseColor >> 16) & 0xFF) / 255f;
        float g = ((baseColor >> 8) & 0xFF) / 255f;
        float b = (baseColor & 0xFF) / 255f;

        float alpha = (float) scale;
        float radius = target.getWidth() * 0.8f;

        for (float i = 0; i <= Math.PI * 2 + (Math.PI * 5 / 100); i += Math.PI * 5 / 100) {
            double vecX = x + radius * Math.cos(i);
            double vecZ = z + radius * Math.sin(i);

            buffer.vertex(matrix, (float) vecX, (float) (y - Math.cos(System.currentTimeMillis() / 400.0) / 2), (float) vecZ)
                  .color(r, g, b, 0.01f * alpha);
            buffer.vertex(matrix, (float) vecX, (float) y, (float) vecZ)
                  .color(r, g, b, 1f * alpha);
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());
        
        RenderSystem.disableBlend();
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
    
    // ============ UTILS ============
    private int applyOpacity(int baseColor, float alpha) {
        int r = (baseColor >> 16) & 0xFF;
        int g = (baseColor >> 8) & 0xFF;
        int b = baseColor & 0xFF;
        int a = (int) (255 * Math.min(alpha, 1f));
        return (a << 24) | (r << 16) | (g << 8) | b;
    }
    
    private int blendColors(int color1, int color2, float ratio) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
        
        int r = (int) (r1 + (r2 - r1) * ratio);
        int g = (int) (g1 + (g2 - g1) * ratio);
        int b = (int) (b1 + (b2 - b1) * ratio);
        
        return (0xFF << 24) | (r << 16) | (g << 8) | b;
    }
    
    private int setAlpha(int color, int alpha) {
        return (alpha << 24) | (color & 0x00FFFFFF);
    }

    
    // ============ CRYSTALS (Кристаллы) ============
    private void renderCrystals(LivingEntity target, MatrixStack ms, float anim, float hitProgress) {
        if (target == null) return;
        
        if (crystalList.isEmpty() || target != lastCrystalTarget) {
            createCrystals();
            lastCrystalTarget = target;
        }
        
        RenderSystem.enableDepthTest();
        
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double tX = MathHelper.lerp(delta, target.lastRenderX, target.getX()) - camPos.x;
        double tY = MathHelper.lerp(delta, target.lastRenderY, target.getY()) - camPos.y;
        double tZ = MathHelper.lerp(delta, target.lastRenderZ, target.getZ()) - camPos.z;
        
        float rotSpeed = crystalSpeed.getCurrent();
        crystalRotationAngle = (crystalRotationAngle + rotSpeed) % 360;
        
        ms.push();
        ms.translate(tX, tY, tZ);
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(crystalRotationAngle));
        
        Camera camera = mc.gameRenderer.getCamera();
        int baseColor = getColor(hitProgress);
        float size = crystalSize.getCurrent();
        
        for (CrystalData crystal : crystalList) {
            renderCrystal(ms, crystal, baseColor, anim, camera, size);
        }
        
        ms.pop();
        RenderSystem.enableDepthTest();
    }
    
    private void createCrystals() {
        crystalList.clear();
        
        // 14 кристаллов как в оригинале
        crystalList.add(new CrystalData(new Vec3d(0, 0.85, 0.8), new Vec3d(-49, 0, 40)));
        crystalList.add(new CrystalData(new Vec3d(0.2, 0.85, -0.675), new Vec3d(35, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.6, 1.35, 0.6), new Vec3d(-30, 0, 35)));
        crystalList.add(new CrystalData(new Vec3d(-0.74, 1.05, 0.4), new Vec3d(-25, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.74, 0.95, -0.4), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.475, 0.85, -0.375), new Vec3d(30, 0, -25)));
        crystalList.add(new CrystalData(new Vec3d(0, 1.35, -0.6), new Vec3d(45, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.85, 0.7, 0.1), new Vec3d(-30, 0, 30)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 1.35, -0.3), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.3, 1.35, 0.55), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 0.75, 0), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.2, 0.65, -0.7), new Vec3d(0, 0, 0)));
    }
    
    private void renderCrystal(MatrixStack ms, CrystalData crystal, int baseColor, float anim, Camera camera, float size) {
        ms.push();
        ms.translate(crystal.position.x, crystal.position.y, crystal.position.z);
        
        float pulsation = 1.0f + (float) (Math.sin(System.currentTimeMillis() / 500.0) * 0.1f);
        ms.scale(pulsation, pulsation, pulsation);
        
        float selfRotation = (System.currentTimeMillis() % 36000) / 100.0f * crystal.rotationSpeed;
        ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees((float) crystal.rotation.x));
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((float) crystal.rotation.y + selfRotation));
        ms.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((float) crystal.rotation.z));
        
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        
        // Внутреннее свечение
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        drawCrystalShape(ms, baseColor, 0.15f, true, anim, size);
        
        // Основной кристалл
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        drawCrystalShape(ms, baseColor, 0.4f, true, anim, size);
        
        // Внешнее свечение
        RenderSystem.depthMask(false);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        ms.push();
        ms.scale(1.3f, 1.3f, 1.3f);
        drawCrystalShape(ms, baseColor, 0.2f, true, anim, size);
        ms.pop();
        
        // Bloom сфера
        drawBloomSphere(ms, baseColor, anim, camera, size);
        
        RenderSystem.depthMask(true);
        RenderSystem.disableBlend();
        RenderSystem.enableCull();
        ms.pop();
    }
    
    private void drawCrystalShape(MatrixStack ms, int baseColor, float alpha, boolean filled, float anim, float size) {
        BufferBuilder buffer = Tessellator.getInstance().begin(
            filled ? VertexFormat.DrawMode.TRIANGLES : VertexFormat.DrawMode.DEBUG_LINES,
            VertexFormats.POSITION_COLOR
        );
        
        float s = size;
        float h_prism = size * 1.2f;
        float h_pyramid = size * 2.0f;
        int numSides = 6; // Меньше граней для более гладкого вида
        
        java.util.List<Vec3d> topVertices = new java.util.ArrayList<>();
        java.util.List<Vec3d> bottomVertices = new java.util.ArrayList<>();
        
        for (int i = 0; i < numSides; i++) {
            float angle = (float) (2 * Math.PI * i / numSides);
            float x = (float) (s * Math.cos(angle));
            float z = (float) (s * Math.sin(angle));
            topVertices.add(new Vec3d(x, h_prism / 2, z));
            bottomVertices.add(new Vec3d(x, -h_prism / 2, z));
        }
        
        Vec3d vTop = new Vec3d(0, h_prism / 2 + h_pyramid, 0);
        Vec3d vBottom = new Vec3d(0, -h_prism / 2 - h_pyramid, 0);
        
        int finalColor = setAlpha(baseColor, (int) (alpha * 255 * anim));
        
        // Боковые грани призмы
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            Vec3d v3 = topVertices.get((i + 1) % numSides);
            Vec3d v4 = topVertices.get(i);
            if (filled) {
                drawTriangle(ms, buffer, v1, v2, v3, finalColor);
                drawTriangle(ms, buffer, v1, v3, v4, finalColor);
            }
        }
        
        // Верхняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = topVertices.get(i);
            Vec3d v2 = topVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vTop, v1, v2, finalColor);
        }
        
        // Нижняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vBottom, v2, v1, finalColor);
        }
        
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
    
    private void drawTriangle(MatrixStack ms, BufferBuilder bb, Vec3d v1, Vec3d v2, Vec3d v3, int color) {
        Matrix4f matrix = ms.peek().getPositionMatrix();
        bb.vertex(matrix, (float)v1.x, (float)v1.y, (float)v1.z).color(color);
        bb.vertex(matrix, (float)v2.x, (float)v2.y, (float)v2.z).color(color);
        bb.vertex(matrix, (float)v3.x, (float)v3.y, (float)v3.z).color(color);
    }
    
    private void drawBloomSphere(MatrixStack ms, int baseColor, float anim, Camera camera, float size) {
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.depthMask(false);
        
        int bloomColor = setAlpha(baseColor, (int) (0.5f * 25 * anim));
        float bloomSize = size * 15.0f;
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        int segments = 6;
        
        for (int i = 0; i < segments; i++) {
            ms.push();
            float angle = (360.0f / segments) * i;
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle));
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
            ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
            
            Matrix4f matrix = ms.peek().getPositionMatrix();
            BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
            buffer.vertex(matrix, -bloomSize / 2, -bloomSize / 2, 0).texture(0, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, -bloomSize / 2, 0).texture(1, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, bloomSize / 2, 0).texture(1, 0).color(bloomColor);
            buffer.vertex(matrix, -bloomSize / 2, bloomSize / 2, 0).texture(0, 0).color(bloomColor);
            BufferRenderer.drawWithGlobalProgram(buffer.end());
            ms.pop();
        }
        
        RenderSystem.depthMask(true);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
    
    private static class CrystalData {
        final Vec3d position;
        final Vec3d rotation;
        final float rotationSpeed;
        
        CrystalData(Vec3d position, Vec3d rotation) {
            this.position = position;
            this.rotation = rotation;
            this.rotationSpeed = 0.5f + (float)(Math.random() * 1.5f);
        }
    }
}
}
Screenshot 2025-12-09 183614.png
1765298272781.png
 
бля типу настолько лень убрать коменты от нейронки что он это вылаживает сюда сука
я же говорю что через нейронку делал часть, в чём проблема? если надо сам удали я тебе код и так слил
 
я же говорю что через нейронку делал часть, в чём проблема? если надо сам удали я тебе код и так слил
1. Где кристалы? На SS
2. Каким надо быть ебейщим типом чтобы закидывать на югейм с коментами от ии
3. Говнокод на 750 строк...
 
1. Где кристалы? На SS
2. Каким надо быть ебейщим типом чтобы закидывать на югейм с коментами от ии
3. Говнокод на 750 строк...
алё, я говорил что код написан через нейронку и мной. кристали сами посмотрите в игре если надо мой говно код.
таргет есп на 750 строк)
еще один блять
 
и чем эти призраки отличаются от сотни других на форуме? Они даж обрезают часть себя на втором скрине
призраки не отличаютсья просто готовый код на зенит, а на скрине это скриншот такой не удачный, в игре норм всё
 
бля типу настолько лень убрать коменты от нейронки что он это вылаживает сюда сука
ну он хотябы указал что делал с клоудом, уже сделал то что не делают большинство вайбкодеров тут
 
/del
1. Бесполезно, сейчас призраки есть везде еще и покрасивее намного, не нужная тема засоряет форум только
2. Гпт код, полный коментариев, не нужной воды и на 750 строк, зато молодец что сказал, много тут вайбкодеров которые выдают за свое
 
Салют югейм, сливаю вам Targed ESP на Zenith recode, чо то делал через клауд опус, чё-то сам.
Не бейте ногами пж первая тема.
SS: Прикреплён снизу
есп:
Expand Collapse Copy
package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import org.joml.Matrix4f;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ColorSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.modules.impl.combat.Aura;
import zenith.zov.Zenith;
import zenith.zov.utility.render.display.base.color.ColorRGBA;

import java.awt.*;

import static zenith.zov.utility.math.MathUtil.interpolate;

@ModuleAnnotation(name = "TargetESP", category = Category.RENDER, description = "Подсвечивает цель ауры")
public final class TargetESP extends Module {

    public static final TargetESP INSTANCE = new TargetESP();

    // Режим
    public final ModeSetting mode = new ModeSetting("Режим", "Души", "Кружок", "Призраки", "Кристаллы");
    public final BooleanSetting aimEsp = new BooleanSetting("При наведении", false);
   
    // Настройки для Душ
    private final ModeSetting soulsMovement = new ModeSetting("Движение душ", () -> mode.is("Души"), "Стандарт", "Волна", "Спираль", "Пульс", "Сквозь");
    private final NumberSetting soulsSpeed = new NumberSetting("Скорость", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsSize = new NumberSetting("Размер", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsDistance = new NumberSetting("Дистанция", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsCount = new NumberSetting("Количество", 4, 2, 8, 1, () -> mode.is("Души"));
    private final NumberSetting soulsLength = new NumberSetting("Длина хвоста", 10, 5, 20, 1, () -> mode.is("Души"));
    private final NumberSetting soulsVerticalSpeed = new NumberSetting("Вертикальная скорость", 1.0f, 0.1f, 3.0f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    private final NumberSetting soulsVerticalRange = new NumberSetting("Вертикальный диапазон", 0.5f, 0.1f, 1.5f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
   
    // Настройки для Призраков (упрощённые - без разных движений)
    private final NumberSetting ghostSpeed = new NumberSetting("Скорость призраков", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostRadius = new NumberSetting("Радиус призраков", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostSize = new NumberSetting("Размер призраков", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostTrailLength = new NumberSetting("Длина хвоста призраков", 10, 5, 20, 1, () -> mode.is("Призраки"));
    private final NumberSetting ghostCount = new NumberSetting("Количество призраков", 3, 1, 6, 1, () -> mode.is("Призраки"));
   
    // Настройки для Кристаллов
    private final NumberSetting crystalSpeed = new NumberSetting("Скорость вращения", 0.5f, 0.1f, 2.0f, 0.1f, () -> mode.is("Кристаллы"));
    private final NumberSetting crystalSize = new NumberSetting("Размер кристаллов", 0.05f, 0.02f, 0.15f, 0.01f, () -> mode.is("Кристаллы"));
   
    // Цвета
    private final BooleanSetting useThemeColor = new BooleanSetting("Цвет из темы", true);
    private final ColorSetting mainColor = new ColorSetting("Основной цвет", new ColorRGBA(255, 100, 100, 255), () -> !useThemeColor.isEnabled());
    private final BooleanSetting hitColorEnabled = new BooleanSetting("Цвет при ударе", true, () -> !useThemeColor.isEnabled());
    private final ColorSetting hitColor = new ColorSetting("Цвет удара", new ColorRGBA(255, 0, 0, 255), () -> !useThemeColor.isEnabled() && hitColorEnabled.isEnabled());

    private final Identifier bloomTexture = Identifier.of("zenith", "textures/particles/bloom.png");
    private final Identifier sparkTexture = Identifier.of("zenith", "textures/particles/spark.png");
   
    private LivingEntity target;
    private LivingEntity lastTarget;
    private double scale = 0.0D;
   
    // Кэшированные объекты
    private final MatrixStack reusableMatrices = new MatrixStack();
   
    // Кристаллы
    private LivingEntity lastCrystalTarget = null;
    private final java.util.List<CrystalData> crystalList = new java.util.ArrayList<>();
    private float crystalRotationAngle = 0;
   
    private TargetESP() {
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (!this.isEnabled()) return;
           
        updateTarget();
       
        LivingEntity currentTarget = target != null ? target : lastTarget;
        if (currentTarget == null) return;
       
        if (target != null) {
            scale = Math.min(scale + 0.1, 1.0);
        } else {
            scale = Math.max(scale - 0.1, 0.0);
        }
       
        if (scale <= 0) return;
       
        float hitProgress = getHitProgress(currentTarget);
        float anim = (float) scale;
       
        switch (mode.get()) {
            case "Души" -> renderSouls(currentTarget, anim, hitProgress);
            case "Кружок" -> renderCircle(currentTarget, event.getMatrix(), event.getPartialTicks(), hitProgress);
            case "Призраки" -> renderGhosts(currentTarget, anim, hitProgress);
            case "Кристаллы" -> renderCrystals(currentTarget, event.getMatrix(), anim, hitProgress);
        }
    }
   
    private void updateTarget() {
        LivingEntity newTarget = Aura.INSTANCE.getTarget();
        if (aimEsp.isEnabled() && mc.crosshairTarget != null &&
            mc.crosshairTarget.getType() == HitResult.Type.ENTITY &&
            mc.crosshairTarget instanceof net.minecraft.util.hit.EntityHitResult entityHit &&
            entityHit.getEntity() instanceof LivingEntity living) {
            if (living.isAlive() && living != mc.player) {
                newTarget = living;
            }
        }
        this.target = newTarget;
       
        if (this.target != null) {
            this.lastTarget = this.target;
        }
    }
   
    private float getHitProgress(LivingEntity target) {
        return target.hurtTime > 0 ? Math.min(target.hurtTime / 10f, 1f) : 0f;
    }
   
    private int getColor(float hitProgress) {
        int base;
        if (useThemeColor.isEnabled()) {
            base = Zenith.getInstance().getThemeManager().getClientColor(0).getRGB();
        } else {
            base = mainColor.getColor().getRGB();
        }
       
        if (!useThemeColor.isEnabled() && hitColorEnabled.isEnabled() && hitProgress > 0) {
            return blendColors(base, hitColor.getColor().getRGB(), hitProgress);
        }
        return base;
    }
   
    private int getColorStyle(int hue) {
        return Color.getHSBColor(hue / 360f, 1.0f, 1.0f).getRGB();
    }


    // ============ SOULS (Души) ============
    private void renderSouls(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        String movement = soulsMovement.get();
       
        // Режим "Сквозь" - души летают через игрока
        if (movement.equals("Сквозь")) {
            renderSoulsThrough(target, anim, hitProgress);
            return;
        }
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double tX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double tY = interpolate(target.prevY, target.getY(), delta) - camPos.y;
        double tZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        boolean canSee = mc.player.canSee(target);
        double iAge = interpolate(mc.player.age - 1, mc.player.age, delta);
        float halfHeight = target.getHeight() / 2 + 0.2F;
        float baseWidth = target.getWidth() + 0.2f;
        float minY = 0.2f;
        float maxY = target.getHeight() - 0.2F;

        float hitEffect = Math.min(hitProgress * 2f, 2f);
        float acceleration = (float) Math.sin(hitEffect * Math.PI) * 0.18f;
        float bany = (float) Math.sin(hitEffect * Math.PI) * -0.04f;
       
        float speed = soulsSpeed.getCurrent();
        float size = soulsSize.getCurrent();
        float distance = soulsDistance.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int length = (int) soulsLength.getCurrent();
        float vertSpeed = soulsVerticalSpeed.getCurrent();
        float vertRange = soulsVerticalRange.getCurrent();

        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
       
        if (canSee) {
            RenderSystem.enableDepthTest();
            RenderSystem.depthMask(false);
        } else {
            RenderSystem.disableDepthTest();
        }

        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();

        int baseColorCached = getColor(hitProgress);
        float sizeSpeedFactor = 0.6f + speed * 0.1f;
       
        for (int j = 0; j < count; j++) {
            double jAngleOffset = j * (360.0 / count);
            double spiralJ = iAge * vertSpeed * 0.5 + j;
           
            for (int i = 0; i <= length; i++) {
                double baseAngle = ((i / 2F + iAge * speed * 2.0f) * length + jAngleOffset) % (length * 180);
                double radians = Math.toRadians(baseAngle);

                float distanceMultiplier = 1.0f + acceleration;
                float offset = ((float) (i + length) / (length + length));

                double yOffset = calculateYOffset(movement, iAge, i, j, halfHeight, minY, maxY, vertSpeed, vertRange);
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));

                double finalWidth = baseWidth * distanceMultiplier * distance;
               
                if (movement.equals("Спираль")) {
                    double spiralFactor = 1.0 + Math.sin(spiralJ) * 0.3;
                    finalWidth *= spiralFactor;
                }
               
                reusableMatrices.translate(tX + Math.cos(radians) * finalWidth, tY + yOffset, tZ + Math.sin(radians) * finalWidth);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                int blendedColor = blendColors(baseColorCached, getColorStyle((int) (180 * offset)), 0.3f);
                int color = applyOpacity(blendedColor, offset * anim);
               
                float particleSize = size * offset * sizeSpeedFactor + bany;
                float halfSize = particleSize / 2;
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(color);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(color);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(color);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(color);
            }
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());

        if (canSee) {
            RenderSystem.depthMask(true);
        }
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    // ============ SOULS THROUGH (Души сквозь) - летают через игрока ============
    private void renderSoulsThrough(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = soulsSpeed.getCurrent() * 50f;
        float radius = soulsDistance.getCurrent() * 0.55f;
        float size = soulsSize.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int trailLength = (int) soulsLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture); // Используем bloom как обычные души
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[count][];
            for (int g = 0; g < count; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / count);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }

   
    // ============ GHOSTS (Призраки) - летают через игрока ============
    private void renderGhosts(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = ghostSpeed.getCurrent() * 50f;
        float radius = ghostRadius.getCurrent() * 0.55f;
        float size = ghostSize.getCurrent();
        int trailLength = (int) ghostTrailLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, sparkTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        int numGhosts = (int) ghostCount.getCurrent();
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[numGhosts][];
            for (int g = 0; g < numGhosts; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / numGhosts);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    private double calculateYOffset(String movement, double iAge, int i, int j, float halfHeight, float minY, float maxY, float vertSpeed, float vertRange) {
        double baseY = halfHeight;
       
        switch (movement) {
            case "Волна" -> {
                double wave = Math.sin(iAge * vertSpeed + j * Math.PI / 2 + i * 0.3) * vertRange;
                return baseY + wave;
            }
            case "Спираль" -> {
                double spiral = Math.sin(iAge * vertSpeed * 0.7 + j) * vertRange;
                double heightProgress = (Math.sin(iAge * vertSpeed * 0.3 + j * 0.5) + 1) / 2;
                return minY + (maxY - minY) * heightProgress + spiral * 0.5;
            }
            case "Пульс" -> {
                double pulse = Math.sin(iAge * vertSpeed) * vertRange;
                double individualOffset = Math.sin(j * Math.PI / 2) * 0.2;
                return baseY + pulse + individualOffset;
            }
            default -> {
                double sinQuad = Math.sin(Math.toRadians(iAge * 0.7 + i * (j + halfHeight)) * 1.1) / 2;
                double adjustedSin = (j % 2 == 0) ? sinQuad : -sinQuad;
                return minY + (adjustedSin + 0.5) * (maxY - minY);
            }
        }
    }
   
    // ============ CIRCLE (Кружок) ============
    private void renderCircle(LivingEntity target, MatrixStack matrices, float tickDelta, float hitProgress) {
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double x = MathHelper.lerp(tickDelta, target.lastRenderX, target.getX()) - camPos.x;
        double z = MathHelper.lerp(tickDelta, target.lastRenderZ, target.getZ()) - camPos.z;
        double y = MathHelper.lerp(tickDelta, target.lastRenderY, target.getY()) - camPos.y +
                   Math.min(Math.sin(System.currentTimeMillis() / 400.0) + 0.95, target.getHeight());

        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);

        int baseColor = getColor(hitProgress);
        float r = ((baseColor >> 16) & 0xFF) / 255f;
        float g = ((baseColor >> 8) & 0xFF) / 255f;
        float b = (baseColor & 0xFF) / 255f;

        float alpha = (float) scale;
        float radius = target.getWidth() * 0.8f;

        for (float i = 0; i <= Math.PI * 2 + (Math.PI * 5 / 100); i += Math.PI * 5 / 100) {
            double vecX = x + radius * Math.cos(i);
            double vecZ = z + radius * Math.sin(i);

            buffer.vertex(matrix, (float) vecX, (float) (y - Math.cos(System.currentTimeMillis() / 400.0) / 2), (float) vecZ)
                  .color(r, g, b, 0.01f * alpha);
            buffer.vertex(matrix, (float) vecX, (float) y, (float) vecZ)
                  .color(r, g, b, 1f * alpha);
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.disableBlend();
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    // ============ UTILS ============
    private int applyOpacity(int baseColor, float alpha) {
        int r = (baseColor >> 16) & 0xFF;
        int g = (baseColor >> 8) & 0xFF;
        int b = baseColor & 0xFF;
        int a = (int) (255 * Math.min(alpha, 1f));
        return (a << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int blendColors(int color1, int color2, float ratio) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
       
        int r = (int) (r1 + (r2 - r1) * ratio);
        int g = (int) (g1 + (g2 - g1) * ratio);
        int b = (int) (b1 + (b2 - b1) * ratio);
       
        return (0xFF << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int setAlpha(int color, int alpha) {
        return (alpha << 24) | (color & 0x00FFFFFF);
    }

   
    // ============ CRYSTALS (Кристаллы) ============
    private void renderCrystals(LivingEntity target, MatrixStack ms, float anim, float hitProgress) {
        if (target == null) return;
       
        if (crystalList.isEmpty() || target != lastCrystalTarget) {
            createCrystals();
            lastCrystalTarget = target;
        }
       
        RenderSystem.enableDepthTest();
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double tX = MathHelper.lerp(delta, target.lastRenderX, target.getX()) - camPos.x;
        double tY = MathHelper.lerp(delta, target.lastRenderY, target.getY()) - camPos.y;
        double tZ = MathHelper.lerp(delta, target.lastRenderZ, target.getZ()) - camPos.z;
       
        float rotSpeed = crystalSpeed.getCurrent();
        crystalRotationAngle = (crystalRotationAngle + rotSpeed) % 360;
       
        ms.push();
        ms.translate(tX, tY, tZ);
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(crystalRotationAngle));
       
        Camera camera = mc.gameRenderer.getCamera();
        int baseColor = getColor(hitProgress);
        float size = crystalSize.getCurrent();
       
        for (CrystalData crystal : crystalList) {
            renderCrystal(ms, crystal, baseColor, anim, camera, size);
        }
       
        ms.pop();
        RenderSystem.enableDepthTest();
    }
   
    private void createCrystals() {
        crystalList.clear();
       
        // 14 кристаллов как в оригинале
        crystalList.add(new CrystalData(new Vec3d(0, 0.85, 0.8), new Vec3d(-49, 0, 40)));
        crystalList.add(new CrystalData(new Vec3d(0.2, 0.85, -0.675), new Vec3d(35, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.6, 1.35, 0.6), new Vec3d(-30, 0, 35)));
        crystalList.add(new CrystalData(new Vec3d(-0.74, 1.05, 0.4), new Vec3d(-25, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.74, 0.95, -0.4), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.475, 0.85, -0.375), new Vec3d(30, 0, -25)));
        crystalList.add(new CrystalData(new Vec3d(0, 1.35, -0.6), new Vec3d(45, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.85, 0.7, 0.1), new Vec3d(-30, 0, 30)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 1.35, -0.3), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.3, 1.35, 0.55), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 0.75, 0), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.2, 0.65, -0.7), new Vec3d(0, 0, 0)));
    }
   
    private void renderCrystal(MatrixStack ms, CrystalData crystal, int baseColor, float anim, Camera camera, float size) {
        ms.push();
        ms.translate(crystal.position.x, crystal.position.y, crystal.position.z);
       
        float pulsation = 1.0f + (float) (Math.sin(System.currentTimeMillis() / 500.0) * 0.1f);
        ms.scale(pulsation, pulsation, pulsation);
       
        float selfRotation = (System.currentTimeMillis() % 36000) / 100.0f * crystal.rotationSpeed;
        ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees((float) crystal.rotation.x));
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((float) crystal.rotation.y + selfRotation));
        ms.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((float) crystal.rotation.z));
       
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        // Внутреннее свечение
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        drawCrystalShape(ms, baseColor, 0.15f, true, anim, size);
       
        // Основной кристалл
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        drawCrystalShape(ms, baseColor, 0.4f, true, anim, size);
       
        // Внешнее свечение
        RenderSystem.depthMask(false);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        ms.push();
        ms.scale(1.3f, 1.3f, 1.3f);
        drawCrystalShape(ms, baseColor, 0.2f, true, anim, size);
        ms.pop();
       
        // Bloom сфера
        drawBloomSphere(ms, baseColor, anim, camera, size);
       
        RenderSystem.depthMask(true);
        RenderSystem.disableBlend();
        RenderSystem.enableCull();
        ms.pop();
    }
   
    private void drawCrystalShape(MatrixStack ms, int baseColor, float alpha, boolean filled, float anim, float size) {
        BufferBuilder buffer = Tessellator.getInstance().begin(
            filled ? VertexFormat.DrawMode.TRIANGLES : VertexFormat.DrawMode.DEBUG_LINES,
            VertexFormats.POSITION_COLOR
        );
       
        float s = size;
        float h_prism = size * 1.2f;
        float h_pyramid = size * 2.0f;
        int numSides = 6; // Меньше граней для более гладкого вида
       
        java.util.List<Vec3d> topVertices = new java.util.ArrayList<>();
        java.util.List<Vec3d> bottomVertices = new java.util.ArrayList<>();
       
        for (int i = 0; i < numSides; i++) {
            float angle = (float) (2 * Math.PI * i / numSides);
            float x = (float) (s * Math.cos(angle));
            float z = (float) (s * Math.sin(angle));
            topVertices.add(new Vec3d(x, h_prism / 2, z));
            bottomVertices.add(new Vec3d(x, -h_prism / 2, z));
        }
       
        Vec3d vTop = new Vec3d(0, h_prism / 2 + h_pyramid, 0);
        Vec3d vBottom = new Vec3d(0, -h_prism / 2 - h_pyramid, 0);
       
        int finalColor = setAlpha(baseColor, (int) (alpha * 255 * anim));
       
        // Боковые грани призмы
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            Vec3d v3 = topVertices.get((i + 1) % numSides);
            Vec3d v4 = topVertices.get(i);
            if (filled) {
                drawTriangle(ms, buffer, v1, v2, v3, finalColor);
                drawTriangle(ms, buffer, v1, v3, v4, finalColor);
            }
        }
       
        // Верхняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = topVertices.get(i);
            Vec3d v2 = topVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vTop, v1, v2, finalColor);
        }
       
        // Нижняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vBottom, v2, v1, finalColor);
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawTriangle(MatrixStack ms, BufferBuilder bb, Vec3d v1, Vec3d v2, Vec3d v3, int color) {
        Matrix4f matrix = ms.peek().getPositionMatrix();
        bb.vertex(matrix, (float)v1.x, (float)v1.y, (float)v1.z).color(color);
        bb.vertex(matrix, (float)v2.x, (float)v2.y, (float)v2.z).color(color);
        bb.vertex(matrix, (float)v3.x, (float)v3.y, (float)v3.z).color(color);
    }
   
    private void drawBloomSphere(MatrixStack ms, int baseColor, float anim, Camera camera, float size) {
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.depthMask(false);
       
        int bloomColor = setAlpha(baseColor, (int) (0.5f * 25 * anim));
        float bloomSize = size * 15.0f;
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        int segments = 6;
       
        for (int i = 0; i < segments; i++) {
            ms.push();
            float angle = (360.0f / segments) * i;
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle));
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
            ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
           
            Matrix4f matrix = ms.peek().getPositionMatrix();
            BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
            buffer.vertex(matrix, -bloomSize / 2, -bloomSize / 2, 0).texture(0, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, -bloomSize / 2, 0).texture(1, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, bloomSize / 2, 0).texture(1, 0).color(bloomColor);
            buffer.vertex(matrix, -bloomSize / 2, bloomSize / 2, 0).texture(0, 0).color(bloomColor);
            BufferRenderer.drawWithGlobalProgram(buffer.end());
            ms.pop();
        }
       
        RenderSystem.depthMask(true);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    private static class CrystalData {
        final Vec3d position;
        final Vec3d rotation;
        final float rotationSpeed;
       
        CrystalData(Vec3d position, Vec3d rotation) {
            this.position = position;
            this.rotation = rotation;
            this.rotationSpeed = 0.5f + (float)(Math.random() * 1.5f);
        }
    }
}
}Посмотреть вложение 321712Посмотреть вложение 321713
аааа таргет есп в 750 строк??? понял тебя
 
Салют югейм, сливаю вам Targed ESP на Zenith recode, чо то делал через клауд опус, чё-то сам.
Не бейте ногами пж первая тема.
SS: Прикреплён снизу
есп:
Expand Collapse Copy
package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import org.joml.Matrix4f;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ColorSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.modules.impl.combat.Aura;
import zenith.zov.Zenith;
import zenith.zov.utility.render.display.base.color.ColorRGBA;

import java.awt.*;

import static zenith.zov.utility.math.MathUtil.interpolate;

@ModuleAnnotation(name = "TargetESP", category = Category.RENDER, description = "Подсвечивает цель ауры")
public final class TargetESP extends Module {

    public static final TargetESP INSTANCE = new TargetESP();

    // Режим
    public final ModeSetting mode = new ModeSetting("Режим", "Души", "Кружок", "Призраки", "Кристаллы");
    public final BooleanSetting aimEsp = new BooleanSetting("При наведении", false);
   
    // Настройки для Душ
    private final ModeSetting soulsMovement = new ModeSetting("Движение душ", () -> mode.is("Души"), "Стандарт", "Волна", "Спираль", "Пульс", "Сквозь");
    private final NumberSetting soulsSpeed = new NumberSetting("Скорость", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsSize = new NumberSetting("Размер", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsDistance = new NumberSetting("Дистанция", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsCount = new NumberSetting("Количество", 4, 2, 8, 1, () -> mode.is("Души"));
    private final NumberSetting soulsLength = new NumberSetting("Длина хвоста", 10, 5, 20, 1, () -> mode.is("Души"));
    private final NumberSetting soulsVerticalSpeed = new NumberSetting("Вертикальная скорость", 1.0f, 0.1f, 3.0f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    private final NumberSetting soulsVerticalRange = new NumberSetting("Вертикальный диапазон", 0.5f, 0.1f, 1.5f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
   
    // Настройки для Призраков (упрощённые - без разных движений)
    private final NumberSetting ghostSpeed = new NumberSetting("Скорость призраков", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostRadius = new NumberSetting("Радиус призраков", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostSize = new NumberSetting("Размер призраков", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostTrailLength = new NumberSetting("Длина хвоста призраков", 10, 5, 20, 1, () -> mode.is("Призраки"));
    private final NumberSetting ghostCount = new NumberSetting("Количество призраков", 3, 1, 6, 1, () -> mode.is("Призраки"));
   
    // Настройки для Кристаллов
    private final NumberSetting crystalSpeed = new NumberSetting("Скорость вращения", 0.5f, 0.1f, 2.0f, 0.1f, () -> mode.is("Кристаллы"));
    private final NumberSetting crystalSize = new NumberSetting("Размер кристаллов", 0.05f, 0.02f, 0.15f, 0.01f, () -> mode.is("Кристаллы"));
   
    // Цвета
    private final BooleanSetting useThemeColor = new BooleanSetting("Цвет из темы", true);
    private final ColorSetting mainColor = new ColorSetting("Основной цвет", new ColorRGBA(255, 100, 100, 255), () -> !useThemeColor.isEnabled());
    private final BooleanSetting hitColorEnabled = new BooleanSetting("Цвет при ударе", true, () -> !useThemeColor.isEnabled());
    private final ColorSetting hitColor = new ColorSetting("Цвет удара", new ColorRGBA(255, 0, 0, 255), () -> !useThemeColor.isEnabled() && hitColorEnabled.isEnabled());

    private final Identifier bloomTexture = Identifier.of("zenith", "textures/particles/bloom.png");
    private final Identifier sparkTexture = Identifier.of("zenith", "textures/particles/spark.png");
   
    private LivingEntity target;
    private LivingEntity lastTarget;
    private double scale = 0.0D;
   
    // Кэшированные объекты
    private final MatrixStack reusableMatrices = new MatrixStack();
   
    // Кристаллы
    private LivingEntity lastCrystalTarget = null;
    private final java.util.List<CrystalData> crystalList = new java.util.ArrayList<>();
    private float crystalRotationAngle = 0;
   
    private TargetESP() {
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (!this.isEnabled()) return;
           
        updateTarget();
       
        LivingEntity currentTarget = target != null ? target : lastTarget;
        if (currentTarget == null) return;
       
        if (target != null) {
            scale = Math.min(scale + 0.1, 1.0);
        } else {
            scale = Math.max(scale - 0.1, 0.0);
        }
       
        if (scale <= 0) return;
       
        float hitProgress = getHitProgress(currentTarget);
        float anim = (float) scale;
       
        switch (mode.get()) {
            case "Души" -> renderSouls(currentTarget, anim, hitProgress);
            case "Кружок" -> renderCircle(currentTarget, event.getMatrix(), event.getPartialTicks(), hitProgress);
            case "Призраки" -> renderGhosts(currentTarget, anim, hitProgress);
            case "Кристаллы" -> renderCrystals(currentTarget, event.getMatrix(), anim, hitProgress);
        }
    }
   
    private void updateTarget() {
        LivingEntity newTarget = Aura.INSTANCE.getTarget();
        if (aimEsp.isEnabled() && mc.crosshairTarget != null &&
            mc.crosshairTarget.getType() == HitResult.Type.ENTITY &&
            mc.crosshairTarget instanceof net.minecraft.util.hit.EntityHitResult entityHit &&
            entityHit.getEntity() instanceof LivingEntity living) {
            if (living.isAlive() && living != mc.player) {
                newTarget = living;
            }
        }
        this.target = newTarget;
       
        if (this.target != null) {
            this.lastTarget = this.target;
        }
    }
   
    private float getHitProgress(LivingEntity target) {
        return target.hurtTime > 0 ? Math.min(target.hurtTime / 10f, 1f) : 0f;
    }
   
    private int getColor(float hitProgress) {
        int base;
        if (useThemeColor.isEnabled()) {
            base = Zenith.getInstance().getThemeManager().getClientColor(0).getRGB();
        } else {
            base = mainColor.getColor().getRGB();
        }
       
        if (!useThemeColor.isEnabled() && hitColorEnabled.isEnabled() && hitProgress > 0) {
            return blendColors(base, hitColor.getColor().getRGB(), hitProgress);
        }
        return base;
    }
   
    private int getColorStyle(int hue) {
        return Color.getHSBColor(hue / 360f, 1.0f, 1.0f).getRGB();
    }


    // ============ SOULS (Души) ============
    private void renderSouls(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        String movement = soulsMovement.get();
       
        // Режим "Сквозь" - души летают через игрока
        if (movement.equals("Сквозь")) {
            renderSoulsThrough(target, anim, hitProgress);
            return;
        }
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double tX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double tY = interpolate(target.prevY, target.getY(), delta) - camPos.y;
        double tZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        boolean canSee = mc.player.canSee(target);
        double iAge = interpolate(mc.player.age - 1, mc.player.age, delta);
        float halfHeight = target.getHeight() / 2 + 0.2F;
        float baseWidth = target.getWidth() + 0.2f;
        float minY = 0.2f;
        float maxY = target.getHeight() - 0.2F;

        float hitEffect = Math.min(hitProgress * 2f, 2f);
        float acceleration = (float) Math.sin(hitEffect * Math.PI) * 0.18f;
        float bany = (float) Math.sin(hitEffect * Math.PI) * -0.04f;
       
        float speed = soulsSpeed.getCurrent();
        float size = soulsSize.getCurrent();
        float distance = soulsDistance.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int length = (int) soulsLength.getCurrent();
        float vertSpeed = soulsVerticalSpeed.getCurrent();
        float vertRange = soulsVerticalRange.getCurrent();

        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
       
        if (canSee) {
            RenderSystem.enableDepthTest();
            RenderSystem.depthMask(false);
        } else {
            RenderSystem.disableDepthTest();
        }

        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();

        int baseColorCached = getColor(hitProgress);
        float sizeSpeedFactor = 0.6f + speed * 0.1f;
       
        for (int j = 0; j < count; j++) {
            double jAngleOffset = j * (360.0 / count);
            double spiralJ = iAge * vertSpeed * 0.5 + j;
           
            for (int i = 0; i <= length; i++) {
                double baseAngle = ((i / 2F + iAge * speed * 2.0f) * length + jAngleOffset) % (length * 180);
                double radians = Math.toRadians(baseAngle);

                float distanceMultiplier = 1.0f + acceleration;
                float offset = ((float) (i + length) / (length + length));

                double yOffset = calculateYOffset(movement, iAge, i, j, halfHeight, minY, maxY, vertSpeed, vertRange);
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));

                double finalWidth = baseWidth * distanceMultiplier * distance;
               
                if (movement.equals("Спираль")) {
                    double spiralFactor = 1.0 + Math.sin(spiralJ) * 0.3;
                    finalWidth *= spiralFactor;
                }
               
                reusableMatrices.translate(tX + Math.cos(radians) * finalWidth, tY + yOffset, tZ + Math.sin(radians) * finalWidth);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                int blendedColor = blendColors(baseColorCached, getColorStyle((int) (180 * offset)), 0.3f);
                int color = applyOpacity(blendedColor, offset * anim);
               
                float particleSize = size * offset * sizeSpeedFactor + bany;
                float halfSize = particleSize / 2;
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(color);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(color);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(color);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(color);
            }
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());

        if (canSee) {
            RenderSystem.depthMask(true);
        }
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    // ============ SOULS THROUGH (Души сквозь) - летают через игрока ============
    private void renderSoulsThrough(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = soulsSpeed.getCurrent() * 50f;
        float radius = soulsDistance.getCurrent() * 0.55f;
        float size = soulsSize.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int trailLength = (int) soulsLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture); // Используем bloom как обычные души
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[count][];
            for (int g = 0; g < count; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / count);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }

   
    // ============ GHOSTS (Призраки) - летают через игрока ============
    private void renderGhosts(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = ghostSpeed.getCurrent() * 50f;
        float radius = ghostRadius.getCurrent() * 0.55f;
        float size = ghostSize.getCurrent();
        int trailLength = (int) ghostTrailLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, sparkTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        int numGhosts = (int) ghostCount.getCurrent();
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[numGhosts][];
            for (int g = 0; g < numGhosts; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / numGhosts);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    private double calculateYOffset(String movement, double iAge, int i, int j, float halfHeight, float minY, float maxY, float vertSpeed, float vertRange) {
        double baseY = halfHeight;
       
        switch (movement) {
            case "Волна" -> {
                double wave = Math.sin(iAge * vertSpeed + j * Math.PI / 2 + i * 0.3) * vertRange;
                return baseY + wave;
            }
            case "Спираль" -> {
                double spiral = Math.sin(iAge * vertSpeed * 0.7 + j) * vertRange;
                double heightProgress = (Math.sin(iAge * vertSpeed * 0.3 + j * 0.5) + 1) / 2;
                return minY + (maxY - minY) * heightProgress + spiral * 0.5;
            }
            case "Пульс" -> {
                double pulse = Math.sin(iAge * vertSpeed) * vertRange;
                double individualOffset = Math.sin(j * Math.PI / 2) * 0.2;
                return baseY + pulse + individualOffset;
            }
            default -> {
                double sinQuad = Math.sin(Math.toRadians(iAge * 0.7 + i * (j + halfHeight)) * 1.1) / 2;
                double adjustedSin = (j % 2 == 0) ? sinQuad : -sinQuad;
                return minY + (adjustedSin + 0.5) * (maxY - minY);
            }
        }
    }
   
    // ============ CIRCLE (Кружок) ============
    private void renderCircle(LivingEntity target, MatrixStack matrices, float tickDelta, float hitProgress) {
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double x = MathHelper.lerp(tickDelta, target.lastRenderX, target.getX()) - camPos.x;
        double z = MathHelper.lerp(tickDelta, target.lastRenderZ, target.getZ()) - camPos.z;
        double y = MathHelper.lerp(tickDelta, target.lastRenderY, target.getY()) - camPos.y +
                   Math.min(Math.sin(System.currentTimeMillis() / 400.0) + 0.95, target.getHeight());

        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);

        int baseColor = getColor(hitProgress);
        float r = ((baseColor >> 16) & 0xFF) / 255f;
        float g = ((baseColor >> 8) & 0xFF) / 255f;
        float b = (baseColor & 0xFF) / 255f;

        float alpha = (float) scale;
        float radius = target.getWidth() * 0.8f;

        for (float i = 0; i <= Math.PI * 2 + (Math.PI * 5 / 100); i += Math.PI * 5 / 100) {
            double vecX = x + radius * Math.cos(i);
            double vecZ = z + radius * Math.sin(i);

            buffer.vertex(matrix, (float) vecX, (float) (y - Math.cos(System.currentTimeMillis() / 400.0) / 2), (float) vecZ)
                  .color(r, g, b, 0.01f * alpha);
            buffer.vertex(matrix, (float) vecX, (float) y, (float) vecZ)
                  .color(r, g, b, 1f * alpha);
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.disableBlend();
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    // ============ UTILS ============
    private int applyOpacity(int baseColor, float alpha) {
        int r = (baseColor >> 16) & 0xFF;
        int g = (baseColor >> 8) & 0xFF;
        int b = baseColor & 0xFF;
        int a = (int) (255 * Math.min(alpha, 1f));
        return (a << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int blendColors(int color1, int color2, float ratio) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
       
        int r = (int) (r1 + (r2 - r1) * ratio);
        int g = (int) (g1 + (g2 - g1) * ratio);
        int b = (int) (b1 + (b2 - b1) * ratio);
       
        return (0xFF << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int setAlpha(int color, int alpha) {
        return (alpha << 24) | (color & 0x00FFFFFF);
    }

   
    // ============ CRYSTALS (Кристаллы) ============
    private void renderCrystals(LivingEntity target, MatrixStack ms, float anim, float hitProgress) {
        if (target == null) return;
       
        if (crystalList.isEmpty() || target != lastCrystalTarget) {
            createCrystals();
            lastCrystalTarget = target;
        }
       
        RenderSystem.enableDepthTest();
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double tX = MathHelper.lerp(delta, target.lastRenderX, target.getX()) - camPos.x;
        double tY = MathHelper.lerp(delta, target.lastRenderY, target.getY()) - camPos.y;
        double tZ = MathHelper.lerp(delta, target.lastRenderZ, target.getZ()) - camPos.z;
       
        float rotSpeed = crystalSpeed.getCurrent();
        crystalRotationAngle = (crystalRotationAngle + rotSpeed) % 360;
       
        ms.push();
        ms.translate(tX, tY, tZ);
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(crystalRotationAngle));
       
        Camera camera = mc.gameRenderer.getCamera();
        int baseColor = getColor(hitProgress);
        float size = crystalSize.getCurrent();
       
        for (CrystalData crystal : crystalList) {
            renderCrystal(ms, crystal, baseColor, anim, camera, size);
        }
       
        ms.pop();
        RenderSystem.enableDepthTest();
    }
   
    private void createCrystals() {
        crystalList.clear();
       
        // 14 кристаллов как в оригинале
        crystalList.add(new CrystalData(new Vec3d(0, 0.85, 0.8), new Vec3d(-49, 0, 40)));
        crystalList.add(new CrystalData(new Vec3d(0.2, 0.85, -0.675), new Vec3d(35, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.6, 1.35, 0.6), new Vec3d(-30, 0, 35)));
        crystalList.add(new CrystalData(new Vec3d(-0.74, 1.05, 0.4), new Vec3d(-25, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.74, 0.95, -0.4), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.475, 0.85, -0.375), new Vec3d(30, 0, -25)));
        crystalList.add(new CrystalData(new Vec3d(0, 1.35, -0.6), new Vec3d(45, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.85, 0.7, 0.1), new Vec3d(-30, 0, 30)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 1.35, -0.3), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.3, 1.35, 0.55), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 0.75, 0), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.2, 0.65, -0.7), new Vec3d(0, 0, 0)));
    }
   
    private void renderCrystal(MatrixStack ms, CrystalData crystal, int baseColor, float anim, Camera camera, float size) {
        ms.push();
        ms.translate(crystal.position.x, crystal.position.y, crystal.position.z);
       
        float pulsation = 1.0f + (float) (Math.sin(System.currentTimeMillis() / 500.0) * 0.1f);
        ms.scale(pulsation, pulsation, pulsation);
       
        float selfRotation = (System.currentTimeMillis() % 36000) / 100.0f * crystal.rotationSpeed;
        ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees((float) crystal.rotation.x));
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((float) crystal.rotation.y + selfRotation));
        ms.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((float) crystal.rotation.z));
       
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        // Внутреннее свечение
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        drawCrystalShape(ms, baseColor, 0.15f, true, anim, size);
       
        // Основной кристалл
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        drawCrystalShape(ms, baseColor, 0.4f, true, anim, size);
       
        // Внешнее свечение
        RenderSystem.depthMask(false);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        ms.push();
        ms.scale(1.3f, 1.3f, 1.3f);
        drawCrystalShape(ms, baseColor, 0.2f, true, anim, size);
        ms.pop();
       
        // Bloom сфера
        drawBloomSphere(ms, baseColor, anim, camera, size);
       
        RenderSystem.depthMask(true);
        RenderSystem.disableBlend();
        RenderSystem.enableCull();
        ms.pop();
    }
   
    private void drawCrystalShape(MatrixStack ms, int baseColor, float alpha, boolean filled, float anim, float size) {
        BufferBuilder buffer = Tessellator.getInstance().begin(
            filled ? VertexFormat.DrawMode.TRIANGLES : VertexFormat.DrawMode.DEBUG_LINES,
            VertexFormats.POSITION_COLOR
        );
       
        float s = size;
        float h_prism = size * 1.2f;
        float h_pyramid = size * 2.0f;
        int numSides = 6; // Меньше граней для более гладкого вида
       
        java.util.List<Vec3d> topVertices = new java.util.ArrayList<>();
        java.util.List<Vec3d> bottomVertices = new java.util.ArrayList<>();
       
        for (int i = 0; i < numSides; i++) {
            float angle = (float) (2 * Math.PI * i / numSides);
            float x = (float) (s * Math.cos(angle));
            float z = (float) (s * Math.sin(angle));
            topVertices.add(new Vec3d(x, h_prism / 2, z));
            bottomVertices.add(new Vec3d(x, -h_prism / 2, z));
        }
       
        Vec3d vTop = new Vec3d(0, h_prism / 2 + h_pyramid, 0);
        Vec3d vBottom = new Vec3d(0, -h_prism / 2 - h_pyramid, 0);
       
        int finalColor = setAlpha(baseColor, (int) (alpha * 255 * anim));
       
        // Боковые грани призмы
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            Vec3d v3 = topVertices.get((i + 1) % numSides);
            Vec3d v4 = topVertices.get(i);
            if (filled) {
                drawTriangle(ms, buffer, v1, v2, v3, finalColor);
                drawTriangle(ms, buffer, v1, v3, v4, finalColor);
            }
        }
       
        // Верхняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = topVertices.get(i);
            Vec3d v2 = topVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vTop, v1, v2, finalColor);
        }
       
        // Нижняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vBottom, v2, v1, finalColor);
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawTriangle(MatrixStack ms, BufferBuilder bb, Vec3d v1, Vec3d v2, Vec3d v3, int color) {
        Matrix4f matrix = ms.peek().getPositionMatrix();
        bb.vertex(matrix, (float)v1.x, (float)v1.y, (float)v1.z).color(color);
        bb.vertex(matrix, (float)v2.x, (float)v2.y, (float)v2.z).color(color);
        bb.vertex(matrix, (float)v3.x, (float)v3.y, (float)v3.z).color(color);
    }
   
    private void drawBloomSphere(MatrixStack ms, int baseColor, float anim, Camera camera, float size) {
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.depthMask(false);
       
        int bloomColor = setAlpha(baseColor, (int) (0.5f * 25 * anim));
        float bloomSize = size * 15.0f;
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        int segments = 6;
       
        for (int i = 0; i < segments; i++) {
            ms.push();
            float angle = (360.0f / segments) * i;
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle));
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
            ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
           
            Matrix4f matrix = ms.peek().getPositionMatrix();
            BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
            buffer.vertex(matrix, -bloomSize / 2, -bloomSize / 2, 0).texture(0, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, -bloomSize / 2, 0).texture(1, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, bloomSize / 2, 0).texture(1, 0).color(bloomColor);
            buffer.vertex(matrix, -bloomSize / 2, bloomSize / 2, 0).texture(0, 0).color(bloomColor);
            BufferRenderer.drawWithGlobalProgram(buffer.end());
            ms.pop();
        }
       
        RenderSystem.depthMask(true);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    private static class CrystalData {
        final Vec3d position;
        final Vec3d rotation;
        final float rotationSpeed;
       
        CrystalData(Vec3d position, Vec3d rotation) {
            this.position = position;
            this.rotation = rotation;
            this.rotationSpeed = 0.5f + (float)(Math.random() * 1.5f);
        }
    }
}
}Посмотреть вложение 321712Посмотреть вложение 321713
2 фото хрень а 1 неплохо
 
Салют югейм, сливаю вам Targed ESP на Zenith recode, чо то делал через клауд опус, чё-то сам.
Не бейте ногами пж первая тема.
SS: Прикреплён снизу
есп:
Expand Collapse Copy
package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import org.joml.Matrix4f;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ColorSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.modules.impl.combat.Aura;
import zenith.zov.Zenith;
import zenith.zov.utility.render.display.base.color.ColorRGBA;

import java.awt.*;

import static zenith.zov.utility.math.MathUtil.interpolate;

@ModuleAnnotation(name = "TargetESP", category = Category.RENDER, description = "Подсвечивает цель ауры")
public final class TargetESP extends Module {

    public static final TargetESP INSTANCE = new TargetESP();

    // Режим
    public final ModeSetting mode = new ModeSetting("Режим", "Души", "Кружок", "Призраки", "Кристаллы");
    public final BooleanSetting aimEsp = new BooleanSetting("При наведении", false);
   
    // Настройки для Душ
    private final ModeSetting soulsMovement = new ModeSetting("Движение душ", () -> mode.is("Души"), "Стандарт", "Волна", "Спираль", "Пульс", "Сквозь");
    private final NumberSetting soulsSpeed = new NumberSetting("Скорость", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsSize = new NumberSetting("Размер", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsDistance = new NumberSetting("Дистанция", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsCount = new NumberSetting("Количество", 4, 2, 8, 1, () -> mode.is("Души"));
    private final NumberSetting soulsLength = new NumberSetting("Длина хвоста", 10, 5, 20, 1, () -> mode.is("Души"));
    private final NumberSetting soulsVerticalSpeed = new NumberSetting("Вертикальная скорость", 1.0f, 0.1f, 3.0f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    private final NumberSetting soulsVerticalRange = new NumberSetting("Вертикальный диапазон", 0.5f, 0.1f, 1.5f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
   
    // Настройки для Призраков (упрощённые - без разных движений)
    private final NumberSetting ghostSpeed = new NumberSetting("Скорость призраков", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostRadius = new NumberSetting("Радиус призраков", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostSize = new NumberSetting("Размер призраков", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostTrailLength = new NumberSetting("Длина хвоста призраков", 10, 5, 20, 1, () -> mode.is("Призраки"));
    private final NumberSetting ghostCount = new NumberSetting("Количество призраков", 3, 1, 6, 1, () -> mode.is("Призраки"));
   
    // Настройки для Кристаллов
    private final NumberSetting crystalSpeed = new NumberSetting("Скорость вращения", 0.5f, 0.1f, 2.0f, 0.1f, () -> mode.is("Кристаллы"));
    private final NumberSetting crystalSize = new NumberSetting("Размер кристаллов", 0.05f, 0.02f, 0.15f, 0.01f, () -> mode.is("Кристаллы"));
   
    // Цвета
    private final BooleanSetting useThemeColor = new BooleanSetting("Цвет из темы", true);
    private final ColorSetting mainColor = new ColorSetting("Основной цвет", new ColorRGBA(255, 100, 100, 255), () -> !useThemeColor.isEnabled());
    private final BooleanSetting hitColorEnabled = new BooleanSetting("Цвет при ударе", true, () -> !useThemeColor.isEnabled());
    private final ColorSetting hitColor = new ColorSetting("Цвет удара", new ColorRGBA(255, 0, 0, 255), () -> !useThemeColor.isEnabled() && hitColorEnabled.isEnabled());

    private final Identifier bloomTexture = Identifier.of("zenith", "textures/particles/bloom.png");
    private final Identifier sparkTexture = Identifier.of("zenith", "textures/particles/spark.png");
   
    private LivingEntity target;
    private LivingEntity lastTarget;
    private double scale = 0.0D;
   
    // Кэшированные объекты
    private final MatrixStack reusableMatrices = new MatrixStack();
   
    // Кристаллы
    private LivingEntity lastCrystalTarget = null;
    private final java.util.List<CrystalData> crystalList = new java.util.ArrayList<>();
    private float crystalRotationAngle = 0;
   
    private TargetESP() {
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (!this.isEnabled()) return;
           
        updateTarget();
       
        LivingEntity currentTarget = target != null ? target : lastTarget;
        if (currentTarget == null) return;
       
        if (target != null) {
            scale = Math.min(scale + 0.1, 1.0);
        } else {
            scale = Math.max(scale - 0.1, 0.0);
        }
       
        if (scale <= 0) return;
       
        float hitProgress = getHitProgress(currentTarget);
        float anim = (float) scale;
       
        switch (mode.get()) {
            case "Души" -> renderSouls(currentTarget, anim, hitProgress);
            case "Кружок" -> renderCircle(currentTarget, event.getMatrix(), event.getPartialTicks(), hitProgress);
            case "Призраки" -> renderGhosts(currentTarget, anim, hitProgress);
            case "Кристаллы" -> renderCrystals(currentTarget, event.getMatrix(), anim, hitProgress);
        }
    }
   
    private void updateTarget() {
        LivingEntity newTarget = Aura.INSTANCE.getTarget();
        if (aimEsp.isEnabled() && mc.crosshairTarget != null &&
            mc.crosshairTarget.getType() == HitResult.Type.ENTITY &&
            mc.crosshairTarget instanceof net.minecraft.util.hit.EntityHitResult entityHit &&
            entityHit.getEntity() instanceof LivingEntity living) {
            if (living.isAlive() && living != mc.player) {
                newTarget = living;
            }
        }
        this.target = newTarget;
       
        if (this.target != null) {
            this.lastTarget = this.target;
        }
    }
   
    private float getHitProgress(LivingEntity target) {
        return target.hurtTime > 0 ? Math.min(target.hurtTime / 10f, 1f) : 0f;
    }
   
    private int getColor(float hitProgress) {
        int base;
        if (useThemeColor.isEnabled()) {
            base = Zenith.getInstance().getThemeManager().getClientColor(0).getRGB();
        } else {
            base = mainColor.getColor().getRGB();
        }
       
        if (!useThemeColor.isEnabled() && hitColorEnabled.isEnabled() && hitProgress > 0) {
            return blendColors(base, hitColor.getColor().getRGB(), hitProgress);
        }
        return base;
    }
   
    private int getColorStyle(int hue) {
        return Color.getHSBColor(hue / 360f, 1.0f, 1.0f).getRGB();
    }


    // ============ SOULS (Души) ============
    private void renderSouls(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        String movement = soulsMovement.get();
       
        // Режим "Сквозь" - души летают через игрока
        if (movement.equals("Сквозь")) {
            renderSoulsThrough(target, anim, hitProgress);
            return;
        }
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double tX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double tY = interpolate(target.prevY, target.getY(), delta) - camPos.y;
        double tZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        boolean canSee = mc.player.canSee(target);
        double iAge = interpolate(mc.player.age - 1, mc.player.age, delta);
        float halfHeight = target.getHeight() / 2 + 0.2F;
        float baseWidth = target.getWidth() + 0.2f;
        float minY = 0.2f;
        float maxY = target.getHeight() - 0.2F;

        float hitEffect = Math.min(hitProgress * 2f, 2f);
        float acceleration = (float) Math.sin(hitEffect * Math.PI) * 0.18f;
        float bany = (float) Math.sin(hitEffect * Math.PI) * -0.04f;
       
        float speed = soulsSpeed.getCurrent();
        float size = soulsSize.getCurrent();
        float distance = soulsDistance.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int length = (int) soulsLength.getCurrent();
        float vertSpeed = soulsVerticalSpeed.getCurrent();
        float vertRange = soulsVerticalRange.getCurrent();

        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
       
        if (canSee) {
            RenderSystem.enableDepthTest();
            RenderSystem.depthMask(false);
        } else {
            RenderSystem.disableDepthTest();
        }

        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();

        int baseColorCached = getColor(hitProgress);
        float sizeSpeedFactor = 0.6f + speed * 0.1f;
       
        for (int j = 0; j < count; j++) {
            double jAngleOffset = j * (360.0 / count);
            double spiralJ = iAge * vertSpeed * 0.5 + j;
           
            for (int i = 0; i <= length; i++) {
                double baseAngle = ((i / 2F + iAge * speed * 2.0f) * length + jAngleOffset) % (length * 180);
                double radians = Math.toRadians(baseAngle);

                float distanceMultiplier = 1.0f + acceleration;
                float offset = ((float) (i + length) / (length + length));

                double yOffset = calculateYOffset(movement, iAge, i, j, halfHeight, minY, maxY, vertSpeed, vertRange);
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));

                double finalWidth = baseWidth * distanceMultiplier * distance;
               
                if (movement.equals("Спираль")) {
                    double spiralFactor = 1.0 + Math.sin(spiralJ) * 0.3;
                    finalWidth *= spiralFactor;
                }
               
                reusableMatrices.translate(tX + Math.cos(radians) * finalWidth, tY + yOffset, tZ + Math.sin(radians) * finalWidth);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                int blendedColor = blendColors(baseColorCached, getColorStyle((int) (180 * offset)), 0.3f);
                int color = applyOpacity(blendedColor, offset * anim);
               
                float particleSize = size * offset * sizeSpeedFactor + bany;
                float halfSize = particleSize / 2;
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(color);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(color);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(color);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(color);
            }
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());

        if (canSee) {
            RenderSystem.depthMask(true);
        }
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    // ============ SOULS THROUGH (Души сквозь) - летают через игрока ============
    private void renderSoulsThrough(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = soulsSpeed.getCurrent() * 50f;
        float radius = soulsDistance.getCurrent() * 0.55f;
        float size = soulsSize.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int trailLength = (int) soulsLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture); // Используем bloom как обычные души
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[count][];
            for (int g = 0; g < count; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / count);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }

   
    // ============ GHOSTS (Призраки) - летают через игрока ============
    private void renderGhosts(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = ghostSpeed.getCurrent() * 50f;
        float radius = ghostRadius.getCurrent() * 0.55f;
        float size = ghostSize.getCurrent();
        int trailLength = (int) ghostTrailLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, sparkTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        int numGhosts = (int) ghostCount.getCurrent();
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[numGhosts][];
            for (int g = 0; g < numGhosts; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / numGhosts);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    private double calculateYOffset(String movement, double iAge, int i, int j, float halfHeight, float minY, float maxY, float vertSpeed, float vertRange) {
        double baseY = halfHeight;
       
        switch (movement) {
            case "Волна" -> {
                double wave = Math.sin(iAge * vertSpeed + j * Math.PI / 2 + i * 0.3) * vertRange;
                return baseY + wave;
            }
            case "Спираль" -> {
                double spiral = Math.sin(iAge * vertSpeed * 0.7 + j) * vertRange;
                double heightProgress = (Math.sin(iAge * vertSpeed * 0.3 + j * 0.5) + 1) / 2;
                return minY + (maxY - minY) * heightProgress + spiral * 0.5;
            }
            case "Пульс" -> {
                double pulse = Math.sin(iAge * vertSpeed) * vertRange;
                double individualOffset = Math.sin(j * Math.PI / 2) * 0.2;
                return baseY + pulse + individualOffset;
            }
            default -> {
                double sinQuad = Math.sin(Math.toRadians(iAge * 0.7 + i * (j + halfHeight)) * 1.1) / 2;
                double adjustedSin = (j % 2 == 0) ? sinQuad : -sinQuad;
                return minY + (adjustedSin + 0.5) * (maxY - minY);
            }
        }
    }
   
    // ============ CIRCLE (Кружок) ============
    private void renderCircle(LivingEntity target, MatrixStack matrices, float tickDelta, float hitProgress) {
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double x = MathHelper.lerp(tickDelta, target.lastRenderX, target.getX()) - camPos.x;
        double z = MathHelper.lerp(tickDelta, target.lastRenderZ, target.getZ()) - camPos.z;
        double y = MathHelper.lerp(tickDelta, target.lastRenderY, target.getY()) - camPos.y +
                   Math.min(Math.sin(System.currentTimeMillis() / 400.0) + 0.95, target.getHeight());

        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);

        int baseColor = getColor(hitProgress);
        float r = ((baseColor >> 16) & 0xFF) / 255f;
        float g = ((baseColor >> 8) & 0xFF) / 255f;
        float b = (baseColor & 0xFF) / 255f;

        float alpha = (float) scale;
        float radius = target.getWidth() * 0.8f;

        for (float i = 0; i <= Math.PI * 2 + (Math.PI * 5 / 100); i += Math.PI * 5 / 100) {
            double vecX = x + radius * Math.cos(i);
            double vecZ = z + radius * Math.sin(i);

            buffer.vertex(matrix, (float) vecX, (float) (y - Math.cos(System.currentTimeMillis() / 400.0) / 2), (float) vecZ)
                  .color(r, g, b, 0.01f * alpha);
            buffer.vertex(matrix, (float) vecX, (float) y, (float) vecZ)
                  .color(r, g, b, 1f * alpha);
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.disableBlend();
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    // ============ UTILS ============
    private int applyOpacity(int baseColor, float alpha) {
        int r = (baseColor >> 16) & 0xFF;
        int g = (baseColor >> 8) & 0xFF;
        int b = baseColor & 0xFF;
        int a = (int) (255 * Math.min(alpha, 1f));
        return (a << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int blendColors(int color1, int color2, float ratio) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
       
        int r = (int) (r1 + (r2 - r1) * ratio);
        int g = (int) (g1 + (g2 - g1) * ratio);
        int b = (int) (b1 + (b2 - b1) * ratio);
       
        return (0xFF << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int setAlpha(int color, int alpha) {
        return (alpha << 24) | (color & 0x00FFFFFF);
    }

   
    // ============ CRYSTALS (Кристаллы) ============
    private void renderCrystals(LivingEntity target, MatrixStack ms, float anim, float hitProgress) {
        if (target == null) return;
       
        if (crystalList.isEmpty() || target != lastCrystalTarget) {
            createCrystals();
            lastCrystalTarget = target;
        }
       
        RenderSystem.enableDepthTest();
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double tX = MathHelper.lerp(delta, target.lastRenderX, target.getX()) - camPos.x;
        double tY = MathHelper.lerp(delta, target.lastRenderY, target.getY()) - camPos.y;
        double tZ = MathHelper.lerp(delta, target.lastRenderZ, target.getZ()) - camPos.z;
       
        float rotSpeed = crystalSpeed.getCurrent();
        crystalRotationAngle = (crystalRotationAngle + rotSpeed) % 360;
       
        ms.push();
        ms.translate(tX, tY, tZ);
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(crystalRotationAngle));
       
        Camera camera = mc.gameRenderer.getCamera();
        int baseColor = getColor(hitProgress);
        float size = crystalSize.getCurrent();
       
        for (CrystalData crystal : crystalList) {
            renderCrystal(ms, crystal, baseColor, anim, camera, size);
        }
       
        ms.pop();
        RenderSystem.enableDepthTest();
    }
   
    private void createCrystals() {
        crystalList.clear();
       
        // 14 кристаллов как в оригинале
        crystalList.add(new CrystalData(new Vec3d(0, 0.85, 0.8), new Vec3d(-49, 0, 40)));
        crystalList.add(new CrystalData(new Vec3d(0.2, 0.85, -0.675), new Vec3d(35, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.6, 1.35, 0.6), new Vec3d(-30, 0, 35)));
        crystalList.add(new CrystalData(new Vec3d(-0.74, 1.05, 0.4), new Vec3d(-25, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.74, 0.95, -0.4), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.475, 0.85, -0.375), new Vec3d(30, 0, -25)));
        crystalList.add(new CrystalData(new Vec3d(0, 1.35, -0.6), new Vec3d(45, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.85, 0.7, 0.1), new Vec3d(-30, 0, 30)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 1.35, -0.3), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.3, 1.35, 0.55), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 0.75, 0), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.2, 0.65, -0.7), new Vec3d(0, 0, 0)));
    }
   
    private void renderCrystal(MatrixStack ms, CrystalData crystal, int baseColor, float anim, Camera camera, float size) {
        ms.push();
        ms.translate(crystal.position.x, crystal.position.y, crystal.position.z);
       
        float pulsation = 1.0f + (float) (Math.sin(System.currentTimeMillis() / 500.0) * 0.1f);
        ms.scale(pulsation, pulsation, pulsation);
       
        float selfRotation = (System.currentTimeMillis() % 36000) / 100.0f * crystal.rotationSpeed;
        ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees((float) crystal.rotation.x));
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((float) crystal.rotation.y + selfRotation));
        ms.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((float) crystal.rotation.z));
       
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        // Внутреннее свечение
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        drawCrystalShape(ms, baseColor, 0.15f, true, anim, size);
       
        // Основной кристалл
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        drawCrystalShape(ms, baseColor, 0.4f, true, anim, size);
       
        // Внешнее свечение
        RenderSystem.depthMask(false);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        ms.push();
        ms.scale(1.3f, 1.3f, 1.3f);
        drawCrystalShape(ms, baseColor, 0.2f, true, anim, size);
        ms.pop();
       
        // Bloom сфера
        drawBloomSphere(ms, baseColor, anim, camera, size);
       
        RenderSystem.depthMask(true);
        RenderSystem.disableBlend();
        RenderSystem.enableCull();
        ms.pop();
    }
   
    private void drawCrystalShape(MatrixStack ms, int baseColor, float alpha, boolean filled, float anim, float size) {
        BufferBuilder buffer = Tessellator.getInstance().begin(
            filled ? VertexFormat.DrawMode.TRIANGLES : VertexFormat.DrawMode.DEBUG_LINES,
            VertexFormats.POSITION_COLOR
        );
       
        float s = size;
        float h_prism = size * 1.2f;
        float h_pyramid = size * 2.0f;
        int numSides = 6; // Меньше граней для более гладкого вида
       
        java.util.List<Vec3d> topVertices = new java.util.ArrayList<>();
        java.util.List<Vec3d> bottomVertices = new java.util.ArrayList<>();
       
        for (int i = 0; i < numSides; i++) {
            float angle = (float) (2 * Math.PI * i / numSides);
            float x = (float) (s * Math.cos(angle));
            float z = (float) (s * Math.sin(angle));
            topVertices.add(new Vec3d(x, h_prism / 2, z));
            bottomVertices.add(new Vec3d(x, -h_prism / 2, z));
        }
       
        Vec3d vTop = new Vec3d(0, h_prism / 2 + h_pyramid, 0);
        Vec3d vBottom = new Vec3d(0, -h_prism / 2 - h_pyramid, 0);
       
        int finalColor = setAlpha(baseColor, (int) (alpha * 255 * anim));
       
        // Боковые грани призмы
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            Vec3d v3 = topVertices.get((i + 1) % numSides);
            Vec3d v4 = topVertices.get(i);
            if (filled) {
                drawTriangle(ms, buffer, v1, v2, v3, finalColor);
                drawTriangle(ms, buffer, v1, v3, v4, finalColor);
            }
        }
       
        // Верхняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = topVertices.get(i);
            Vec3d v2 = topVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vTop, v1, v2, finalColor);
        }
       
        // Нижняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vBottom, v2, v1, finalColor);
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawTriangle(MatrixStack ms, BufferBuilder bb, Vec3d v1, Vec3d v2, Vec3d v3, int color) {
        Matrix4f matrix = ms.peek().getPositionMatrix();
        bb.vertex(matrix, (float)v1.x, (float)v1.y, (float)v1.z).color(color);
        bb.vertex(matrix, (float)v2.x, (float)v2.y, (float)v2.z).color(color);
        bb.vertex(matrix, (float)v3.x, (float)v3.y, (float)v3.z).color(color);
    }
   
    private void drawBloomSphere(MatrixStack ms, int baseColor, float anim, Camera camera, float size) {
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.depthMask(false);
       
        int bloomColor = setAlpha(baseColor, (int) (0.5f * 25 * anim));
        float bloomSize = size * 15.0f;
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        int segments = 6;
       
        for (int i = 0; i < segments; i++) {
            ms.push();
            float angle = (360.0f / segments) * i;
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle));
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
            ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
           
            Matrix4f matrix = ms.peek().getPositionMatrix();
            BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
            buffer.vertex(matrix, -bloomSize / 2, -bloomSize / 2, 0).texture(0, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, -bloomSize / 2, 0).texture(1, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, bloomSize / 2, 0).texture(1, 0).color(bloomColor);
            buffer.vertex(matrix, -bloomSize / 2, bloomSize / 2, 0).texture(0, 0).color(bloomColor);
            BufferRenderer.drawWithGlobalProgram(buffer.end());
            ms.pop();
        }
       
        RenderSystem.depthMask(true);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    private static class CrystalData {
        final Vec3d position;
        final Vec3d rotation;
        final float rotationSpeed;
       
        CrystalData(Vec3d position, Vec3d rotation) {
            this.position = position;
            this.rotation = rotation;
            this.rotationSpeed = 0.5f + (float)(Math.random() * 1.5f);
        }
    }
}
}Посмотреть вложение 321712Посмотреть вложение 321713
ты нормас таргет есп в 749 строк? Ну и тут фулл нейра
 
Салют югейм, сливаю вам Targed ESP на Zenith recode, чо то делал через клауд опус, чё-то сам.
Не бейте ногами пж первая тема.
SS: Прикреплён снизу
есп:
Expand Collapse Copy
package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import org.joml.Matrix4f;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ColorSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.modules.impl.combat.Aura;
import zenith.zov.Zenith;
import zenith.zov.utility.render.display.base.color.ColorRGBA;

import java.awt.*;

import static zenith.zov.utility.math.MathUtil.interpolate;

@ModuleAnnotation(name = "TargetESP", category = Category.RENDER, description = "Подсвечивает цель ауры")
public final class TargetESP extends Module {

    public static final TargetESP INSTANCE = new TargetESP();

    // Режим
    public final ModeSetting mode = new ModeSetting("Режим", "Души", "Кружок", "Призраки", "Кристаллы");
    public final BooleanSetting aimEsp = new BooleanSetting("При наведении", false);
   
    // Настройки для Душ
    private final ModeSetting soulsMovement = new ModeSetting("Движение душ", () -> mode.is("Души"), "Стандарт", "Волна", "Спираль", "Пульс", "Сквозь");
    private final NumberSetting soulsSpeed = new NumberSetting("Скорость", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsSize = new NumberSetting("Размер", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsDistance = new NumberSetting("Дистанция", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Души"));
    private final NumberSetting soulsCount = new NumberSetting("Количество", 4, 2, 8, 1, () -> mode.is("Души"));
    private final NumberSetting soulsLength = new NumberSetting("Длина хвоста", 10, 5, 20, 1, () -> mode.is("Души"));
    private final NumberSetting soulsVerticalSpeed = new NumberSetting("Вертикальная скорость", 1.0f, 0.1f, 3.0f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
    private final NumberSetting soulsVerticalRange = new NumberSetting("Вертикальный диапазон", 0.5f, 0.1f, 1.5f, 0.1f,
            () -> mode.is("Души") && !soulsMovement.is("Сквозь") && !soulsMovement.is("Стандарт"));
   
    // Настройки для Призраков (упрощённые - без разных движений)
    private final NumberSetting ghostSpeed = new NumberSetting("Скорость призраков", 0.62f, 0.1f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostRadius = new NumberSetting("Радиус призраков", 1.04f, 0.5f, 2.0f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostSize = new NumberSetting("Размер призраков", 0.6f, 0.2f, 1.5f, 0.05f, () -> mode.is("Призраки"));
    private final NumberSetting ghostTrailLength = new NumberSetting("Длина хвоста призраков", 10, 5, 20, 1, () -> mode.is("Призраки"));
    private final NumberSetting ghostCount = new NumberSetting("Количество призраков", 3, 1, 6, 1, () -> mode.is("Призраки"));
   
    // Настройки для Кристаллов
    private final NumberSetting crystalSpeed = new NumberSetting("Скорость вращения", 0.5f, 0.1f, 2.0f, 0.1f, () -> mode.is("Кристаллы"));
    private final NumberSetting crystalSize = new NumberSetting("Размер кристаллов", 0.05f, 0.02f, 0.15f, 0.01f, () -> mode.is("Кристаллы"));
   
    // Цвета
    private final BooleanSetting useThemeColor = new BooleanSetting("Цвет из темы", true);
    private final ColorSetting mainColor = new ColorSetting("Основной цвет", new ColorRGBA(255, 100, 100, 255), () -> !useThemeColor.isEnabled());
    private final BooleanSetting hitColorEnabled = new BooleanSetting("Цвет при ударе", true, () -> !useThemeColor.isEnabled());
    private final ColorSetting hitColor = new ColorSetting("Цвет удара", new ColorRGBA(255, 0, 0, 255), () -> !useThemeColor.isEnabled() && hitColorEnabled.isEnabled());

    private final Identifier bloomTexture = Identifier.of("zenith", "textures/particles/bloom.png");
    private final Identifier sparkTexture = Identifier.of("zenith", "textures/particles/spark.png");
   
    private LivingEntity target;
    private LivingEntity lastTarget;
    private double scale = 0.0D;
   
    // Кэшированные объекты
    private final MatrixStack reusableMatrices = new MatrixStack();
   
    // Кристаллы
    private LivingEntity lastCrystalTarget = null;
    private final java.util.List<CrystalData> crystalList = new java.util.ArrayList<>();
    private float crystalRotationAngle = 0;
   
    private TargetESP() {
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (!this.isEnabled()) return;
           
        updateTarget();
       
        LivingEntity currentTarget = target != null ? target : lastTarget;
        if (currentTarget == null) return;
       
        if (target != null) {
            scale = Math.min(scale + 0.1, 1.0);
        } else {
            scale = Math.max(scale - 0.1, 0.0);
        }
       
        if (scale <= 0) return;
       
        float hitProgress = getHitProgress(currentTarget);
        float anim = (float) scale;
       
        switch (mode.get()) {
            case "Души" -> renderSouls(currentTarget, anim, hitProgress);
            case "Кружок" -> renderCircle(currentTarget, event.getMatrix(), event.getPartialTicks(), hitProgress);
            case "Призраки" -> renderGhosts(currentTarget, anim, hitProgress);
            case "Кристаллы" -> renderCrystals(currentTarget, event.getMatrix(), anim, hitProgress);
        }
    }
   
    private void updateTarget() {
        LivingEntity newTarget = Aura.INSTANCE.getTarget();
        if (aimEsp.isEnabled() && mc.crosshairTarget != null &&
            mc.crosshairTarget.getType() == HitResult.Type.ENTITY &&
            mc.crosshairTarget instanceof net.minecraft.util.hit.EntityHitResult entityHit &&
            entityHit.getEntity() instanceof LivingEntity living) {
            if (living.isAlive() && living != mc.player) {
                newTarget = living;
            }
        }
        this.target = newTarget;
       
        if (this.target != null) {
            this.lastTarget = this.target;
        }
    }
   
    private float getHitProgress(LivingEntity target) {
        return target.hurtTime > 0 ? Math.min(target.hurtTime / 10f, 1f) : 0f;
    }
   
    private int getColor(float hitProgress) {
        int base;
        if (useThemeColor.isEnabled()) {
            base = Zenith.getInstance().getThemeManager().getClientColor(0).getRGB();
        } else {
            base = mainColor.getColor().getRGB();
        }
       
        if (!useThemeColor.isEnabled() && hitColorEnabled.isEnabled() && hitProgress > 0) {
            return blendColors(base, hitColor.getColor().getRGB(), hitProgress);
        }
        return base;
    }
   
    private int getColorStyle(int hue) {
        return Color.getHSBColor(hue / 360f, 1.0f, 1.0f).getRGB();
    }


    // ============ SOULS (Души) ============
    private void renderSouls(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        String movement = soulsMovement.get();
       
        // Режим "Сквозь" - души летают через игрока
        if (movement.equals("Сквозь")) {
            renderSoulsThrough(target, anim, hitProgress);
            return;
        }
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double tX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double tY = interpolate(target.prevY, target.getY(), delta) - camPos.y;
        double tZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        boolean canSee = mc.player.canSee(target);
        double iAge = interpolate(mc.player.age - 1, mc.player.age, delta);
        float halfHeight = target.getHeight() / 2 + 0.2F;
        float baseWidth = target.getWidth() + 0.2f;
        float minY = 0.2f;
        float maxY = target.getHeight() - 0.2F;

        float hitEffect = Math.min(hitProgress * 2f, 2f);
        float acceleration = (float) Math.sin(hitEffect * Math.PI) * 0.18f;
        float bany = (float) Math.sin(hitEffect * Math.PI) * -0.04f;
       
        float speed = soulsSpeed.getCurrent();
        float size = soulsSize.getCurrent();
        float distance = soulsDistance.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int length = (int) soulsLength.getCurrent();
        float vertSpeed = soulsVerticalSpeed.getCurrent();
        float vertRange = soulsVerticalRange.getCurrent();

        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
       
        if (canSee) {
            RenderSystem.enableDepthTest();
            RenderSystem.depthMask(false);
        } else {
            RenderSystem.disableDepthTest();
        }

        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();

        int baseColorCached = getColor(hitProgress);
        float sizeSpeedFactor = 0.6f + speed * 0.1f;
       
        for (int j = 0; j < count; j++) {
            double jAngleOffset = j * (360.0 / count);
            double spiralJ = iAge * vertSpeed * 0.5 + j;
           
            for (int i = 0; i <= length; i++) {
                double baseAngle = ((i / 2F + iAge * speed * 2.0f) * length + jAngleOffset) % (length * 180);
                double radians = Math.toRadians(baseAngle);

                float distanceMultiplier = 1.0f + acceleration;
                float offset = ((float) (i + length) / (length + length));

                double yOffset = calculateYOffset(movement, iAge, i, j, halfHeight, minY, maxY, vertSpeed, vertRange);
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));

                double finalWidth = baseWidth * distanceMultiplier * distance;
               
                if (movement.equals("Спираль")) {
                    double spiralFactor = 1.0 + Math.sin(spiralJ) * 0.3;
                    finalWidth *= spiralFactor;
                }
               
                reusableMatrices.translate(tX + Math.cos(radians) * finalWidth, tY + yOffset, tZ + Math.sin(radians) * finalWidth);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                int blendedColor = blendColors(baseColorCached, getColorStyle((int) (180 * offset)), 0.3f);
                int color = applyOpacity(blendedColor, offset * anim);
               
                float particleSize = size * offset * sizeSpeedFactor + bany;
                float halfSize = particleSize / 2;
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(color);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(color);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(color);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(color);
            }
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());

        if (canSee) {
            RenderSystem.depthMask(true);
        }
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    // ============ SOULS THROUGH (Души сквозь) - летают через игрока ============
    private void renderSoulsThrough(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = soulsSpeed.getCurrent() * 50f;
        float radius = soulsDistance.getCurrent() * 0.55f;
        float size = soulsSize.getCurrent();
        int count = (int) soulsCount.getCurrent();
        int trailLength = (int) soulsLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, bloomTexture); // Используем bloom как обычные души
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[count][];
            for (int g = 0; g < count; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / count);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }

   
    // ============ GHOSTS (Призраки) - летают через игрока ============
    private void renderGhosts(LivingEntity target, float anim, float hitProgress) {
        Camera camera = mc.getEntityRenderDispatcher().camera;
        if (camera == null) return;
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = camera.getPos();
        double baseX = interpolate(target.prevX, target.getX(), delta) - camPos.x;
        double baseY = interpolate(target.prevY, target.getY(), delta) - camPos.y + target.getHeight() / 2f;
        double baseZ = interpolate(target.prevZ, target.getZ(), delta) - camPos.z;
       
        long time = System.currentTimeMillis();
        float hurtPC = (float) Math.sin(target.hurtTime * (Math.PI / 25f));
       
        float speed = ghostSpeed.getCurrent() * 50f;
        float radius = ghostRadius.getCurrent() * 0.55f;
        float size = ghostSize.getCurrent();
        int trailLength = (int) ghostTrailLength.getCurrent() * 15;
        double distanceStep = 1.5;
       
        RenderSystem.disableDepthTest();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShaderTexture(0, sparkTexture);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.depthMask(false);
       
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
       
        int baseColorCached = getColor(hitProgress);
        int redColor = 0xFFFF0000;
        float invTrailLength = 1.0f / trailLength;
       
        int numGhosts = (int) ghostCount.getCurrent();
       
        for (int i = 0; i < trailLength; i++) {
            double angle = 0.1f * (time - i * distanceStep) / speed;
           
            double[][] points = new double[numGhosts][];
            for (int g = 0; g < numGhosts; g++) {
                double ghostAngle = angle + g * (Math.PI * 2.0 / numGhosts);
                double s = Math.sin(ghostAngle) * radius;
                double c = Math.cos(ghostAngle) * radius;
                double zOff = Math.sin(ghostAngle * 1.5) * radius * 0.7;
                points[g] = new double[] {baseX + s, baseY + c, baseZ + zOff};
            }
           
            float progress = i * invTrailLength;
            float sizeFactor = (float) Math.pow(1.0f - progress, 1.1f);
            float alphaTrail = anim * (1f - progress * progress) * 0.6f;
            float rotation = (float) (time / 5.0 + i * 5) % 360;
           
            int colorWithAlpha = applyOpacity(baseColorCached, alphaTrail);
            int redWithAlpha = applyOpacity(redColor, alphaTrail);
            int finalColor = blendColors(colorWithAlpha, redWithAlpha, hurtPC);
           
            for (double[] pos : points) {
                double dx = pos[0] + camPos.x;
                double dy = pos[1] + camPos.y;
                double dz = pos[2] + camPos.z;
                double distSq = dx * dx + dy * dy + dz * dz;
                float distanceScale = (float) (size * 85.0f / Math.max(1, Math.sqrt(distSq)));
                float finalSize = distanceScale * sizeFactor;
                float halfSize = finalSize / 2;
               
                reusableMatrices.loadIdentity();
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw + 180.0F));
                reusableMatrices.translate(pos[0], pos[1], pos[2]);
                reusableMatrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
                reusableMatrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
                reusableMatrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));
               
                Matrix4f matrix = reusableMatrices.peek().getPositionMatrix();
               
                buffer.vertex(matrix, -halfSize, halfSize, 0).texture(0f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, halfSize, 0).texture(1f, 0f).color(finalColor);
                buffer.vertex(matrix, halfSize, -halfSize, 0).texture(1f, 1f).color(finalColor);
                buffer.vertex(matrix, -halfSize, -halfSize, 0).texture(0f, 1f).color(finalColor);
            }
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.disableBlend();
    }
   
    private double calculateYOffset(String movement, double iAge, int i, int j, float halfHeight, float minY, float maxY, float vertSpeed, float vertRange) {
        double baseY = halfHeight;
       
        switch (movement) {
            case "Волна" -> {
                double wave = Math.sin(iAge * vertSpeed + j * Math.PI / 2 + i * 0.3) * vertRange;
                return baseY + wave;
            }
            case "Спираль" -> {
                double spiral = Math.sin(iAge * vertSpeed * 0.7 + j) * vertRange;
                double heightProgress = (Math.sin(iAge * vertSpeed * 0.3 + j * 0.5) + 1) / 2;
                return minY + (maxY - minY) * heightProgress + spiral * 0.5;
            }
            case "Пульс" -> {
                double pulse = Math.sin(iAge * vertSpeed) * vertRange;
                double individualOffset = Math.sin(j * Math.PI / 2) * 0.2;
                return baseY + pulse + individualOffset;
            }
            default -> {
                double sinQuad = Math.sin(Math.toRadians(iAge * 0.7 + i * (j + halfHeight)) * 1.1) / 2;
                double adjustedSin = (j % 2 == 0) ? sinQuad : -sinQuad;
                return minY + (adjustedSin + 0.5) * (maxY - minY);
            }
        }
    }
   
    // ============ CIRCLE (Кружок) ============
    private void renderCircle(LivingEntity target, MatrixStack matrices, float tickDelta, float hitProgress) {
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double x = MathHelper.lerp(tickDelta, target.lastRenderX, target.getX()) - camPos.x;
        double z = MathHelper.lerp(tickDelta, target.lastRenderZ, target.getZ()) - camPos.z;
        double y = MathHelper.lerp(tickDelta, target.lastRenderY, target.getY()) - camPos.y +
                   Math.min(Math.sin(System.currentTimeMillis() / 400.0) + 0.95, target.getHeight());

        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);

        int baseColor = getColor(hitProgress);
        float r = ((baseColor >> 16) & 0xFF) / 255f;
        float g = ((baseColor >> 8) & 0xFF) / 255f;
        float b = (baseColor & 0xFF) / 255f;

        float alpha = (float) scale;
        float radius = target.getWidth() * 0.8f;

        for (float i = 0; i <= Math.PI * 2 + (Math.PI * 5 / 100); i += Math.PI * 5 / 100) {
            double vecX = x + radius * Math.cos(i);
            double vecZ = z + radius * Math.sin(i);

            buffer.vertex(matrix, (float) vecX, (float) (y - Math.cos(System.currentTimeMillis() / 400.0) / 2), (float) vecZ)
                  .color(r, g, b, 0.01f * alpha);
            buffer.vertex(matrix, (float) vecX, (float) y, (float) vecZ)
                  .color(r, g, b, 1f * alpha);
        }

        BufferRenderer.drawWithGlobalProgram(buffer.end());
       
        RenderSystem.disableBlend();
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    // ============ UTILS ============
    private int applyOpacity(int baseColor, float alpha) {
        int r = (baseColor >> 16) & 0xFF;
        int g = (baseColor >> 8) & 0xFF;
        int b = baseColor & 0xFF;
        int a = (int) (255 * Math.min(alpha, 1f));
        return (a << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int blendColors(int color1, int color2, float ratio) {
        int r1 = (color1 >> 16) & 0xFF;
        int g1 = (color1 >> 8) & 0xFF;
        int b1 = color1 & 0xFF;
        int r2 = (color2 >> 16) & 0xFF;
        int g2 = (color2 >> 8) & 0xFF;
        int b2 = color2 & 0xFF;
       
        int r = (int) (r1 + (r2 - r1) * ratio);
        int g = (int) (g1 + (g2 - g1) * ratio);
        int b = (int) (b1 + (b2 - b1) * ratio);
       
        return (0xFF << 24) | (r << 16) | (g << 8) | b;
    }
   
    private int setAlpha(int color, int alpha) {
        return (alpha << 24) | (color & 0x00FFFFFF);
    }

   
    // ============ CRYSTALS (Кристаллы) ============
    private void renderCrystals(LivingEntity target, MatrixStack ms, float anim, float hitProgress) {
        if (target == null) return;
       
        if (crystalList.isEmpty() || target != lastCrystalTarget) {
            createCrystals();
            lastCrystalTarget = target;
        }
       
        RenderSystem.enableDepthTest();
       
        float delta = mc.getRenderTickCounter().getTickDelta(true);
        Vec3d camPos = mc.gameRenderer.getCamera().getPos();
        double tX = MathHelper.lerp(delta, target.lastRenderX, target.getX()) - camPos.x;
        double tY = MathHelper.lerp(delta, target.lastRenderY, target.getY()) - camPos.y;
        double tZ = MathHelper.lerp(delta, target.lastRenderZ, target.getZ()) - camPos.z;
       
        float rotSpeed = crystalSpeed.getCurrent();
        crystalRotationAngle = (crystalRotationAngle + rotSpeed) % 360;
       
        ms.push();
        ms.translate(tX, tY, tZ);
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(crystalRotationAngle));
       
        Camera camera = mc.gameRenderer.getCamera();
        int baseColor = getColor(hitProgress);
        float size = crystalSize.getCurrent();
       
        for (CrystalData crystal : crystalList) {
            renderCrystal(ms, crystal, baseColor, anim, camera, size);
        }
       
        ms.pop();
        RenderSystem.enableDepthTest();
    }
   
    private void createCrystals() {
        crystalList.clear();
       
        // 14 кристаллов как в оригинале
        crystalList.add(new CrystalData(new Vec3d(0, 0.85, 0.8), new Vec3d(-49, 0, 40)));
        crystalList.add(new CrystalData(new Vec3d(0.2, 0.85, -0.675), new Vec3d(35, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.6, 1.35, 0.6), new Vec3d(-30, 0, 35)));
        crystalList.add(new CrystalData(new Vec3d(-0.74, 1.05, 0.4), new Vec3d(-25, 0, -30)));
        crystalList.add(new CrystalData(new Vec3d(0.74, 0.95, -0.4), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.475, 0.85, -0.375), new Vec3d(30, 0, -25)));
        crystalList.add(new CrystalData(new Vec3d(0, 1.35, -0.6), new Vec3d(45, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.85, 0.7, 0.1), new Vec3d(-30, 0, 30)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 1.35, -0.3), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.3, 1.35, 0.55), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(0.5, 0.7, 0.7), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.7, 0.75, 0), new Vec3d(0, 0, 0)));
        crystalList.add(new CrystalData(new Vec3d(-0.2, 0.65, -0.7), new Vec3d(0, 0, 0)));
    }
   
    private void renderCrystal(MatrixStack ms, CrystalData crystal, int baseColor, float anim, Camera camera, float size) {
        ms.push();
        ms.translate(crystal.position.x, crystal.position.y, crystal.position.z);
       
        float pulsation = 1.0f + (float) (Math.sin(System.currentTimeMillis() / 500.0) * 0.1f);
        ms.scale(pulsation, pulsation, pulsation);
       
        float selfRotation = (System.currentTimeMillis() % 36000) / 100.0f * crystal.rotationSpeed;
        ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees((float) crystal.rotation.x));
        ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((float) crystal.rotation.y + selfRotation));
        ms.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((float) crystal.rotation.z));
       
        RenderSystem.disableCull();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
       
        // Внутреннее свечение
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        drawCrystalShape(ms, baseColor, 0.15f, true, anim, size);
       
        // Основной кристалл
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
        drawCrystalShape(ms, baseColor, 0.4f, true, anim, size);
       
        // Внешнее свечение
        RenderSystem.depthMask(false);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        ms.push();
        ms.scale(1.3f, 1.3f, 1.3f);
        drawCrystalShape(ms, baseColor, 0.2f, true, anim, size);
        ms.pop();
       
        // Bloom сфера
        drawBloomSphere(ms, baseColor, anim, camera, size);
       
        RenderSystem.depthMask(true);
        RenderSystem.disableBlend();
        RenderSystem.enableCull();
        ms.pop();
    }
   
    private void drawCrystalShape(MatrixStack ms, int baseColor, float alpha, boolean filled, float anim, float size) {
        BufferBuilder buffer = Tessellator.getInstance().begin(
            filled ? VertexFormat.DrawMode.TRIANGLES : VertexFormat.DrawMode.DEBUG_LINES,
            VertexFormats.POSITION_COLOR
        );
       
        float s = size;
        float h_prism = size * 1.2f;
        float h_pyramid = size * 2.0f;
        int numSides = 6; // Меньше граней для более гладкого вида
       
        java.util.List<Vec3d> topVertices = new java.util.ArrayList<>();
        java.util.List<Vec3d> bottomVertices = new java.util.ArrayList<>();
       
        for (int i = 0; i < numSides; i++) {
            float angle = (float) (2 * Math.PI * i / numSides);
            float x = (float) (s * Math.cos(angle));
            float z = (float) (s * Math.sin(angle));
            topVertices.add(new Vec3d(x, h_prism / 2, z));
            bottomVertices.add(new Vec3d(x, -h_prism / 2, z));
        }
       
        Vec3d vTop = new Vec3d(0, h_prism / 2 + h_pyramid, 0);
        Vec3d vBottom = new Vec3d(0, -h_prism / 2 - h_pyramid, 0);
       
        int finalColor = setAlpha(baseColor, (int) (alpha * 255 * anim));
       
        // Боковые грани призмы
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            Vec3d v3 = topVertices.get((i + 1) % numSides);
            Vec3d v4 = topVertices.get(i);
            if (filled) {
                drawTriangle(ms, buffer, v1, v2, v3, finalColor);
                drawTriangle(ms, buffer, v1, v3, v4, finalColor);
            }
        }
       
        // Верхняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = topVertices.get(i);
            Vec3d v2 = topVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vTop, v1, v2, finalColor);
        }
       
        // Нижняя пирамида
        for (int i = 0; i < numSides; i++) {
            Vec3d v1 = bottomVertices.get(i);
            Vec3d v2 = bottomVertices.get((i + 1) % numSides);
            if (filled) drawTriangle(ms, buffer, vBottom, v2, v1, finalColor);
        }
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawTriangle(MatrixStack ms, BufferBuilder bb, Vec3d v1, Vec3d v2, Vec3d v3, int color) {
        Matrix4f matrix = ms.peek().getPositionMatrix();
        bb.vertex(matrix, (float)v1.x, (float)v1.y, (float)v1.z).color(color);
        bb.vertex(matrix, (float)v2.x, (float)v2.y, (float)v2.z).color(color);
        bb.vertex(matrix, (float)v3.x, (float)v3.y, (float)v3.z).color(color);
    }
   
    private void drawBloomSphere(MatrixStack ms, int baseColor, float anim, Camera camera, float size) {
        RenderSystem.setShader(ShaderProgramKeys.POSITION_TEX_COLOR);
        RenderSystem.setShaderTexture(0, bloomTexture);
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
        RenderSystem.depthMask(false);
       
        int bloomColor = setAlpha(baseColor, (int) (0.5f * 25 * anim));
        float bloomSize = size * 15.0f;
        float pitch = camera.getPitch();
        float yaw = camera.getYaw();
        int segments = 6;
       
        for (int i = 0; i < segments; i++) {
            ms.push();
            float angle = (360.0f / segments) * i;
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle));
            ms.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-yaw));
            ms.multiply(RotationAxis.POSITIVE_X.rotationDegrees(pitch));
           
            Matrix4f matrix = ms.peek().getPositionMatrix();
            BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
            buffer.vertex(matrix, -bloomSize / 2, -bloomSize / 2, 0).texture(0, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, -bloomSize / 2, 0).texture(1, 1).color(bloomColor);
            buffer.vertex(matrix, bloomSize / 2, bloomSize / 2, 0).texture(1, 0).color(bloomColor);
            buffer.vertex(matrix, -bloomSize / 2, bloomSize / 2, 0).texture(0, 0).color(bloomColor);
            BufferRenderer.drawWithGlobalProgram(buffer.end());
            ms.pop();
        }
       
        RenderSystem.depthMask(true);
        RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
    }
   
    private static class CrystalData {
        final Vec3d position;
        final Vec3d rotation;
        final float rotationSpeed;
       
        CrystalData(Vec3d position, Vec3d rotation) {
            this.position = position;
            this.rotation = rotation;
            this.rotationSpeed = 0.5f + (float)(Math.random() * 1.5f);
        }
    }
}
}Посмотреть вложение 321712Посмотреть вложение 321713
Возникает вопрос, как это нейронка обрабатывала... 750 строк....
 
Назад
Сверху Снизу