engine-c: denser melee roster + building damage FX at clash
Raid packs grow (raid[96]); Evolved MUTANT/BEAST wedges + Survivor INFANTRY screens; stronger battle-wear + scorch/crack/ember draw in snapshot/live.
This commit is contained in:
parent
125dcf837a
commit
c551b85912
3 changed files with 76 additions and 12 deletions
|
|
@ -67,12 +67,13 @@ static void bld_force_complete(Game *g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After force-complete: leave a few incomplete yards + battle-worn
|
/* After force-complete: leave a few incomplete yards + battle-worn
|
||||||
* fortifications near the raid locus so scaffold/damage FX show in KKND_SHOT. */
|
* fortifications near both raid loci so scaffold/damage FX show in KKND_SHOT. */
|
||||||
static void showcase_bld_battle_wear(Game *g) {
|
static void showcase_bld_battle_wear(Game *g) {
|
||||||
int incomplete_n = 0, damaged_n = 0;
|
int incomplete_n = 0, damaged_n = 0;
|
||||||
float wx, wy;
|
float wx, wy;
|
||||||
map_tile_to_world(g->map.spawn_x[g->human], g->map.spawn_y[g->human], &wx, &wy);
|
map_tile_to_world(g->map.spawn_x[g->human], g->map.spawn_y[g->human], &wx, &wy);
|
||||||
float rx = wx + 88.0f, ry = wy - 48.0f;
|
float rx = wx + 88.0f, ry = wy - 48.0f;
|
||||||
|
float rx2 = wx + 140.0f, ry2 = wy + 96.0f;
|
||||||
for (int i = 0; i < g->bld_count; i++) {
|
for (int i = 0; i < g->bld_count; i++) {
|
||||||
Building *b = &g->buildings[i];
|
Building *b = &g->buildings[i];
|
||||||
if (b->dead) continue;
|
if (b->dead) continue;
|
||||||
|
|
@ -80,6 +81,9 @@ static void showcase_bld_battle_wear(Game *g) {
|
||||||
float cy = (b->ty + b->h * 0.5f) * (float)TILE;
|
float cy = (b->ty + b->h * 0.5f) * (float)TILE;
|
||||||
float dx = cx - rx, dy = cy - ry;
|
float dx = cx - rx, dy = cy - ry;
|
||||||
float d2 = dx * dx + dy * dy;
|
float d2 = dx * dx + dy * dy;
|
||||||
|
float dx2 = cx - rx2, dy2 = cy - ry2;
|
||||||
|
float d2b = dx2 * dx2 + dy2 * dy2;
|
||||||
|
float dmin = d2 < d2b ? d2 : d2b;
|
||||||
/* mid-base construction yards (away from clash) */
|
/* mid-base construction yards (away from clash) */
|
||||||
if (incomplete_n < 2 && b->faction == g->human && d2 > 180.0f * 180.0f &&
|
if (incomplete_n < 2 && b->faction == g->human && d2 > 180.0f * 180.0f &&
|
||||||
(b->type == BT_REPAIR || b->type == BT_RESEARCH || b->type == BT_WARFACTORY)) {
|
(b->type == BT_REPAIR || b->type == BT_RESEARCH || b->type == BT_WARFACTORY)) {
|
||||||
|
|
@ -88,11 +92,13 @@ static void showcase_bld_battle_wear(Game *g) {
|
||||||
incomplete_n++;
|
incomplete_n++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* clash fortifications: turrets / walls / power take hits */
|
/* clash fortifications + economy pads take hits at both fronts */
|
||||||
if (damaged_n < 6 && d2 < 160.0f * 160.0f &&
|
if (damaged_n < 16 && dmin < 220.0f * 220.0f &&
|
||||||
(b->type == BT_TURRET || b->type == BT_WALL || b->type == BT_POWER)) {
|
(b->type == BT_TURRET || b->type == BT_WALL || b->type == BT_POWER ||
|
||||||
float frac = (damaged_n % 3 == 0) ? 0.35f
|
b->type == BT_REFINERY || b->type == BT_BASE || b->type == BT_WARFACTORY)) {
|
||||||
: (damaged_n % 3 == 1) ? 0.55f : 0.72f;
|
float frac = (damaged_n % 4 == 0) ? 0.22f
|
||||||
|
: (damaged_n % 4 == 1) ? 0.40f
|
||||||
|
: (damaged_n % 4 == 2) ? 0.58f : 0.74f;
|
||||||
b->hp = b->max_hp * frac;
|
b->hp = b->max_hp * frac;
|
||||||
damaged_n++;
|
damaged_n++;
|
||||||
}
|
}
|
||||||
|
|
@ -216,6 +222,10 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
unit_spawn(g, UT_MEDIC, human, wx + 20, wy + 28);
|
unit_spawn(g, UT_MEDIC, human, wx + 20, wy + 28);
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
unit_spawn(g, UT_INFANTRY, human, wx + 88 + (i % 5) * 14, wy + 8 + (i / 5) * 16);
|
unit_spawn(g, UT_INFANTRY, human, wx + 88 + (i % 5) * 14, wy + 8 + (i / 5) * 16);
|
||||||
|
/* dense melee screen at primary clash (riflemen packed for KKND2 crop) */
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
unit_spawn(g, UT_INFANTRY, human,
|
||||||
|
wx + 72 + (i % 6) * 11, wy - 28 + (i / 6) * 12);
|
||||||
|
|
||||||
/* Evolved raid pack — close NE, overlapping Survivor line */
|
/* Evolved raid pack — close NE, overlapping Survivor line */
|
||||||
float rx = wx + 88.0f, ry = wy - 48.0f;
|
float rx = wx + 88.0f, ry = wy - 48.0f;
|
||||||
|
|
@ -602,8 +612,12 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
unit_spawn(g, UT_INFANTRY, human,
|
unit_spawn(g, UT_INFANTRY, human,
|
||||||
rx2 - 12 + (i % 3) * 12, ry2 - 16 + (i / 3) * 14);
|
rx2 - 12 + (i % 3) * 12, ry2 - 16 + (i / 3) * 14);
|
||||||
|
/* denser Survivor melee at SE clash */
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
unit_spawn(g, UT_INFANTRY, human,
|
||||||
|
rx2 - 22 + (i % 4) * 10, ry2 - 6 + (i / 4) * 11);
|
||||||
|
|
||||||
int raid[56];
|
int raid[96];
|
||||||
int rn = 0;
|
int rn = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
||||||
|
|
@ -632,8 +646,18 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||||
rx - 28 + (i % 4) * 14, ry - 8 + (i / 4) * 14);
|
rx - 28 + (i % 4) * 14, ry - 8 + (i / 4) * 14);
|
||||||
|
/* dense Evolved melee wedge into Survivor rifle screen */
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
||||||
|
rx - 8 + (i % 3) * 12, ry + 6 + (i / 3) * 11);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_BEAST, enemy,
|
||||||
|
rx + 4 + i * 13, ry + 18 + (i & 1) * 8);
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||||
|
rx - 18 + (i % 4) * 10, ry + 10 + (i / 4) * 9);
|
||||||
|
|
||||||
/* secondary Evolved pack at SE clash (room left in raid[56]) */
|
/* secondary Evolved pack at SE clash — melee-heavy */
|
||||||
int rn_pri = rn;
|
int rn_pri = rn;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
||||||
|
|
@ -651,6 +675,15 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||||
rx2 + 6 + i * 12, ry2 + 20 + i * 6);
|
rx2 + 6 + i * 12, ry2 + 20 + i * 6);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
||||||
|
rx2 - 4 + (i % 2) * 14, ry2 + 14 + (i / 2) * 12);
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_BEAST, enemy,
|
||||||
|
rx2 + 12 + i * 16, ry2 + 28 + i * 6);
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||||
|
rx2 - 10 + (i % 3) * 11, ry2 + 8 + (i / 3) * 10);
|
||||||
|
|
||||||
/* seed Survivor harvester beds so cargo silhouette is visible in shot */
|
/* seed Survivor harvester beds so cargo silhouette is visible in shot */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -128,23 +128,37 @@ void render_buildings(Game *g) {
|
||||||
} else {
|
} else {
|
||||||
SDL_RenderCopy(g->ren, tex, NULL, &r);
|
SDL_RenderCopy(g->ren, tex, NULL, &r);
|
||||||
}
|
}
|
||||||
/* battle wear: scorch + crack lines when damaged */
|
/* battle wear: scorch + cracks + rubble + ember (parity w/ snapshot) */
|
||||||
if (b->build >= 1.0f && b->max_hp > 0 && b->hp < b->max_hp * 0.95f) {
|
if (b->build >= 1.0f && b->max_hp > 0 && b->hp < b->max_hp * 0.95f) {
|
||||||
float dmg = 1.0f - (b->hp / b->max_hp);
|
float dmg = 1.0f - (b->hp / b->max_hp);
|
||||||
int pw = W / 4; if (pw < 4) pw = 4;
|
int pw = W / 4; if (pw < 4) pw = 4;
|
||||||
int ph = H / 5; if (ph < 3) ph = 3;
|
int ph = H / 5; if (ph < 3) ph = 3;
|
||||||
SDL_SetRenderDrawColor(g->ren, 42, 32, 22, (Uint8)(90 + (int)(dmg * 110)));
|
SDL_SetRenderDrawColor(g->ren, 42, 32, 22, (Uint8)(90 + (int)(dmg * 110)));
|
||||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 4, sy + H / 3, pw, ph });
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 4, sy + H / 3, pw, ph });
|
||||||
if (dmg > 0.3f)
|
if (dmg > 0.25f)
|
||||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 2, sy + H / 2, pw, ph });
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 2, sy + H / 2, pw, ph });
|
||||||
|
if (dmg > 0.45f)
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 6, sy + (H * 2) / 3, pw - 1, ph - 1 });
|
||||||
SDL_SetRenderDrawColor(g->ren, 25, 22, 18, 255);
|
SDL_SetRenderDrawColor(g->ren, 25, 22, 18, 255);
|
||||||
SDL_RenderDrawLine(g->ren, sx + 4, sy + H / 4, sx + W / 2, sy + (H * 2) / 3);
|
SDL_RenderDrawLine(g->ren, sx + 4, sy + H / 4, sx + W / 2, sy + (H * 2) / 3);
|
||||||
SDL_RenderDrawLine(g->ren, sx + W / 2, sy + (H * 2) / 3, sx + W - 4, sy + H / 3);
|
SDL_RenderDrawLine(g->ren, sx + W / 2, sy + (H * 2) / 3, sx + W - 4, sy + H / 3);
|
||||||
|
SDL_RenderDrawLine(g->ren, sx + W / 5, sy + 4, sx + (W * 3) / 5, sy + H / 2);
|
||||||
if (dmg > 0.5f) {
|
if (dmg > 0.5f) {
|
||||||
SDL_RenderDrawLine(g->ren, sx + W / 3, sy + 2, sx + W / 3 + 4, sy + H - 2);
|
SDL_RenderDrawLine(g->ren, sx + W / 3, sy + 2, sx + W / 3 + 4, sy + H - 2);
|
||||||
|
SDL_RenderDrawLine(g->ren, sx + (W * 2) / 3, sy + H / 5, sx + W / 4, sy + H - 3);
|
||||||
SDL_SetRenderDrawColor(g->ren, 90, 75, 55, 255);
|
SDL_SetRenderDrawColor(g->ren, 90, 75, 55, 255);
|
||||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + 2, sy + H - 4, 6, 4 });
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + 2, sy + H - 4, 6, 4 });
|
||||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W - 10, sy + H - 5, 8, 5 });
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W - 10, sy + H - 5, 8, 5 });
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 2 - 2, sy + H - 3, 6, 3 });
|
||||||
|
}
|
||||||
|
if (dmg > 0.65f) {
|
||||||
|
SDL_SetRenderDrawColor(g->ren, 220, 110, 40, 220);
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 2 - 1, sy + H / 2 - 1, 3, 3 });
|
||||||
|
SDL_SetRenderDrawColor(g->ren, 255, 160, 60, 200);
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 3 + 1, sy + (H * 2) / 3, 2, 2 });
|
||||||
|
SDL_SetRenderDrawColor(g->ren, 40, 32, 24, 255);
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + 4, sy + 3, 3, 2 });
|
||||||
|
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W - 8, sy + 4, 4, 3 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* outlined HP strip (green→red) when damaged or selected */
|
/* outlined HP strip (green→red) when damaged or selected */
|
||||||
|
|
|
||||||
|
|
@ -717,20 +717,37 @@ static void draw_bld(Building *b, int sx, int sy) {
|
||||||
fill_rect(sx, sy - 7, W, 4, 55, 50, 40);
|
fill_rect(sx, sy - 7, W, 4, 55, 50, 40);
|
||||||
fill_rect(sx, sy - 7, (int)(W * b->build + 0.5f), 4, 120, 220, 120);
|
fill_rect(sx, sy - 7, (int)(W * b->build + 0.5f), 4, 120, 220, 120);
|
||||||
}
|
}
|
||||||
/* battle damage: scorch patches + crack lines + rubble chips */
|
/* battle damage: scorch + cracks + rubble + ember (reads in KKND_SHOT) */
|
||||||
if (b->max_hp > 0 && b->hp < b->max_hp * 0.95f) {
|
if (b->max_hp > 0 && b->hp < b->max_hp * 0.95f) {
|
||||||
float dmg = 1.0f - (b->hp / b->max_hp);
|
float dmg = 1.0f - (b->hp / b->max_hp);
|
||||||
int pw = W / 4; if (pw < 3) pw = 3;
|
int pw = W / 4; if (pw < 3) pw = 3;
|
||||||
int ph = H / 5; if (ph < 2) ph = 2;
|
int ph = H / 5; if (ph < 2) ph = 2;
|
||||||
fill_rect(sx + W / 4, sy + H / 3, pw, ph, 45, 35, 25);
|
fill_rect(sx + W / 4, sy + H / 3, pw, ph, 45, 35, 25);
|
||||||
if (dmg > 0.3f)
|
disc(sx + W / 3, sy + H / 2, pw / 2 + 1, 38, 30, 22);
|
||||||
|
if (dmg > 0.25f) {
|
||||||
fill_rect(sx + W / 2, sy + H / 2, pw, ph, 55, 40, 28);
|
fill_rect(sx + W / 2, sy + H / 2, pw, ph, 55, 40, 28);
|
||||||
|
disc(sx + (W * 2) / 3, sy + H / 3, pw / 3 + 1, 48, 36, 24);
|
||||||
|
}
|
||||||
|
if (dmg > 0.45f) {
|
||||||
|
fill_rect(sx + W / 6, sy + (H * 2) / 3, pw - 1, ph - 1, 50, 38, 26);
|
||||||
|
disc(sx + W / 5, sy + H / 4, 2, 60, 42, 28);
|
||||||
|
}
|
||||||
line(sx + 3, sy + H / 4, sx + W / 2, sy + (H * 2) / 3, 28, 24, 18);
|
line(sx + 3, sy + H / 4, sx + W / 2, sy + (H * 2) / 3, 28, 24, 18);
|
||||||
line(sx + W / 2, sy + (H * 2) / 3, sx + W - 3, sy + H / 3, 28, 24, 18);
|
line(sx + W / 2, sy + (H * 2) / 3, sx + W - 3, sy + H / 3, 28, 24, 18);
|
||||||
|
line(sx + W / 5, sy + 4, sx + (W * 3) / 5, sy + H / 2, 32, 26, 20);
|
||||||
if (dmg > 0.5f) {
|
if (dmg > 0.5f) {
|
||||||
line(sx + W / 3, sy + 2, sx + W / 3 + 3, sy + H - 2, 22, 18, 14);
|
line(sx + W / 3, sy + 2, sx + W / 3 + 3, sy + H - 2, 22, 18, 14);
|
||||||
|
line(sx + (W * 2) / 3, sy + H / 5, sx + W / 4, sy + H - 3, 24, 20, 16);
|
||||||
fill_rect(sx + 2, sy + H - 4, 5, 3, 95, 78, 55);
|
fill_rect(sx + 2, sy + H - 4, 5, 3, 95, 78, 55);
|
||||||
fill_rect(sx + W - 9, sy + H - 5, 7, 4, 85, 70, 50);
|
fill_rect(sx + W - 9, sy + H - 5, 7, 4, 85, 70, 50);
|
||||||
|
fill_rect(sx + W / 2 - 2, sy + H - 3, 6, 3, 90, 72, 48);
|
||||||
|
}
|
||||||
|
if (dmg > 0.65f) {
|
||||||
|
/* ember glow in heavy breaches */
|
||||||
|
disc(sx + W / 2, sy + H / 2, 2, 220, 110, 40);
|
||||||
|
disc(sx + W / 3 + 2, sy + (H * 2) / 3, 1, 255, 160, 60);
|
||||||
|
fill_rect(sx + 4, sy + 3, 3, 2, 40, 32, 24);
|
||||||
|
fill_rect(sx + W - 8, sy + 4, 4, 3, 35, 28, 20);
|
||||||
}
|
}
|
||||||
/* thin HP bar so damage reads in KKND_SHOT */
|
/* thin HP bar so damage reads in KKND_SHOT */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue