Начинающий
- Статус
- Оффлайн
- Регистрация
- 26 Апр 2025
- Сообщения
- 64
- Реакции
- 1
- Выберите загрузчик игры
- Fabric
взял идею с вегалайна и сделал ее на евачку.
code:
ss:
code:
LineGlyphsModule:
package code.miaware.client.features.modules.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import lombok.Getter;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;
import code.miaware.api.event.EventListener;
import code.miaware.api.event.Listener;
import code.miaware.api.event.events.client.TickEvent;
import code.miaware.api.event.events.render.Render3DEvent;
import code.miaware.api.module.Category;
import code.miaware.api.module.Module;
import code.miaware.api.module.ModuleRegister;
import code.miaware.api.module.setting.BooleanSetting;
import code.miaware.api.module.setting.ModeSetting;
import code.miaware.api.module.setting.SliderSetting;
import code.miaware.api.utils.animation.AnimationUtil;
import code.miaware.api.utils.animation.Easing;
import code.miaware.api.utils.color.ColorUtil;
import code.miaware.api.utils.color.UIColors;
import java.awt.*;
import java.util.*;
import java.util.List;
@ModuleRegister(name = "Line Glyphs", category = Category.RENDER)
public class LineGlyphsModule extends Module {
@Getter private static final LineGlyphsModule instance = new LineGlyphsModule();
private final SliderSetting count = new SliderSetting("Count").value(70f).range(10f, 200f).step(5f);
private final BooleanSetting slow = new BooleanSetting("Slow Speed").value(false);
private final ModeSetting colorMode = new ModeSetting("Color").value("Theme").values("Theme", "Rainbow", "Single");
private final List<Glyph> glyphs = new ArrayList<>();
private final Random rand = new Random(93882L);
public LineGlyphsModule() {
addSettings(count, slow, colorMode);
}
@Override
public void onEnable() {
glyphs.clear();
}
@Override
public void onEvent() {
EventListener tick = TickEvent.getInstance().subscribe(new Listener<>(e -> {
if (mc.player == null) return;
glyphs.removeIf(g -> g.isDead());
int cap = count.getValue().intValue();
int attempts = 8;
while (attempts-- > 0 && glyphs.size() < cap) {
glyphs.add(new Glyph(spawnPos(), rand.nextInt(7, 13)));
}
glyphs.forEach(Glyph::tick);
}));
EventListener render = Render3DEvent.getInstance().subscribe(new Listener<>(e -> {
if (mc.player == null) return;
drawAll(e.matrixStack(), e.partialTicks());
}));
addEvents(tick, render);
}
private void drawAll(MatrixStack ms, float pt) {
if (glyphs.isEmpty()) return;
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE);
RenderSystem.disableCull();
RenderSystem.disableDepthTest();
RenderSystem.depthMask(false);
RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
Vec3d cam = mc.gameRenderer.getCamera().getPos();
int idx = 0;
for (Glyph g : glyphs) {
List<Vec3d> pts = g.getPoints(pt);
if (pts.size() < 2) { idx++; continue; }
float lineW = calcLineWidth(g, cam);
RenderSystem.lineWidth(lineW);
BufferBuilder buf = Tessellator.getInstance().begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP, VertexFormats.POSITION_COLOR);
Matrix4f mat = ms.peek().getPositionMatrix();
int ci = idx;
int step = 0;
for (Vec3d p : pts) {
float apc = g.alpha() * (0.25f + (float) step / pts.size() / 1.75f);
Color c = stateColor(ci, apc);
buf.vertex(mat,
(float)(p.x - cam.x),
(float)(p.y - cam.y),
(float)(p.z - cam.z))
.color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
ci += 180;
step++;
}
BufferRenderer.drawWithGlobalProgram(buf.end());
RenderSystem.lineWidth(lineW * 3f);
BufferBuilder dots = Tessellator.getInstance().begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
ci = idx;
step = 0;
for (Vec3d p : pts) {
float apc = g.alpha() * (0.25f + (float) step / pts.size() / 1.75f);
Color c = stateColor(ci, apc);
dots.vertex(mat,
(float)(p.x - cam.x),
(float)(p.y - cam.y),
(float)(p.z - cam.z))
.color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
ci += 180;
step++;
}
BufferRenderer.drawWithGlobalProgram(dots.end());
idx++;
}
RenderSystem.lineWidth(1f);
RenderSystem.depthMask(true);
RenderSystem.enableDepthTest();
RenderSystem.enableCull();
RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc();
}
private Color stateColor(int index, float alphaPC) {
Color base = switch (colorMode.getValue()) {
case "Rainbow" -> {
float hue = ((System.currentTimeMillis() / 20f + index * 2f) % 360f) / 360f;
yield Color.getHSBColor(hue, 1f, 1f);
}
case "Single" -> UIColors.primary();
default -> UIColors.gradient(index); // Theme
};
int a = Math.max(0, Math.min(255, (int)(alphaPC * 255f)));
return ColorUtil.setAlpha(base, a);
}
private float calcLineWidth(Glyph g, Vec3d cam) {
if (g.nodes.isEmpty()) return 1f;
int[] n0 = g.nodes.get(0);
Vec3d first = new Vec3d(n0[0], n0[1], n0[2]);
double dst = cam.distanceTo(first);
return 1e-4f + 3f * (float) Math.max(0, Math.min(1, 1.0 - dst / 20.0));
}
private int[] spawnPosInts() {
double fov = mc.options.getFov().getValue();
double yaw = Math.toRadians(rand.nextInt(
(int)(mc.player.getYaw() - fov * 0.75),
(int)(mc.player.getYaw() + fov * 0.75)));
double dst = rand.nextInt(6, 24);
int dx = (int)(-(Math.sin(yaw) * dst));
int dy = rand.nextInt(0, 12);
int dz = (int)(Math.cos(yaw) * dst);
Vec3d eye = mc.player.getEyePos();
return new int[]{(int)eye.x + dx, (int)eye.y + dy, (int)eye.z + dz};
}
private int[] spawnPos() { return spawnPosInts(); }
private int[] randXY() {
return new int[]{rand.nextInt(0, 4) * 90, rand.nextInt(-1, 2) * 90};
}
private int[] nextDir(int[] prev) {
int a = prev[0], b = prev[1];
int nb = b;
for (int i = 150; i > 0 && Math.abs(nb - b) != 90; i--) nb = rand.nextInt(-2, 2) * 90;
int na = a;
for (int i = 5; i > 0 && Math.abs(na - a) != 90; i--) na = rand.nextInt(0, 4) * 90;
return new int[]{na, nb};
}
private int[] step(int[] pos, int[] dir, int r) {
double yaw = Math.toRadians(dir[0]);
double pitch = Math.toRadians(dir[1]);
double r1 = r;
int ry = (int)(Math.sin(pitch) * r1);
if (pitch != 0) r1 = 0;
int rx = (int)(-(Math.sin(yaw) * r1));
int rz = (int)(Math.cos(yaw) * r1);
return new int[]{pos[0] + rx, pos[1] + ry, pos[2] + rz};
}
private class Glyph {
final List<int[]> nodes = new ArrayList<>();
private int[] dir;
private int stepsLeft;
private int ticksLeft;
private int lastSet;
private boolean dying = false;
private final AnimationUtil anim = new AnimationUtil();
Glyph(int[] spawn, int steps) {
nodes.add(spawn);
dir = randXY();
stepsLeft = steps;
anim.setValue(0.0);
anim.run(1.0, 600, Easing.SINE_OUT);
}
void tick() {
anim.update();
if (stepsLeft == 0) {
if (!dying) {
dying = true;
anim.run(0.0, 400, Easing.SINE_IN);
}
return;
}
if (ticksLeft > 0) {
ticksLeft -= slow.getValue() ? 1 : 2;
if (ticksLeft < 0) ticksLeft = 0;
return;
}
dir = nextDir(dir);
lastSet = ticksLeft = rand.nextInt(0, 3);
nodes.add(step(nodes.get(nodes.size() - 1), dir, Math.max(1, ticksLeft)));
stepsLeft--;
}
float alpha() { return (float) anim.getValue(); }
boolean isDead() {
return stepsLeft == 0 && anim.getValue() < 0.01 && anim.isFinished();
}
List<Vec3d> getPoints(float pt) {
List<Vec3d> out = new ArrayList<>();
for (int i = 0; i < nodes.size(); i++) {
int[] n = nodes.get(i);
double x = n[0], y = n[1], z = n[2];
// smooth last segment
if (i == nodes.size() - 1 && nodes.size() >= 2) {
int[] prev = nodes.get(i - 1);
float adv = lastSet > 0 ? Math.max(0, Math.min(1, 1f - (float) ticksLeft / lastSet)) : 1f;
x = lerp(prev[0], x, adv);
y = lerp(prev[1], y, adv);
z = lerp(prev[2], z, adv);
}
out.add(new Vec3d(x, y, z));
}
return out;
}
private double lerp(double a, double b, float t) { return a + (b - a) * t; }
}
}
ss:
