engine-c: scrap mounds + lingering FX + secondary SE clash
This commit is contained in:
parent
0897293f51
commit
4411169cc3
5 changed files with 243 additions and 22 deletions
|
|
@ -357,8 +357,82 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* scrap mound fields: SE of HQ + corridor toward primary clash */
|
||||||
|
{
|
||||||
|
int hx_t = sx, hy_t = sy;
|
||||||
|
for (int dy = -2; dy <= 8; dy++) {
|
||||||
|
for (int dx = -2; dx <= 10; dx++) {
|
||||||
|
int tx = hx_t + dx, ty = hy_t + dy;
|
||||||
|
if (!map_in_bounds(&g->map, tx, ty)) continue;
|
||||||
|
Tile *t = map_tile(&g->map, tx, ty);
|
||||||
|
if (!t || t->occupied || !t->walkable) continue;
|
||||||
|
if (t->terrain == T_ROAD) continue;
|
||||||
|
int h = (dx * 11 + dy * 9) & 7;
|
||||||
|
if (h == 0 || h == 3) {
|
||||||
|
t->terrain = T_SCRAP;
|
||||||
|
t->scrap = (uint8_t)(110 + ((dx * 17 + dy * 13) & 127));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* secondary clash front SE of HQ (second fight plate in crop) */
|
||||||
|
float rx2 = wx + 40.0f, ry2 = wy + 70.0f;
|
||||||
|
{
|
||||||
|
int ctx2, cty2;
|
||||||
|
map_world_to_tile(rx2, ry2, &ctx2, &cty2);
|
||||||
|
for (int dy = -5; dy <= 5; dy++) {
|
||||||
|
for (int dx = -6; dx <= 6; dx++) {
|
||||||
|
int tx = ctx2 + dx, ty = cty2 + dy;
|
||||||
|
if (!map_in_bounds(&g->map, tx, ty)) continue;
|
||||||
|
Tile *t = map_tile(&g->map, tx, ty);
|
||||||
|
if (!t || !t->walkable) continue;
|
||||||
|
int d2 = dx * dx + dy * dy;
|
||||||
|
if (d2 <= 2) {
|
||||||
|
t->terrain = T_ROAD;
|
||||||
|
t->scrap = 0;
|
||||||
|
} else if (d2 <= 10) {
|
||||||
|
t->terrain = T_RUBBLE;
|
||||||
|
t->scrap = 0;
|
||||||
|
} else if (d2 <= 24 && ((dx + dy * 2) & 3) == 0) {
|
||||||
|
t->terrain = T_SCRAP;
|
||||||
|
t->scrap = (uint8_t)(100 + ((dx * 19 + dy * 11) & 127));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* short approach from HQ south gate toward secondary */
|
||||||
|
{
|
||||||
|
int steps = abs(ctx2 - sx) + abs(cty2 - sy);
|
||||||
|
if (steps < 1) steps = 1;
|
||||||
|
for (int s = 0; s <= steps; s++) {
|
||||||
|
int tx = sx + (ctx2 - sx) * s / steps;
|
||||||
|
int ty = sy + (cty2 - sy) * s / steps;
|
||||||
|
if (!map_in_bounds(&g->map, tx, ty)) continue;
|
||||||
|
Tile *t = map_tile(&g->map, tx, ty);
|
||||||
|
if (!t || !t->walkable) continue;
|
||||||
|
if (t->occupied) continue;
|
||||||
|
t->terrain = T_ROAD;
|
||||||
|
t->scrap = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bld_spawn(g, BT_TURRET, human, ctx2 - 2, cty2);
|
||||||
|
bld_spawn(g, BT_TURRET, human, ctx2 + 1, cty2 + 1);
|
||||||
|
bld_spawn(g, BT_WALL, human, ctx2 - 3, cty2);
|
||||||
|
bld_spawn(g, BT_WALL, human, ctx2 - 3, cty2 + 1);
|
||||||
|
bld_force_complete(g);
|
||||||
|
}
|
||||||
|
/* Survivor SE defenders */
|
||||||
|
unit_spawn(g, UT_TANK, human, rx2 - 18, ry2 - 8);
|
||||||
|
unit_spawn(g, UT_TANK, human, rx2 - 6, ry2 + 10);
|
||||||
|
unit_spawn(g, UT_JEEP, human, rx2 - 28, ry2 + 4);
|
||||||
|
unit_spawn(g, UT_FLAME, human, rx2 - 22, ry2 + 18);
|
||||||
|
unit_spawn(g, UT_BUGGY, human, rx2 - 34, ry2 - 12);
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
unit_spawn(g, UT_INFANTRY, human,
|
||||||
|
rx2 - 12 + (i % 3) * 12, ry2 - 16 + (i / 3) * 14);
|
||||||
|
|
||||||
int raid[56];
|
int raid[56];
|
||||||
int rn = 0;
|
int rn = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
|
|
@ -389,6 +463,24 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
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);
|
||||||
|
|
||||||
|
/* secondary Evolved pack at SE clash (room left in raid[56]) */
|
||||||
|
int rn_pri = rn;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_MUTANT, enemy,
|
||||||
|
rx2 + 10 + (i % 2) * 16, ry2 + 8 + (i / 2) * 14);
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_BEAST, enemy, rx2 + 28 + i * 14, ry2 + 4 + i * 10);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_BUGGY, enemy, rx2 + 18, ry2 - 10);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_BUGGY, enemy, rx2 + 34, ry2 + 16);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_JEEP, enemy, rx2 + 42, ry2 + 2);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_TANK, enemy, rx2 + 50, ry2 + 12);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_TANK, enemy, rx2 + 58, ry2 - 6);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_RAVAGER, enemy, rx2 + 46, ry2 + 22);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_FLAME, enemy, rx2 + 22, ry2 + 26);
|
||||||
|
raid[rn++] = unit_spawn(g, UT_MISSILE, enemy, rx2 + 64, ry2 + 8);
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
raid[rn++] = unit_spawn(g, UT_INFANTRY, enemy,
|
||||||
|
rx2 + 6 + i * 12, ry2 + 20 + i * 6);
|
||||||
|
|
||||||
/* seed Survivor harvester beds so cargo silhouette is visible in shot */
|
/* seed Survivor harvester beds so cargo silhouette is visible in shot */
|
||||||
{
|
{
|
||||||
|
|
@ -404,66 +496,104 @@ static void place_showcase(Game *g, Faction human, Faction enemy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pre-damage for HP-bar variety (sim may add more) */
|
/* pre-damage for HP-bar variety at both clash loci */
|
||||||
for (int i = 0; i < g->unit_count; i++) {
|
for (int i = 0; i < g->unit_count; i++) {
|
||||||
Unit *u = &g->units[i];
|
Unit *u = &g->units[i];
|
||||||
if (u->dead || u->max_hp <= 0) continue;
|
if (u->dead || u->max_hp <= 0) continue;
|
||||||
float dx = u->x - rx, dy = u->y - ry;
|
float dx = u->x - rx, dy = u->y - ry;
|
||||||
if (dx * dx + dy * dy > 140.0f * 140.0f) continue;
|
float dx2 = u->x - rx2, dy2 = u->y - ry2;
|
||||||
|
int near = (dx * dx + dy * dy <= 140.0f * 140.0f)
|
||||||
|
|| (dx2 * dx2 + dy2 * dy2 <= 110.0f * 110.0f);
|
||||||
|
if (!near) continue;
|
||||||
float f = 0.35f + 0.45f * ((i * 17) % 100) / 100.0f;
|
float f = 0.35f + 0.45f * ((i * 17) % 100) / 100.0f;
|
||||||
u->hp = u->max_hp * f;
|
u->hp = u->max_hp * f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FX seeds at the clash locus */
|
/* FX seeds at primary + secondary clash loci */
|
||||||
particle_burst(g, rx, ry, 28, 1, 255, 140, 40);
|
particle_burst(g, rx, ry, 28, 1, 255, 140, 40);
|
||||||
particle_burst(g, rx + 20, ry - 10, 18, 0, 90, 90, 90);
|
particle_burst(g, rx + 20, ry - 10, 18, 0, 90, 90, 90);
|
||||||
particle_burst(g, rx - 15, ry + 12, 22, 2, 255, 220, 80);
|
particle_burst(g, rx - 15, ry + 12, 22, 2, 255, 220, 80);
|
||||||
particle_burst(g, rx + 40, ry + 5, 14, 1, 255, 100, 30);
|
particle_burst(g, rx + 40, ry + 5, 14, 1, 255, 100, 30);
|
||||||
particle_burst(g, rx + 10, ry - 25, 16, 3, 80, 70, 60);
|
particle_burst(g, rx + 10, ry - 25, 16, 3, 80, 70, 60);
|
||||||
|
particle_burst(g, rx2, ry2, 24, 1, 255, 130, 35);
|
||||||
|
particle_burst(g, rx2 + 16, ry2 - 8, 16, 0, 100, 95, 85);
|
||||||
|
particle_burst(g, rx2 - 12, ry2 + 10, 18, 2, 255, 210, 70);
|
||||||
|
particle_burst(g, rx2 + 28, ry2 + 6, 12, 1, 255, 90, 25);
|
||||||
|
particle_burst(g, rx2 + 8, ry2 + 20, 14, 3, 85, 75, 55);
|
||||||
|
|
||||||
/* point raid at nearest human combat units / HQ */
|
/* point primary raid at nearest human combat / HQ; secondary at SE prey */
|
||||||
int hq = -1;
|
int hq = -1;
|
||||||
for (int i = 0; i < g->bld_count; i++)
|
for (int i = 0; i < g->bld_count; i++)
|
||||||
if (!g->buildings[i].dead && g->buildings[i].faction == human
|
if (!g->buildings[i].dead && g->buildings[i].faction == human
|
||||||
&& g->buildings[i].type == BT_BASE) { hq = i; break; }
|
&& g->buildings[i].type == BT_BASE) { hq = i; break; }
|
||||||
int prey = -1;
|
int prey = -1, prey2 = -1;
|
||||||
|
float prey_d2 = 1e12f, prey2_d2 = 1e12f;
|
||||||
for (int i = 0; i < g->unit_count; i++) {
|
for (int i = 0; i < g->unit_count; i++) {
|
||||||
Unit *u = &g->units[i];
|
Unit *u = &g->units[i];
|
||||||
if (u->dead || u->faction != human) continue;
|
if (u->dead || u->faction != human) continue;
|
||||||
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
||||||
prey = i; break;
|
float d1 = (u->x - rx) * (u->x - rx) + (u->y - ry) * (u->y - ry);
|
||||||
|
float d2 = (u->x - rx2) * (u->x - rx2) + (u->y - ry2) * (u->y - ry2);
|
||||||
|
if (d1 < prey_d2) { prey_d2 = d1; prey = i; }
|
||||||
|
if (d2 < prey2_d2) { prey2_d2 = d2; prey2 = i; }
|
||||||
|
}
|
||||||
|
int tur2 = -1;
|
||||||
|
for (int i = 0; i < g->bld_count; i++) {
|
||||||
|
Building *b = &g->buildings[i];
|
||||||
|
if (b->dead || b->faction != human || b->type != BT_TURRET) continue;
|
||||||
|
float bx = (float)(b->tx * TILE + b->w * TILE / 2);
|
||||||
|
float by = (float)(b->ty * TILE + b->h * TILE / 2);
|
||||||
|
float d2 = (bx - rx2) * (bx - rx2) + (by - ry2) * (by - ry2);
|
||||||
|
if (d2 < 90.0f * 90.0f) { tur2 = i; break; }
|
||||||
}
|
}
|
||||||
for (int i = 0; i < rn; i++) {
|
for (int i = 0; i < rn; i++) {
|
||||||
if (raid[i] < 0) continue;
|
if (raid[i] < 0) continue;
|
||||||
if (prey >= 0) unit_issue_attack_unit(g, raid[i], prey);
|
if (i < rn_pri) {
|
||||||
else if (hq >= 0) unit_issue_attack_bld(g, raid[i], hq);
|
if (prey >= 0) unit_issue_attack_unit(g, raid[i], prey);
|
||||||
|
else if (hq >= 0) unit_issue_attack_bld(g, raid[i], hq);
|
||||||
|
} else {
|
||||||
|
if (prey2 >= 0) unit_issue_attack_unit(g, raid[i], prey2);
|
||||||
|
else if (tur2 >= 0) unit_issue_attack_bld(g, raid[i], tur2);
|
||||||
|
else if (hq >= 0) unit_issue_attack_bld(g, raid[i], hq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* human combat units engage nearest raiders (spread targets) */
|
/* human combat units engage nearest raiders (both fronts) */
|
||||||
int ridx = 0;
|
int ridx = 0;
|
||||||
for (int i = 0; i < g->unit_count; i++) {
|
for (int i = 0; i < g->unit_count; i++) {
|
||||||
Unit *u = &g->units[i];
|
Unit *u = &g->units[i];
|
||||||
if (u->dead || u->faction != human) continue;
|
if (u->dead || u->faction != human) continue;
|
||||||
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
||||||
float dx = u->x - rx, dy = u->y - ry;
|
float dx = u->x - rx, dy = u->y - ry;
|
||||||
if (dx * dx + dy * dy > 220.0f * 220.0f) continue;
|
float dx2 = u->x - rx2, dy2 = u->y - ry2;
|
||||||
|
int near = (dx * dx + dy * dy <= 220.0f * 220.0f)
|
||||||
|
|| (dx2 * dx2 + dy2 * dy2 <= 160.0f * 160.0f);
|
||||||
|
if (!near) continue;
|
||||||
|
int prefer_sec = (dx2 * dx2 + dy2 * dy2) < (dx * dx + dy * dy);
|
||||||
|
int lo = prefer_sec ? rn_pri : 0;
|
||||||
|
int hi = prefer_sec ? rn : rn_pri;
|
||||||
|
if (hi <= lo) { lo = 0; hi = rn; }
|
||||||
int tgt = -1;
|
int tgt = -1;
|
||||||
for (int k = 0; k < rn; k++) {
|
int span = hi - lo;
|
||||||
int ri = raid[(ridx + k) % rn];
|
for (int k = 0; k < span; k++) {
|
||||||
|
int ri = raid[lo + (ridx + k) % span];
|
||||||
if (ri >= 0 && !g->units[ri].dead) { tgt = ri; ridx += k + 1; break; }
|
if (ri >= 0 && !g->units[ri].dead) { tgt = ri; ridx += k + 1; break; }
|
||||||
}
|
}
|
||||||
if (tgt >= 0) unit_issue_attack_unit(g, i, tgt);
|
if (tgt >= 0) unit_issue_attack_unit(g, i, tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select a front-line squad for yellow selection boxes in the shot */
|
/* select front-line squads on both clashes for yellow selection boxes */
|
||||||
unit_clear_selection(g);
|
unit_clear_selection(g);
|
||||||
int nsel = 0;
|
int nsel = 0;
|
||||||
for (int i = 0; i < g->unit_count && nsel < 8; i++) {
|
for (int i = 0; i < g->unit_count && nsel < 10; i++) {
|
||||||
Unit *u = &g->units[i];
|
Unit *u = &g->units[i];
|
||||||
if (u->dead || u->faction != human) continue;
|
if (u->dead || u->faction != human) continue;
|
||||||
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
if (u->type == UT_HARVESTER || u->type == UT_MEDIC) continue;
|
||||||
float dx = u->x - rx, dy = u->y - ry;
|
float dx = u->x - rx, dy = u->y - ry;
|
||||||
if (dx * dx + dy * dy > 120.0f * 120.0f) continue;
|
float dx2 = u->x - rx2, dy2 = u->y - ry2;
|
||||||
|
int near = (dx * dx + dy * dy <= 120.0f * 120.0f)
|
||||||
|
|| (dx2 * dx2 + dy2 * dy2 <= 90.0f * 90.0f);
|
||||||
|
if (!near) continue;
|
||||||
unit_select_single(g, i, 1);
|
unit_select_single(g, i, 1);
|
||||||
nsel++;
|
nsel++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,76 @@ int main(int argc, char **argv) {
|
||||||
spawned++;
|
spawned++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* secondary SE clash: lingering columns + tracers */
|
||||||
|
float clash2_x = hx + 40.0f, clash2_y = hy + 70.0f;
|
||||||
|
float c2x = clash2_x, c2y = clash2_y;
|
||||||
|
int n2 = 0;
|
||||||
|
float sx2 = 0, sy2 = 0;
|
||||||
|
for (int i = 0; i < g->unit_count; i++) {
|
||||||
|
Unit *u = &g->units[i];
|
||||||
|
if (u->dead || u->faction == g->human) continue;
|
||||||
|
float dx = u->x - clash2_x, dy = u->y - clash2_y;
|
||||||
|
if (dx * dx + dy * dy > 140.0f * 140.0f) continue;
|
||||||
|
sx2 += u->x; sy2 += u->y; n2++;
|
||||||
|
}
|
||||||
|
if (n2 > 0) { c2x = sx2 / n2; c2y = sy2 / n2; }
|
||||||
|
particle_burst(g, c2x, c2y, 40, 1, 255, 135, 35);
|
||||||
|
particle_burst(g, c2x + 18, c2y - 10, 28, 0, 115, 105, 90);
|
||||||
|
particle_burst(g, c2x - 14, c2y + 12, 30, 2, 255, 220, 85);
|
||||||
|
particle_burst(g, c2x + 26, c2y + 8, 22, 1, 255, 95, 28);
|
||||||
|
particle_burst(g, c2x - 6, c2y - 20, 24, 3, 90, 78, 62);
|
||||||
|
particle_burst(g, c2x + 10, c2y + 24, 20, 1, 255, 160, 50);
|
||||||
|
{
|
||||||
|
int spawned2 = 0;
|
||||||
|
const float pair_r2 = 150.0f * 150.0f;
|
||||||
|
const float r2b = 140.0f * 140.0f;
|
||||||
|
for (int i = 0; i < g->unit_count && spawned2 < 36; 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 < 36 && shots < 2; 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 = (spawned2 % 4 == 0) ? 3
|
||||||
|
: (spawned2 % 4 == 1) ? 1
|
||||||
|
: (spawned2 % 4 == 2) ? 2 : 0;
|
||||||
|
float t = 0.20f + 0.55f * ((spawned2 * 41) % 100) / 100.0f;
|
||||||
|
bullet_spawn(g, a->x + dx * t, a->y + dy * t,
|
||||||
|
b->id, -1, 1.0f, a->faction, kind);
|
||||||
|
spawned2++;
|
||||||
|
shots++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < g->bld_count && spawned2 < 44; i++) {
|
||||||
|
Building *bl = &g->buildings[i];
|
||||||
|
if (bl->dead || (bl->type != BT_TURRET && bl->type != BT_BASE))
|
||||||
|
continue;
|
||||||
|
float bx = (float)(bl->tx * TILE + bl->w * TILE / 2);
|
||||||
|
float by = (float)(bl->ty * TILE + bl->h * TILE / 2);
|
||||||
|
float bdx = bx - clash2_x, bdy = by - clash2_y;
|
||||||
|
if (bdx * bdx + bdy * bdy > r2b) continue;
|
||||||
|
int best = -1; float bestd = 1e12f;
|
||||||
|
for (int j = 0; j < g->unit_count; j++) {
|
||||||
|
Unit *u = &g->units[j];
|
||||||
|
if (u->dead || u->faction == bl->faction) continue;
|
||||||
|
float dx = u->x - bx, dy = u->y - by;
|
||||||
|
float d2 = dx * dx + dy * dy;
|
||||||
|
if (d2 < bestd && d2 < pair_r2) { bestd = d2; best = j; }
|
||||||
|
}
|
||||||
|
if (best < 0) continue;
|
||||||
|
Unit *tgt = &g->units[best];
|
||||||
|
float dx = tgt->x - bx, dy = tgt->y - by;
|
||||||
|
float t = 0.28f + 0.42f * ((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);
|
||||||
|
spawned2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
char path[64]; snprintf(path, sizeof path, "shot_%04d.png", 1);
|
char path[64]; snprintf(path, sizeof path, "shot_%04d.png", 1);
|
||||||
snapshot_capture(g, path);
|
snapshot_capture(g, path);
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,10 @@ void particle_spawn(Game *g, float x, float y, int kind, uint8_t cr, uint8_t cg,
|
||||||
float sp = rng_frange(&g_prng, 10, 60);
|
float sp = rng_frange(&g_prng, 10, 60);
|
||||||
p->vx = (float)cosf(ang) * sp;
|
p->vx = (float)cosf(ang) * sp;
|
||||||
p->vy = (float)sinf(ang) * sp;
|
p->vy = (float)sinf(ang) * sp;
|
||||||
p->life = p->max_life = (kind == 0) ? 1.2f : 0.5f;
|
/* lingering columns: smoke / fire / spark|debris (KKND2 clash plate) */
|
||||||
|
if (kind == 0) p->life = p->max_life = 2.8f;
|
||||||
|
else if (kind == 1) p->life = p->max_life = 1.8f;
|
||||||
|
else p->life = p->max_life = 1.0f;
|
||||||
p->r = cr; p->g = cg; p->b = cb;
|
p->r = cr; p->g = cg; p->b = cb;
|
||||||
p->kind = kind;
|
p->kind = kind;
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +108,7 @@ void particle_update(Game *g, float dt) {
|
||||||
p->y += p->vy * dt;
|
p->y += p->vy * dt;
|
||||||
p->vx *= 0.92f; p->vy *= 0.92f;
|
p->vx *= 0.92f; p->vy *= 0.92f;
|
||||||
if (p->kind == 1) p->vy += 40 * dt; /* fire rises/slows */
|
if (p->kind == 1) p->vy += 40 * dt; /* fire rises/slows */
|
||||||
|
if (p->kind == 0) p->vy -= 18 * dt; /* smoke drifts up */
|
||||||
if (p->life <= 0) {
|
if (p->life <= 0) {
|
||||||
g->particles[i] = g->particles[g->particle_count - 1];
|
g->particles[i] = g->particles[g->particle_count - 1];
|
||||||
g->particle_count--;
|
g->particle_count--;
|
||||||
|
|
|
||||||
|
|
@ -638,9 +638,19 @@ void snapshot_capture(Game *g, const char *path) {
|
||||||
line(sx + TILE/2, sy + 2, sx + TILE/2, sy + TILE - 3, 165, 140, 95);
|
line(sx + TILE/2, sy + 2, sx + TILE/2, sy + TILE - 3, 165, 140, 95);
|
||||||
}
|
}
|
||||||
if (t->terrain == T_SCRAP && t->scrap > 0) {
|
if (t->terrain == T_SCRAP && t->scrap > 0) {
|
||||||
int cc = (sx+TILE/2), cr = (sy+TILE/2);
|
/* stacked scrap mounds (KKND2 resource piles) */
|
||||||
for (int k=0;k<t->scrap/16;k++)
|
int cc = sx + TILE / 2, cr = sy + TILE / 2 + 2;
|
||||||
disc(cc + ((k*7)%12)-6, cr + ((k*5)%12)-6, 3, 235,190,85);
|
int n = 3 + t->scrap / 28;
|
||||||
|
if (n > 9) n = 9;
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
int ox = ((k * 7) % 14) - 7;
|
||||||
|
int oy = ((k * 5) % 10) - 5 - (k / 3) * 2;
|
||||||
|
int rad = 4 + (k & 1) + (t->scrap > 120 ? 1 : 0);
|
||||||
|
disc(cc + ox, cr + oy, rad, 235, 190, 85);
|
||||||
|
disc(cc + ox - 1, cr + oy - rad / 2, rad - 1, 210, 165, 70);
|
||||||
|
disc(cc + ox + 1, cr + oy - rad + 1, (rad > 3) ? rad - 2 : 2,
|
||||||
|
255, 215, 120);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -415,9 +415,16 @@ SDL_Texture *sprites_make_terrain(SDL_Renderer *r, TerrainType t) {
|
||||||
(Uint8)kknd_clampi(tb+v,0,255), 255);
|
(Uint8)kknd_clampi(tb+v,0,255), 255);
|
||||||
}
|
}
|
||||||
if (t == T_SCRAP) {
|
if (t == T_SCRAP) {
|
||||||
for (int i = 0; i < 10; i++) {
|
/* stacked scrap mounds (live parity with snapshot) */
|
||||||
int x = (i*97) % TILE, y = (i*61) % TILE;
|
int cc = TILE / 2, cr = TILE / 2 + 2;
|
||||||
disc(s, x, y, 2, 180, 150, 60, 255);
|
for (int k = 0; k < 7; k++) {
|
||||||
|
int ox = ((k * 7) % 14) - 7;
|
||||||
|
int oy = ((k * 5) % 10) - 5 - (k / 3) * 2;
|
||||||
|
int rad = 3 + (k & 1);
|
||||||
|
disc(s, cc + ox, cr + oy, rad, 235, 190, 85, 255);
|
||||||
|
disc(s, cc + ox - 1, cr + oy - rad / 2, rad - 1, 210, 165, 70, 255);
|
||||||
|
disc(s, cc + ox + 1, cr + oy - rad + 1,
|
||||||
|
(rad > 2) ? rad - 2 : 1, 255, 215, 120, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t == T_WATER) {
|
if (t == T_WATER) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue