Lead Indicator fix

This commit is contained in:
vottozi 2026-02-25 22:18:47 +06:00
parent fa3a4c66c9
commit fb1b0a1c2e

View File

@ -858,41 +858,38 @@ namespace ZL
Vector3f shooterVel = ForwardFromRotation(Environment::shipState.rotation) * Environment::shipState.velocity; Vector3f shooterVel = ForwardFromRotation(Environment::shipState.rotation) * Environment::shipState.velocity;
Vector3f targetVel = ForwardFromRotation(st.rotation) * st.velocity; Vector3f targetVel = ForwardFromRotation(st.rotation) * st.velocity;
// условие "если враг не движется — круг не рисуем"
const float minTargetSpeed = 0.5f; // подобрать (в твоих единицах) const float minTargetSpeed = 0.5f; // подобрать (в твоих единицах)
bool targetMoving = (targetVel.norm() > minTargetSpeed); bool targetMoving = (targetVel.norm() > minTargetSpeed);
// альфа круга
float leadAlpha = targetMoving ? 1.0f : 0.5f;
Vector3f leadWorld = shipWorld; Vector3f leadWorld = shipWorld;
bool haveLead = false; bool haveLead = false;
//if (targetMoving) { // чтобы круг не улетал далеко : максимум 4 секунды(подстрой под игру)
// float tLead = 0.0f; float distToTarget = (Environment::shipState.position - shipWorld).norm();
// if (SolveLeadInterceptTime(shooterPos, shooterVel, shipWorld, targetVel, projectileSpeed, tLead)) { float maxLeadTime = std::clamp((distToTarget / projectileSpeed) * 1.2f, 0.05f, 4.0f);
// // ограничим случаи, чтобы круг не улетал далеко
// if (tLead > 0.0f && tLead < 8.0f) {
// // подобрать максимум (сек)
// leadWorld = shipWorld + targetVel * tLead;
// haveLead = true;
// }
// }
//}
if (targetMoving) { if (!targetMoving) {
// Цель стоит: рисуем lead прямо на ней, но полупрозрачный
leadWorld = shipWorld;
haveLead = true;
}
else {
float tLead = 0.0f; float tLead = 0.0f;
float distToTarget = (Environment::shipState.position - shipWorld).norm();
const float leadMaxDist = 2500.0f; // максимум // 1) Пытаемся “правильное” решение перехвата
float allowedDist = min(distToTarget, leadMaxDist); bool ok = SolveLeadInterceptTime(shooterPos, shooterVel, shipWorld, targetVel, projectileSpeed, tLead);
// + небольшой запас 1020% чтобы не моргало на границе // 2) Если решения нет / оно плохое — fallback (чтобы круг не пропадал при пролёте "вбок")
const float maxLeadTime = (allowedDist / projectileSpeed) * 1.2f; // Это ключевое изменение: lead всегда будет.
if (!ok || !(tLead > 0.0f) || tLead > maxLeadTime) {
if (SolveLeadInterceptTime(shooterPos, shooterVel, shipWorld, targetVel, projectileSpeed, tLead)) { tLead = std::clamp(distToTarget / projectileSpeed, 0.05f, maxLeadTime);
if (tLead > 0.0f && tLead < maxLeadTime) {
leadWorld = shipWorld + targetVel * tLead;
haveLead = true;
}
} }
leadWorld = shipWorld + targetVel * tLead;
haveLead = true;
} }
// 2) проекция // 2) проекция
@ -965,6 +962,10 @@ namespace ZL
renderer.PushMatrix(); renderer.PushMatrix();
renderer.LoadIdentity(); renderer.LoadIdentity();
// базовый цвет для HUD (скобки/стрелка) — непрозрачный
Eigen::Vector4f hudColor = enemyColor;
renderer.RenderUniform4fv("uColor", hudColor.data());
// рисуем кружок упреждения (только если есть решение) // рисуем кружок упреждения (только если есть решение)
if (haveLead) { if (haveLead) {
float leadNdcX, leadNdcY, leadNdcZ, leadClipW; float leadNdcX, leadNdcY, leadNdcZ, leadClipW;
@ -981,9 +982,16 @@ namespace ZL
float innerR = max(1.0f, r - thicknessPx); float innerR = max(1.0f, r - thicknessPx);
float outerR = r + thicknessPx; float outerR = r + thicknessPx;
// для lead indicator alpha: 1.0 если движется, 0.5 если стоит
Eigen::Vector4f leadColor = enemyColor;
leadColor.w() = leadAlpha;
renderer.RenderUniform4fv("uColor", leadColor.data());
VertexDataStruct ring = MakeRing2D(lx, ly, innerR, outerR, 0.0f, 32, enemyColor); VertexDataStruct ring = MakeRing2D(lx, ly, innerR, outerR, 0.0f, 32, enemyColor);
hudTempMesh.AssignFrom(ring); hudTempMesh.AssignFrom(ring);
renderer.DrawVertexRenderStruct(hudTempMesh); renderer.DrawVertexRenderStruct(hudTempMesh);
renderer.RenderUniform4fv("uColor", hudColor.data());
} }
} }
} }