Начинающий
- Статус
- Оффлайн
- Регистрация
- 14 Сен 2025
- Сообщения
- 16
- Реакции
- 0
- Выберите загрузчик игры
- Fabric
решил запостить такой таргетхуд,попросите нейронку перенести она вам все сделает
targethud:
package ru.wraith.module.list.render.hud;
import com.google.common.eventbus.Subscribe;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
import ru.wraith.event.list.EventHUD;
import ru.wraith.module.Module;
import ru.wraith.module.ModuleCategory;
import ru.wraith.module.ModuleInformation;
import ru.wraith.module.list.combat.KillAura;
import ru.wraith.util.base.Instance;
import ru.wraith.util.draggable.DragManager;
import ru.wraith.util.draggable.Draggable;
import ru.wraith.util.render.builders.Builder;
import ru.wraith.util.render.builders.states.QuadColorState;
import ru.wraith.util.render.builders.states.QuadRadiusState;
import ru.wraith.util.render.builders.states.SizeState;
import ru.wraith.util.render.math.Animation;
import ru.wraith.util.render.math.Easing;
import ru.wraith.util.render.msdf.Fonts;
import ru.wraith.util.render.providers.ColorProvider;
import ru.wraith.util.render.renderers.DrawUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* TargetHUD: круглая аватарка, имя, круговой HP-бар с градиентом и AA,
* строка предметов (off-hand / броня / main-hand) с индикатором прочности.
*/
@ModuleInformation(moduleName = "TargetHUD", moduleCategory = ModuleCategory.RENDER)
public class TargetHUD extends Module {
private final Draggable drag = DragManager.installDrag(this, "TargetHUD", 130, 130);
private final Animation animation = new Animation(Easing.EXPO_OUT, 300);
private final Animation armorAnim = new Animation(Easing.EXPO_OUT, 300);
private final Animation hpAnimation = new Animation(Easing.EXPO_OUT, 600);
private LivingEntity lastTarget;
private float lastHpRaw = -1f;
@Subscribe
public void onHud(EventHUD e) {
if (mc.player == null || mc.options.hudHidden) return;
render(e.getDrawContext());
}
private void render(DrawContext context) {
KillAura killAura = Instance.get(KillAura.class);
boolean chatOpen = mc.currentScreen instanceof ChatScreen;
LivingEntity target = null;
if (killAura != null && killAura.isEnabled() && killAura.getTarget() != null
&& killAura.getTarget().isAlive()) {
target = killAura.getTarget();
} else if (mc.targetedEntity instanceof LivingEntity living && living.isAlive()) {
target = living;
} else if (chatOpen) {
target = mc.player;
}
if (target != null) {
lastTarget = target;
animation.run(1);
armorAnim.run(1);
} else {
animation.run(0);
armorAnim.run(0);
}
if (animation.getValue() <= 0.05f || lastTarget == null) return;
LivingEntity entity = lastTarget;
AbstractClientPlayerEntity playerEntity = entity instanceof AbstractClientPlayerEntity ape ? ape : null;
float anim = (float) animation.getValue();
int alphaInt = (int) (255 * anim);
String name = entity.getName().getString();
// Динамическая ширина от имени
float nameWidth = Fonts.SFMEDIUM.get().getWidth(name, 8f);
float width = Math.max(110f, 36 + nameWidth + 35f + 10f);
float height = 36;
float x = drag.getX();
float y = drag.getY();
// Фон панели
DrawUtil.drawRound(x, y, width, height, 4, ColorProvider.rgba(20, 20, 20, (int) (190 * anim)));
// --- Голова ---
float headSize = 30f;
float headX = x + 3;
float headY = y + 3f;
float currentHp = entity.getHealth();
if (Float.isNaN(currentHp) || currentHp < 0) currentHp = 0;
if (lastHpRaw == -1f || lastTarget != entity) lastHpRaw = currentHp;
lastHpRaw = currentHp;
float hurt = entity.hurtTime / 10f;
int headColor = ColorProvider.rgba(255,
(int) (255 * (1 - hurt)),
(int) (255 * (1 - hurt)),
alphaInt);
if (playerEntity != null) {
try {
Identifier skin = playerEntity.getSkinTextures().texture();
int texId = mc.getTextureManager().getTexture(skin).getGlId();
Builder.texture()
.size(new SizeState(headSize, headSize))
.radius(new QuadRadiusState(5))
.color(new QuadColorState(headColor))
.texture(8f / 64f, 8f / 64f, 8f / 64f, 8f / 64f, texId)
.smoothness(1f)
.build()
.render(context.getMatrices().peek().getPositionMatrix(), headX, headY);
} catch (Exception ignored) {}
} else {
DrawUtil.drawText(Fonts.ICONS_NURIK.get(), "N", headX + 1, headY + 8, headColor, 26f);
}
// --- Имя ---
float textX = x + 36;
DrawUtil.drawText(Fonts.SFMEDIUM.get(), name, textX + 0.5f, y + 4,
ColorProvider.rgba(255, 255, 255, alphaInt), 8f);
// --- Круговой HP ---
float circleX = x + width - 18;
float circleY = y + height / 2;
float outerRadius = 12f;
float innerRadius = 10.5f;
float maxHealth = entity.getMaxHealth();
float hpPercent = MathHelper.clamp(currentHp / maxHealth, 0, 1);
hpAnimation.run(hpPercent);
float animatedHpPercent = (float) hpAnimation.getValue();
int hpColor = ColorProvider.setAlpha(ColorProvider.getColorClient(), alphaInt);
int bgColor = ColorProvider.rgba(40, 40, 40, (int) (150 * anim));
drawCircularProgressGradient(
context.getMatrices().peek().getPositionMatrix(),
circleX, circleY, outerRadius, innerRadius,
animatedHpPercent, hpColor, bgColor, alphaInt);
String hpText = String.format("%.1f", currentHp);
float hpTextWidth = Fonts.SFMEDIUM.get().getWidth(hpText, 7.5f);
DrawUtil.drawText(Fonts.SFMEDIUM.get(), hpText,
circleX - hpTextWidth / 2, circleY - 3.5f,
ColorProvider.rgba(255, 255, 255, alphaInt), 7.5f);
// --- Предметы ---
float armorAlpha = (float) armorAnim.getValue();
if (armorAlpha > 0.05f) {
drawEquipment(context, entity, textX, y + 13, armorAlpha);
}
drag.setWidth(width);
drag.setHeight(height);
}
private void drawEquipment(DrawContext context, LivingEntity entity,
float startX, float startY, float alpha) {
List<ItemStack> items = new ArrayList<>();
items.add(entity.getMainHandStack());
for (ItemStack stack : entity.getArmorItems()) items.add(stack);
items.add(entity.getOffHandStack());
Collections.reverse(items);
float itemScale = 0.5f;
float slotSize = 16 * itemScale;
float itemX = startX;
context.getMatrices().push();
context.getMatrices().translate(0, 0, 100);
TextRenderer tr = MinecraftClient.getInstance().textRenderer;
int index = 0;
for (ItemStack stack : items) {
if (stack.isEmpty()) {
itemX += slotSize;
index++;
continue;
}
context.getMatrices().push();
float zOffset = (index == 0) ? 10 : (index == items.size() - 1 ? 0 : 5);
context.getMatrices().translate(itemX, startY, zOffset);
context.getMatrices().scale(alpha * itemScale, alpha * itemScale, 1f);
context.drawItem(stack, 0, 0);
// Количество
if (stack.getCount() > 1) {
String countText = String.valueOf(stack.getCount());
context.getMatrices().push();
context.getMatrices().scale(1f / itemScale, 1f / itemScale, 1f);
context.drawText(tr, countText,
(int) (10 * itemScale - tr.getWidth(countText)),
(int) (10 * itemScale),
0xFFFFFF, true);
context.getMatrices().pop();
}
// Прочность
if (stack.isDamageable() && stack.getDamage() > 0) {
float percent = 1.0f - ((float) stack.getDamage() / stack.getMaxDamage());
int color = percent > 0.5f ? 0xFF00FF00 : percent > 0.25f ? 0xFFFFFF00 : 0xFFFF0000;
context.getMatrices().push();
context.getMatrices().scale(1f / itemScale, 1f / itemScale, 1f);
float barWidth = 13 * itemScale;
float barHeight = 2 * itemScale;
float barX = 1 * itemScale;
float barY = 13 * itemScale;
context.fill((int) barX, (int) barY,
(int) (barX + barWidth), (int) (barY + barHeight), 0xFF000000);
context.fill((int) barX, (int) barY,
(int) (barX + barWidth * percent), (int) (barY + barHeight), color);
context.getMatrices().pop();
}
context.getMatrices().pop();
itemX += slotSize;
index++;
}
context.getMatrices().pop();
}
/**
* Круговой HP-бар с градиентом по цвету темы и антиалиасингом по краям.
*/
private void drawCircularProgressGradient(Matrix4f matrix, float centerX, float centerY,
float outerRadius, float innerRadius,
float progress, int progressColor, int bgColor, int alpha) {
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
GL11.glEnable(GL11.GL_LINE_SMOOTH);
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST);
GL11.glEnable(GL11.GL_POLYGON_SMOOTH);
GL11.glHint(GL11.GL_POLYGON_SMOOTH_HINT, GL11.GL_NICEST);
int segments = 360;
float angleStep = (float) (2 * Math.PI / segments);
float startAngle = (float) (-Math.PI / 2); // начинаем сверху
float aaWidth = 0.5f;
int bgR = (bgColor >> 16) & 0xFF;
int bgG = (bgColor >> 8) & 0xFF;
int bgB = bgColor & 0xFF;
// AA внешнего края фона
BufferBuilder builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= segments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float outerAAX = centerX + cos * (outerRadius + aaWidth);
float outerAAY = centerY + sin * (outerRadius + aaWidth);
float outerX = centerX + cos * outerRadius;
float outerY = centerY + sin * outerRadius;
builder.vertex(matrix, outerAAX, outerAAY, 0).color(ColorProvider.rgba(bgR, bgG, bgB, 0));
builder.vertex(matrix, outerX, outerY, 0).color(bgColor);
}
BufferRenderer.drawWithGlobalProgram(builder.end());
// Основное кольцо фона
builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= segments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float outerX = centerX + cos * outerRadius;
float outerY = centerY + sin * outerRadius;
float innerX = centerX + cos * innerRadius;
float innerY = centerY + sin * innerRadius;
builder.vertex(matrix, outerX, outerY, 0).color(bgColor);
builder.vertex(matrix, innerX, innerY, 0).color(bgColor);
}
BufferRenderer.drawWithGlobalProgram(builder.end());
// AA внутреннего края фона
builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= segments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float innerX = centerX + cos * innerRadius;
float innerY = centerY + sin * innerRadius;
float innerAAX = centerX + cos * (innerRadius - aaWidth);
float innerAAY = centerY + sin * (innerRadius - aaWidth);
builder.vertex(matrix, innerX, innerY, 0).color(bgColor);
builder.vertex(matrix, innerAAX, innerAAY, 0).color(ColorProvider.rgba(bgR, bgG, bgB, 0));
}
BufferRenderer.drawWithGlobalProgram(builder.end());
// Прогресс
if (progress > 0.001f) {
int progressSegments = Math.max(1, (int) (segments * progress));
int r = (progressColor >> 16) & 0xFF;
int g = (progressColor >> 8) & 0xFF;
int b = progressColor & 0xFF;
// AA внешнего края прогресса
builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= progressSegments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float t = (float) i / progressSegments;
float brightness = 1.0f - (t * 0.3f);
int cr = (int) (r * brightness);
int cg = (int) (g * brightness);
int cb = (int) (b * brightness);
float outerAAX = centerX + cos * (outerRadius + aaWidth);
float outerAAY = centerY + sin * (outerRadius + aaWidth);
float outerX = centerX + cos * outerRadius;
float outerY = centerY + sin * outerRadius;
builder.vertex(matrix, outerAAX, outerAAY, 0).color(ColorProvider.rgba(cr, cg, cb, 0));
builder.vertex(matrix, outerX, outerY, 0).color(ColorProvider.rgba(cr, cg, cb, alpha));
}
BufferRenderer.drawWithGlobalProgram(builder.end());
// Основное кольцо прогресса
builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= progressSegments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float t = (float) i / progressSegments;
float brightness = 1.0f - (t * 0.3f);
int cr = (int) (r * brightness);
int cg = (int) (g * brightness);
int cb = (int) (b * brightness);
float outerX = centerX + cos * outerRadius;
float outerY = centerY + sin * outerRadius;
float innerX = centerX + cos * innerRadius;
float innerY = centerY + sin * innerRadius;
int color = ColorProvider.rgba(cr, cg, cb, alpha);
builder.vertex(matrix, outerX, outerY, 0).color(color);
builder.vertex(matrix, innerX, innerY, 0).color(color);
}
BufferRenderer.drawWithGlobalProgram(builder.end());
// AA внутреннего края прогресса
builder = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
for (int i = 0; i <= progressSegments; i++) {
float angle = startAngle + angleStep * i;
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float t = (float) i / progressSegments;
float brightness = 1.0f - (t * 0.3f);
int cr = (int) (r * brightness);
int cg = (int) (g * brightness);
int cb = (int) (b * brightness);
float innerX = centerX + cos * innerRadius;
float innerY = centerY + sin * innerRadius;
float innerAAX = centerX + cos * (innerRadius - aaWidth);
float innerAAY = centerY + sin * (innerRadius - aaWidth);
builder.vertex(matrix, innerX, innerY, 0).color(ColorProvider.rgba(cr, cg, cb, alpha));
builder.vertex(matrix, innerAAX, innerAAY, 0).color(ColorProvider.rgba(cr, cg, cb, 0));
}
BufferRenderer.drawWithGlobalProgram(builder.end());
}
GL11.glDisable(GL11.GL_POLYGON_SMOOTH);
GL11.glDisable(GL11.GL_LINE_SMOOTH);
RenderSystem.disableBlend();
}
}