engine-c: scaffold beams + bld damage FX + wear showcase
This commit is contained in:
parent
a086ab23a6
commit
b2469dbcde
3 changed files with 114 additions and 4 deletions
|
|
@ -66,6 +66,39 @@ static void bld_force_complete(Game *g) {
|
|||
}
|
||||
}
|
||||
|
||||
/* After force-complete: leave a few incomplete yards + battle-worn
|
||||
* fortifications near the raid locus so scaffold/damage FX show in KKND_SHOT. */
|
||||
static void showcase_bld_battle_wear(Game *g) {
|
||||
int incomplete_n = 0, damaged_n = 0;
|
||||
float 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;
|
||||
for (int i = 0; i < g->bld_count; i++) {
|
||||
Building *b = &g->buildings[i];
|
||||
if (b->dead) continue;
|
||||
float cx = (b->tx + b->w * 0.5f) * (float)TILE;
|
||||
float cy = (b->ty + b->h * 0.5f) * (float)TILE;
|
||||
float dx = cx - rx, dy = cy - ry;
|
||||
float d2 = dx * dx + dy * dy;
|
||||
/* mid-base construction yards (away from clash) */
|
||||
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->build = (incomplete_n == 0) ? 0.55f : 0.72f;
|
||||
b->hp = b->max_hp * b->build * 0.9f;
|
||||
incomplete_n++;
|
||||
continue;
|
||||
}
|
||||
/* clash fortifications: turrets / walls / power take hits */
|
||||
if (damaged_n < 6 && d2 < 160.0f * 160.0f &&
|
||||
(b->type == BT_TURRET || b->type == BT_WALL || b->type == BT_POWER)) {
|
||||
float frac = (damaged_n % 3 == 0) ? 0.35f
|
||||
: (damaged_n % 3 == 1) ? 0.55f : 0.72f;
|
||||
b->hp = b->max_hp * frac;
|
||||
damaged_n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void place_start(Game *g, Faction f) {
|
||||
int sx = g->map.spawn_x[f], sy = g->map.spawn_y[f];
|
||||
int bx = sx - 1, by = sy - 1;
|
||||
|
|
@ -465,6 +498,9 @@ void engine_setup_match(Game *g, int mission_id) {
|
|||
bld_force_complete(g);
|
||||
}
|
||||
|
||||
/* demo incomplete yards + damaged clash fortifications for scaffold/FX */
|
||||
showcase_bld_battle_wear(g);
|
||||
|
||||
/* centre camera on player base */
|
||||
int hx = g->map.spawn_x[g->human], hy = g->map.spawn_y[g->human];
|
||||
g->cam.x = (float)(hx*TILE - VIEW_W/2);
|
||||
|
|
|
|||
|
|
@ -99,11 +99,26 @@ void render_buildings(Game *g) {
|
|||
SDL_Rect r = { sx, sy, W, H };
|
||||
SDL_Texture *tex = g->spr.bld[b->type][b->faction];
|
||||
if (b->build < 1.0f) {
|
||||
/* construction: draw then scaffold overlay */
|
||||
/* construction: ghost body + KKND2-style yard scaffold */
|
||||
SDL_SetTextureAlphaMod(tex, 160);
|
||||
SDL_RenderCopy(g->ren, tex, NULL, &r);
|
||||
SDL_SetTextureAlphaMod(tex, 255);
|
||||
int pct = (int)(b->build * 100);
|
||||
int mid = sy + (int)(H * b->build);
|
||||
/* corner posts + rails */
|
||||
SDL_SetRenderDrawColor(g->ren, 175, 145, 85, 255);
|
||||
SDL_RenderDrawLine(g->ren, sx, sy, sx, sy + H);
|
||||
SDL_RenderDrawLine(g->ren, sx + W - 1, sy, sx + W - 1, sy + H);
|
||||
SDL_RenderDrawLine(g->ren, sx, sy + H - 1, sx + W, sy + H - 1);
|
||||
SDL_SetRenderDrawColor(g->ren, 210, 175, 100, 255);
|
||||
SDL_RenderDrawLine(g->ren, sx, sy, sx + W, sy);
|
||||
SDL_RenderDrawLine(g->ren, sx, mid, sx + W, mid);
|
||||
/* X-braces + optional mid post */
|
||||
SDL_SetRenderDrawColor(g->ren, 155, 125, 65, 230);
|
||||
SDL_RenderDrawLine(g->ren, sx + 2, sy + 2, sx + W - 2, sy + H - 2);
|
||||
SDL_RenderDrawLine(g->ren, sx + W - 2, sy + 2, sx + 2, sy + H - 2);
|
||||
if (W >= 48)
|
||||
SDL_RenderDrawLine(g->ren, sx + W / 2, sy, sx + W / 2, sy + H);
|
||||
/* progress bar above */
|
||||
SDL_Rect bar = { sx, sy - 8, W, 5 };
|
||||
SDL_SetRenderDrawColor(g->ren, 200, 200, 200, 255);
|
||||
SDL_RenderFillRect(g->ren, &bar);
|
||||
|
|
@ -113,6 +128,25 @@ void render_buildings(Game *g) {
|
|||
} else {
|
||||
SDL_RenderCopy(g->ren, tex, NULL, &r);
|
||||
}
|
||||
/* battle wear: scorch + crack lines when damaged */
|
||||
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);
|
||||
int pw = W / 4; if (pw < 4) pw = 4;
|
||||
int ph = H / 5; if (ph < 3) ph = 3;
|
||||
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 });
|
||||
if (dmg > 0.3f)
|
||||
SDL_RenderFillRect(g->ren, &(SDL_Rect){ sx + W / 2, sy + H / 2, pw, ph });
|
||||
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 + W / 2, sy + (H * 2) / 3, sx + W - 4, sy + H / 3);
|
||||
if (dmg > 0.5f) {
|
||||
SDL_RenderDrawLine(g->ren, sx + W / 3, sy + 2, sx + W / 3 + 4, sy + H - 2);
|
||||
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 + W - 10, sy + H - 5, 8, 5 });
|
||||
}
|
||||
}
|
||||
/* health bar if damaged or selected */
|
||||
if (b->hp < b->max_hp || b->selected) {
|
||||
SDL_Rect bar = { sx, sy - 6, W, 4 };
|
||||
|
|
|
|||
|
|
@ -318,8 +318,48 @@ static void draw_bld(Building *b, int sx, int sy) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (b->build < 1.0f)
|
||||
fill_rect(sx, sy, W, (int)(H * b->build), 255, 255, 255);
|
||||
/* construction scaffold: yard posts/rails/braces (not flat white wash) */
|
||||
if (b->build < 1.0f) {
|
||||
int mid = sy + (int)(H * b->build);
|
||||
if (mid > sy + 2)
|
||||
fill_rect(sx + 2, sy + 2, W - 4, mid - sy - 2, 235, 232, 220);
|
||||
line(sx, sy, sx, sy + H, 175, 145, 85);
|
||||
line(sx + W - 1, sy, sx + W - 1, sy + H, 175, 145, 85);
|
||||
line(sx, sy, sx + W, sy, 205, 175, 105);
|
||||
line(sx, mid, sx + W, mid, 215, 185, 115);
|
||||
line(sx, sy + H - 1, sx + W, sy + H - 1, 155, 125, 70);
|
||||
line(sx + 2, sy + 2, sx + W - 2, sy + H - 2, 150, 120, 65);
|
||||
line(sx + W - 2, sy + 2, sx + 2, sy + H - 2, 150, 120, 65);
|
||||
if (W >= 48)
|
||||
line(sx + W / 2, sy, sx + W / 2, sy + H, 165, 135, 75);
|
||||
/* progress tick above pad */
|
||||
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);
|
||||
}
|
||||
/* battle damage: scorch patches + crack lines + rubble chips */
|
||||
if (b->max_hp > 0 && b->hp < b->max_hp * 0.95f) {
|
||||
float dmg = 1.0f - (b->hp / b->max_hp);
|
||||
int pw = W / 4; if (pw < 3) pw = 3;
|
||||
int ph = H / 5; if (ph < 2) ph = 2;
|
||||
fill_rect(sx + W / 4, sy + H / 3, pw, ph, 45, 35, 25);
|
||||
if (dmg > 0.3f)
|
||||
fill_rect(sx + W / 2, sy + H / 2, pw, ph, 55, 40, 28);
|
||||
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);
|
||||
if (dmg > 0.5f) {
|
||||
line(sx + W / 3, sy + 2, sx + W / 3 + 3, sy + H - 2, 22, 18, 14);
|
||||
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);
|
||||
}
|
||||
/* thin HP bar so damage reads in KKND_SHOT */
|
||||
{
|
||||
int by = sy - 6;
|
||||
float f = b->hp / b->max_hp;
|
||||
fill_rect(sx - 1, by - 1, W + 2, 5, 20, 18, 14);
|
||||
fill_rect(sx, by, W, 3, 55, 48, 36);
|
||||
fill_rect(sx, by, (int)(W * f + 0.5f), 3, br, bg, 40);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void snapshot_capture(Game *g, const char *path) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue