engine-c: denser mid-air tracers + artillery/missile arcs
This commit is contained in:
parent
1ef6df4ce5
commit
b4d3388701
7 changed files with 187 additions and 76 deletions
|
|
@ -312,6 +312,9 @@ typedef struct Building {
|
|||
/* ----------------------------------------------------------------------- */
|
||||
typedef struct {
|
||||
float x, y, tx, ty;
|
||||
float ox, oy; /* origin for ballistic arc (shell/missile) */
|
||||
float loft; /* peak height above chord; 0 = linear */
|
||||
float prog; /* 0..1 along chord for lofted kinds */
|
||||
float speed;
|
||||
float damage;
|
||||
Faction faction;
|
||||
|
|
@ -560,6 +563,7 @@ int bld_research(Game *g, Faction f, int up);
|
|||
/* ----------------------------------------------------------------------- */
|
||||
void bullet_spawn(Game *g, float x, float y, int target_unit, int target_bld,
|
||||
float dmg, Faction f, int kind);
|
||||
void bullet_place_at_prog(Bullet *b, float prog);
|
||||
void bullet_update(Game *g, float dt);
|
||||
void particle_spawn(Game *g, float x, float y, int kind, uint8_t cr, uint8_t cg, uint8_t cb);
|
||||
void particle_burst(Game *g, float x, float y, int n, int kind, uint8_t cr, uint8_t cg, uint8_t cb);
|
||||
|
|
|
|||
|
|
@ -210,10 +210,14 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
|||
unit_spawn(g, UT_RAVAGER, human, wx + 78, wy - 58);
|
||||
unit_spawn(g, UT_ARTILLERY, human, wx + 18, wy + 48);
|
||||
unit_spawn(g, UT_ARTILLERY, human, wx + 38, wy + 62);
|
||||
unit_spawn(g, UT_ARTILLERY, human, wx + 8, wy + 28);
|
||||
unit_spawn(g, UT_ARTILLERY, human, wx + 52, wy + 44);
|
||||
unit_spawn(g, UT_FLAME, human, wx - 40, wy + 12);
|
||||
unit_spawn(g, UT_FLAME, human, wx + 105, wy - 5);
|
||||
unit_spawn(g, UT_MISSILE, human, wx - 55, wy - 8);
|
||||
unit_spawn(g, UT_MISSILE, human, wx + 110, wy - 40);
|
||||
unit_spawn(g, UT_MISSILE, human, wx + 96, wy - 52);
|
||||
unit_spawn(g, UT_MISSILE, human, wx + 120, wy - 18);
|
||||
unit_spawn(g, UT_JEEP, human, wx + 32, wy - 52);
|
||||
unit_spawn(g, UT_JEEP, human, wx + 48, wy - 68);
|
||||
unit_spawn(g, UT_BUGGY, human, wx + 55, wy - 78);
|
||||
|
|
@ -649,8 +653,12 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
|||
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx + 62, ry - 28);
|
||||
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx + 78, ry - 8);
|
||||
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx + 94, ry + 6);
|
||||
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx + 108, ry - 20);
|
||||
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx + 70, ry + 14);
|
||||
raid[rn++] = unit_spawn(g, UT_ARTILLERY, enemy, rx + 85, ry + 10);
|
||||
raid[rn++] = unit_spawn(g, UT_ARTILLERY, enemy, rx + 98, ry - 18);
|
||||
raid[rn++] = unit_spawn(g, UT_ARTILLERY, enemy, rx + 112, ry + 4);
|
||||
raid[rn++] = unit_spawn(g, UT_ARTILLERY, enemy, rx + 76, ry - 40);
|
||||
for (int i = 0; i < 8; i++)
|
||||
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||
rx - 28 + (i % 4) * 14, ry - 8 + (i / 4) * 14);
|
||||
|
|
|
|||
|
|
@ -203,36 +203,39 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
/* Mid-flight shells/missiles/lasers: after ~1s sim most live
|
||||
* bullets have already impacted. Reseed between nearby opposing
|
||||
* pairs so the PNG shows KKND2-like tracers across the clash. */
|
||||
* bullets have already impacted. Reseed from attacker origin with
|
||||
* mid-flight prog so lofted kinds keep their parabolic arc in PNG. */
|
||||
{
|
||||
int spawned = 0;
|
||||
const float pair_r2 = 180.0f * 180.0f;
|
||||
for (int i = 0; i < g->unit_count && spawned < 72; i++) {
|
||||
for (int i = 0; i < g->unit_count && spawned < 110; i++) {
|
||||
Unit *a = &g->units[i];
|
||||
if (a->dead) continue;
|
||||
float ax = a->x - clash_x, ay = a->y - clash_y;
|
||||
if (ax * ax + ay * ay > r2) continue;
|
||||
int shots = 0;
|
||||
for (int j = 0; j < g->unit_count && spawned < 72 && shots < 3; j++) {
|
||||
for (int j = 0; j < g->unit_count && spawned < 110 && shots < 4; j++) {
|
||||
Unit *b = &g->units[j];
|
||||
if (b->dead || b->faction == a->faction) continue;
|
||||
float dx = b->x - a->x, dy = b->y - a->y;
|
||||
float d2 = dx * dx + dy * dy;
|
||||
if (d2 > pair_r2 || d2 < 20.0f * 20.0f) continue;
|
||||
int kind = (spawned % 4 == 0) ? 3
|
||||
: (spawned % 4 == 1) ? 1
|
||||
: (spawned % 4 == 2) ? 2 : 0;
|
||||
/* bias shell/missile arcs over MG/laser */
|
||||
int kind = (spawned % 5 == 0) ? 0
|
||||
: (spawned % 5 == 1) ? 2
|
||||
: (spawned % 5 == 2) ? 1
|
||||
: (spawned % 5 == 3) ? 3 : 1;
|
||||
float t = 0.18f + 0.60f * ((spawned * 37) % 100) / 100.0f;
|
||||
float sx = a->x + dx * t;
|
||||
float sy = a->y + dy * t;
|
||||
bullet_spawn(g, sx, sy, b->id, -1, 1.0f, a->faction, kind);
|
||||
int before = g->bullet_count;
|
||||
bullet_spawn(g, a->x, a->y, b->id, -1, 1.0f, a->faction, kind);
|
||||
if (g->bullet_count > before)
|
||||
bullet_place_at_prog(&g->bullets[g->bullet_count - 1], t);
|
||||
spawned++;
|
||||
shots++;
|
||||
}
|
||||
}
|
||||
/* turret / base guns → nearest enemy in clash */
|
||||
for (int i = 0; i < g->bld_count && spawned < 88; i++) {
|
||||
for (int i = 0; i < g->bld_count && spawned < 130; i++) {
|
||||
Building *bl = &g->buildings[i];
|
||||
if (bl->dead || (bl->type != BT_TURRET && bl->type != BT_BASE))
|
||||
continue;
|
||||
|
|
@ -250,10 +253,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (best < 0) continue;
|
||||
Unit *tgt = &g->units[best];
|
||||
float dx = tgt->x - bx, dy = tgt->y - by;
|
||||
float t = 0.25f + 0.45f * ((spawned * 19) % 100) / 100.0f;
|
||||
bullet_spawn(g, bx + dx * t, by + dy * t, tgt->id, -1,
|
||||
2.0f, bl->faction, (spawned & 1) ? 1 : 2);
|
||||
int kind = (spawned % 3 == 0) ? 3 : 1;
|
||||
int before = g->bullet_count;
|
||||
bullet_spawn(g, bx, by, tgt->id, -1, 2.0f, bl->faction, kind);
|
||||
if (g->bullet_count > before)
|
||||
bullet_place_at_prog(&g->bullets[g->bullet_count - 1], t);
|
||||
particle_burst(g, bx, by - 4.0f, 5, 2, 255, 220, 100);
|
||||
spawned++;
|
||||
}
|
||||
|
|
@ -307,29 +312,32 @@ int main(int argc, char **argv) {
|
|||
int spawned2 = 0;
|
||||
const float pair_r2 = 160.0f * 160.0f;
|
||||
const float r2b = 140.0f * 140.0f;
|
||||
for (int i = 0; i < g->unit_count && spawned2 < 48; i++) {
|
||||
for (int i = 0; i < g->unit_count && spawned2 < 72; i++) {
|
||||
Unit *a = &g->units[i];
|
||||
if (a->dead) continue;
|
||||
float ax = a->x - clash2_x, ay = a->y - clash2_y;
|
||||
if (ax * ax + ay * ay > r2b) continue;
|
||||
int shots = 0;
|
||||
for (int j = 0; j < g->unit_count && spawned2 < 48 && shots < 3; j++) {
|
||||
for (int j = 0; j < g->unit_count && spawned2 < 72 && shots < 4; j++) {
|
||||
Unit *b = &g->units[j];
|
||||
if (b->dead || b->faction == a->faction) continue;
|
||||
float dx = b->x - a->x, dy = b->y - a->y;
|
||||
float d2 = dx * dx + dy * dy;
|
||||
if (d2 > pair_r2 || d2 < 18.0f * 18.0f) continue;
|
||||
int kind = (spawned2 % 4 == 0) ? 3
|
||||
: (spawned2 % 4 == 1) ? 1
|
||||
: (spawned2 % 4 == 2) ? 2 : 0;
|
||||
int kind = (spawned2 % 5 == 0) ? 0
|
||||
: (spawned2 % 5 == 1) ? 2
|
||||
: (spawned2 % 5 == 2) ? 1
|
||||
: (spawned2 % 5 == 3) ? 3 : 1;
|
||||
float t = 0.18f + 0.58f * ((spawned2 * 41) % 100) / 100.0f;
|
||||
bullet_spawn(g, a->x + dx * t, a->y + dy * t,
|
||||
b->id, -1, 1.0f, a->faction, kind);
|
||||
int before = g->bullet_count;
|
||||
bullet_spawn(g, a->x, a->y, b->id, -1, 1.0f, a->faction, kind);
|
||||
if (g->bullet_count > before)
|
||||
bullet_place_at_prog(&g->bullets[g->bullet_count - 1], t);
|
||||
spawned2++;
|
||||
shots++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < g->bld_count && spawned2 < 56; i++) {
|
||||
for (int i = 0; i < g->bld_count && spawned2 < 88; i++) {
|
||||
Building *bl = &g->buildings[i];
|
||||
if (bl->dead || (bl->type != BT_TURRET && bl->type != BT_BASE))
|
||||
continue;
|
||||
|
|
@ -347,10 +355,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (best < 0) continue;
|
||||
Unit *tgt = &g->units[best];
|
||||
float dx = tgt->x - bx, dy = tgt->y - by;
|
||||
float t = 0.26f + 0.44f * ((spawned2 * 23) % 100) / 100.0f;
|
||||
bullet_spawn(g, bx + dx * t, by + dy * t, tgt->id, -1,
|
||||
2.0f, bl->faction, (spawned2 & 1) ? 1 : 2);
|
||||
int kind = (spawned2 % 3 == 0) ? 3 : 1;
|
||||
int before = g->bullet_count;
|
||||
bullet_spawn(g, bx, by, tgt->id, -1, 2.0f, bl->faction, kind);
|
||||
if (g->bullet_count > before)
|
||||
bullet_place_at_prog(&g->bullets[g->bullet_count - 1], t);
|
||||
spawned2++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -439,37 +439,54 @@ void render_units(Game *g) {
|
|||
}
|
||||
|
||||
void render_bullets(Game *g) {
|
||||
/* Kind-aware tracers / shells with streak tails (parity with snapshot.c). */
|
||||
/* Kind-aware tracers / shells; lofted kinds sample the parabola trail. */
|
||||
for (int i = 0; i < g->bullet_count; i++) {
|
||||
Bullet *b = &g->bullets[i];
|
||||
int sx = (int)(b->x - g->cam.x), sy = (int)(b->y - g->cam.y);
|
||||
int lofted = (b->kind == 1 || b->kind == 3) && b->loft > 0.5f;
|
||||
if (lofted) {
|
||||
int len = (b->kind == 3) ? 28 : 22;
|
||||
float step = 0.018f;
|
||||
for (int t = 1; t <= len; t++) {
|
||||
float tp = b->prog - step * (float)t;
|
||||
if (tp < 0.0f) break;
|
||||
float wx = b->ox + (b->tx - b->ox) * tp;
|
||||
float wy = b->oy + (b->ty - b->oy) * tp
|
||||
- b->loft * 4.0f * tp * (1.0f - tp);
|
||||
int tx = (int)(wx - g->cam.x);
|
||||
int ty = (int)(wy - g->cam.y);
|
||||
if (b->kind == 3) {
|
||||
SDL_SetRenderDrawColor(g->ren, 255, (Uint8)(120 - t * 3), 30, 230);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ tx - 1, ty - 1,
|
||||
(t < 4) ? 3 : 2, (t < 4) ? 3 : 2 });
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(g->ren, 255, (Uint8)(200 - t * 7), 50, 220);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ tx, ty, 2, 2 });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float dx = b->tx - b->x, dy = b->ty - b->y;
|
||||
float d = sqrtf(dx * dx + dy * dy);
|
||||
if (d > 1.0f) {
|
||||
float ux = dx / d, uy = dy / d;
|
||||
int len = (b->kind == 2) ? 32 : (b->kind == 3) ? 24
|
||||
: (b->kind == 1) ? 20 : 14;
|
||||
int len = (b->kind == 2) ? 32 : 14;
|
||||
for (int t = 1; t <= len; t++) {
|
||||
int tx = sx - (int)(ux * (float)t * 0.75f);
|
||||
int ty = sy - (int)(uy * (float)t * 0.75f);
|
||||
Uint8 fade = (Uint8)(255 - t * 9);
|
||||
if (b->kind == 2) {
|
||||
/* laser: cyan→magenta streak */
|
||||
SDL_SetRenderDrawColor(g->ren, fade, 80, 255, 220);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ tx - 1, ty - 1,
|
||||
(t < 3) ? 3 : 2, (t < 3) ? 3 : 2 });
|
||||
SDL_SetRenderDrawColor(g->ren, 220, 180, 255, 255);
|
||||
SDL_RenderDrawPoint(g->ren, tx, ty);
|
||||
} else if (b->kind == 3) {
|
||||
SDL_SetRenderDrawColor(g->ren, 255, (Uint8)(120 - t * 4), 30, 230);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ tx - 1, ty - 1,
|
||||
(t < 4) ? 3 : 2, (t < 4) ? 3 : 2 });
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(g->ren, 255, (Uint8)(200 - t * 8), 50, 220);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ tx, ty, 2, 2 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int rad = (b->kind == 1 || b->kind == 3) ? 8 : 5;
|
||||
SDL_SetRenderDrawColor(g->ren, 255, 160, 40, 255);
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx - rad - 1, sy - rad - 1,
|
||||
|
|
|
|||
|
|
@ -925,31 +925,46 @@ void snapshot_capture(Game *g, const char *path) {
|
|||
draw_unit(u, sx, sy);
|
||||
}
|
||||
|
||||
/* projectiles — bright tracers / shells with streak tails (KKND2-like) */
|
||||
/* projectiles — lofted shell/missile sample parabola; else linear streak */
|
||||
for (int i = 0; i < g->bullet_count; i++) {
|
||||
Bullet *p = &g->bullets[i];
|
||||
int sx = (int)(p->x - camx), sy = (int)(p->y - camy);
|
||||
int lofted = (p->kind == 1 || p->kind == 3) && p->loft > 0.5f;
|
||||
if (lofted) {
|
||||
int len = (p->kind == 3) ? 28 : 22;
|
||||
float step = 0.018f;
|
||||
for (int t = 1; t <= len; t++) {
|
||||
float tp = p->prog - step * (float)t;
|
||||
if (tp < 0.0f) break;
|
||||
float wx = p->ox + (p->tx - p->ox) * tp;
|
||||
float wy = p->oy + (p->ty - p->oy) * tp
|
||||
- p->loft * 4.0f * tp * (1.0f - tp);
|
||||
int tx = (int)(wx - camx);
|
||||
int ty = (int)(wy - camy);
|
||||
if (p->kind == 3)
|
||||
disc(tx, ty, (t < 4) ? 2 : 1, 255, (uint8_t)(120 - t * 3), 30);
|
||||
else
|
||||
disc(tx, ty, 1, 255, (uint8_t)(200 - t * 7), 50);
|
||||
}
|
||||
} else {
|
||||
float dx = p->tx - p->x, dy = p->ty - p->y;
|
||||
float d = sqrtf(dx * dx + dy * dy);
|
||||
if (d > 1.0f) {
|
||||
float ux = dx / d, uy = dy / d;
|
||||
int len = (p->kind == 2) ? 32 : (p->kind == 3) ? 24
|
||||
: (p->kind == 1) ? 20 : 14;
|
||||
int len = (p->kind == 2) ? 32 : 14;
|
||||
for (int t = 1; t <= len; t++) {
|
||||
int tx = sx - (int)(ux * (float)t * 0.75f);
|
||||
int ty = sy - (int)(uy * (float)t * 0.75f);
|
||||
uint8_t fade = (uint8_t)(255 - t * 9);
|
||||
if (p->kind == 2) {
|
||||
/* laser beam: cyan→magenta streak */
|
||||
disc(tx, ty, (t < 3) ? 2 : 1, fade, 80, 255);
|
||||
px(tx, ty, 220, 180, 255);
|
||||
} else if (p->kind == 3) {
|
||||
disc(tx, ty, (t < 4) ? 2 : 1, 255, (uint8_t)(120 - t * 4), 30);
|
||||
} else {
|
||||
disc(tx, ty, 1, 255, (uint8_t)(200 - t * 8), 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int rad = (p->kind == 1 || p->kind == 3) ? 8 : 5;
|
||||
disc(sx, sy, rad + 1, 255, 160, 40);
|
||||
disc(sx, sy, rad, 255, 240, 140);
|
||||
|
|
|
|||
|
|
@ -351,8 +351,8 @@ static void unit_combat_step(Game *g, Unit *u, float dt) {
|
|||
if ((tu || tb) && d <= rng) {
|
||||
u->heading = (float)atan2(ty - u->y, tx - u->x);
|
||||
if (u->atk_cd <= 0) {
|
||||
int kind = (u->type == UT_ARTILLERY || u->type == UT_MISSILE || u->type == UT_TANK)
|
||||
? 1 : 0;
|
||||
int kind = (u->type == UT_MISSILE) ? 3
|
||||
: (u->type == UT_ARTILLERY || u->type == UT_TANK) ? 1 : 0;
|
||||
/* muzzle offset along heading so shot/live FX sit at barrel tip */
|
||||
float mx = u->x + cosf(u->heading) * 14.0f;
|
||||
float my = u->y + sinf(u->heading) * 14.0f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue