engine-c: denser mid-air tracers + artillery/missile arcs

This commit is contained in:
local-model/engine-L2-grok-4.5 2026-09-19 17:42:57 +02:00
parent 1ef6df4ce5
commit b4d3388701
No known key found for this signature in database
7 changed files with 187 additions and 76 deletions

View file

@ -7,11 +7,36 @@
static RNG g_prng;
static int g_prng_init = 0;
/* Place bullet on chord+parabola: loft peaks at prog=0.5 (screen-y up = -). */
static void bullet_place_arc(Bullet *b) {
float t = b->prog;
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
b->x = b->ox + (b->tx - b->ox) * t;
b->y = b->oy + (b->ty - b->oy) * t - b->loft * 4.0f * t * (1.0f - t);
}
/* Mid-flight place: set prog then arc (shell/missile) or linear chord. */
void bullet_place_at_prog(Bullet *b, float prog) {
if (prog < 0.0f) prog = 0.0f;
if (prog > 1.0f) prog = 1.0f;
b->prog = prog;
if ((b->kind == 1 || b->kind == 3) && b->loft > 0.5f)
bullet_place_arc(b);
else {
b->x = b->ox + (b->tx - b->ox) * prog;
b->y = b->oy + (b->ty - b->oy) * prog;
}
}
void bullet_spawn(Game *g, float x, float y, int target_unit, int target_bld,
float dmg, Faction f, int kind) {
if (g->bullet_count >= MAX_BULLETS) return;
Bullet *b = &g->bullets[g->bullet_count++];
b->x = x; b->y = y;
b->ox = x; b->oy = y;
b->prog = 0.0f;
b->loft = 0.0f;
b->target_unit = target_unit;
b->target_bld = target_bld;
b->damage = dmg;
@ -19,6 +44,7 @@ void bullet_spawn(Game *g, float x, float y, int target_unit, int target_bld,
b->kind = kind;
b->speed = (kind == 3) ? 320 : (kind == 1 ? 420 : 520);
b->life = 3.0f;
b->tx = x; b->ty = y;
if (target_unit >= 0) {
Unit *t = unit_by_id(g, target_unit);
if (t) { b->tx = t->x; b->ty = t->y; }
@ -27,6 +53,15 @@ void bullet_spawn(Game *g, float x, float y, int target_unit, int target_bld,
if (t) { b->tx = (float)(t->tx*TILE + t->w*TILE/2);
b->ty = (float)(t->ty*TILE + t->h*TILE/2); }
}
/* shells / missiles get a parabolic loft scaled by range */
if (kind == 1 || kind == 3) {
float dx = b->tx - b->ox, dy = b->ty - b->oy;
float dist = sqrtf(dx * dx + dy * dy);
float base = (kind == 3) ? 28.0f : 18.0f;
b->loft = base + dist * ((kind == 3) ? 0.22f : 0.14f);
if (b->loft > 90.0f) b->loft = 90.0f;
bullet_place_arc(b);
}
}
void bullet_update(Game *g, float dt) {
@ -45,10 +80,26 @@ void bullet_update(Game *g, float dt) {
else b->target_bld = -1;
}
float dx = b->tx - b->x, dy = b->ty - b->y;
float d = (float)sqrtf(dx*dx + dy*dy);
float step = b->speed * dt;
if (d <= step + 4 || b->life <= 0) {
int lofted = (b->kind == 1 || b->kind == 3) && b->loft > 0.5f;
float hit = 0;
if (lofted) {
float cdx = b->tx - b->ox, cdy = b->ty - b->oy;
float chord = sqrtf(cdx * cdx + cdy * cdy);
if (chord < 1.0f) chord = 1.0f;
b->prog += (b->speed * dt) / chord;
bullet_place_arc(b);
hit = (b->prog >= 1.0f || b->life <= 0) ? 1.0f : 0.0f;
} else {
float dx = b->tx - b->x, dy = b->ty - b->y;
float d = (float)sqrtf(dx*dx + dy*dy);
float step = b->speed * dt;
if (d <= step + 4 || b->life <= 0) hit = 1.0f;
else {
b->x += dx/d * step;
b->y += dy/d * step;
}
}
if (hit > 0) {
/* impact */
if (b->target_unit >= 0) {
Unit *t = unit_by_id(g, b->target_unit);
@ -69,16 +120,22 @@ void bullet_update(Game *g, float dt) {
g->bullet_count--;
continue;
}
b->x += dx/d * step;
b->y += dy/d * step;
/* trail — denser muzzle streak for non-ballistic shells */
/* trail — denser muzzle streak for non-MG */
if (b->kind != 0)
particle_spawn(g, b->x, b->y, 2, 255, 180, 60);
if (b->kind == 1 || b->kind == 3) {
particle_spawn(g, b->x - dx / d * 3.0f, b->y - dy / d * 3.0f,
3, 255, 160, 50);
particle_spawn(g, b->x - dx / d * 6.0f, b->y - dy / d * 6.0f,
1, 255, 140, 40);
float tback = b->prog - 0.04f;
if (tback < 0.0f) tback = 0.0f;
float bx = b->ox + (b->tx - b->ox) * tback;
float by = b->oy + (b->ty - b->oy) * tback
- b->loft * 4.0f * tback * (1.0f - tback);
particle_spawn(g, bx, by, 3, 255, 160, 50);
tback = b->prog - 0.08f;
if (tback < 0.0f) tback = 0.0f;
bx = b->ox + (b->tx - b->ox) * tback;
by = b->oy + (b->ty - b->oy) * tback
- b->loft * 4.0f * tback * (1.0f - tback);
particle_spawn(g, bx, by, 1, 255, 140, 40);
}
if (b->kind == 2)
particle_spawn(g, b->x, b->y, 2, 180, 120, 255);