Add hit markers and metal explosion for turrets
Turrets now emit orange-white spark particles when taking non-lethal damage, giving clear visual feedback on hits. On death, turrets get a dedicated metal explosion effect (shrapnel, hot sparks, flash, smoke) instead of the generic death puff, with stronger screen shake. Closes #14
This commit was merged in pull request #25.
This commit is contained in:
@@ -530,6 +530,124 @@ void particle_emit_wall_slide_dust(Vec2 pos, int wall_dir) {
|
||||
particle_emit(&dust);
|
||||
}
|
||||
|
||||
void particle_emit_hit_sparks(Vec2 pos) {
|
||||
/* Bright orange-white sparks — fast, short-lived, spray outward */
|
||||
ParticleBurst sparks = {
|
||||
.origin = pos,
|
||||
.count = 8,
|
||||
.speed_min = 60.0f,
|
||||
.speed_max = 180.0f,
|
||||
.life_min = 0.08f,
|
||||
.life_max = 0.2f,
|
||||
.size_min = 1.0f,
|
||||
.size_max = 2.0f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 3.0f,
|
||||
.gravity_scale = 0.4f,
|
||||
.color = {255, 200, 100, 255}, /* orange-white */
|
||||
.color_vary = true,
|
||||
};
|
||||
particle_emit(&sparks);
|
||||
|
||||
/* Brief white flash at impact point */
|
||||
ParticleBurst flash = {
|
||||
.origin = pos,
|
||||
.count = 3,
|
||||
.speed_min = 5.0f,
|
||||
.speed_max = 15.0f,
|
||||
.life_min = 0.03f,
|
||||
.life_max = 0.06f,
|
||||
.size_min = 2.0f,
|
||||
.size_max = 3.5f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 8.0f,
|
||||
.gravity_scale = 0.0f,
|
||||
.color = {255, 255, 230, 255}, /* bright white */
|
||||
.color_vary = false,
|
||||
};
|
||||
particle_emit(&flash);
|
||||
}
|
||||
|
||||
void particle_emit_metal_explosion(Vec2 pos) {
|
||||
/* Metal shrapnel — fast grey/silver chunks flying outward */
|
||||
ParticleBurst shrapnel = {
|
||||
.origin = pos,
|
||||
.count = 16,
|
||||
.speed_min = 60.0f,
|
||||
.speed_max = 200.0f,
|
||||
.life_min = 0.2f,
|
||||
.life_max = 0.6f,
|
||||
.size_min = 1.5f,
|
||||
.size_max = 3.5f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 2.0f,
|
||||
.gravity_scale = 0.5f,
|
||||
.color = {180, 180, 190, 255}, /* silver-grey */
|
||||
.color_vary = true,
|
||||
};
|
||||
particle_emit(&shrapnel);
|
||||
|
||||
/* Hot orange sparks — electrical/mechanical innards */
|
||||
ParticleBurst sparks = {
|
||||
.origin = pos,
|
||||
.count = 10,
|
||||
.speed_min = 40.0f,
|
||||
.speed_max = 150.0f,
|
||||
.life_min = 0.15f,
|
||||
.life_max = 0.35f,
|
||||
.size_min = 1.0f,
|
||||
.size_max = 2.5f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 2.5f,
|
||||
.gravity_scale = 0.3f,
|
||||
.color = {255, 160, 40, 255}, /* hot orange */
|
||||
.color_vary = true,
|
||||
};
|
||||
particle_emit(&sparks);
|
||||
|
||||
/* Bright white flash at center — brief pop */
|
||||
ParticleBurst flash = {
|
||||
.origin = pos,
|
||||
.count = 5,
|
||||
.speed_min = 5.0f,
|
||||
.speed_max = 20.0f,
|
||||
.life_min = 0.04f,
|
||||
.life_max = 0.08f,
|
||||
.size_min = 3.0f,
|
||||
.size_max = 5.0f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 8.0f,
|
||||
.gravity_scale = 0.0f,
|
||||
.color = {255, 240, 200, 255}, /* bright flash */
|
||||
.color_vary = false,
|
||||
};
|
||||
particle_emit(&flash);
|
||||
|
||||
/* Smoke cloud — slower, lingers */
|
||||
ParticleBurst smoke = {
|
||||
.origin = pos,
|
||||
.count = 8,
|
||||
.speed_min = 15.0f,
|
||||
.speed_max = 50.0f,
|
||||
.life_min = 0.3f,
|
||||
.life_max = 0.7f,
|
||||
.size_min = 2.5f,
|
||||
.size_max = 4.5f,
|
||||
.spread = (float)M_PI,
|
||||
.direction = 0,
|
||||
.drag = 3.5f,
|
||||
.gravity_scale = -0.1f, /* floats up */
|
||||
.color = {120, 120, 130, 180}, /* dark smoke */
|
||||
.color_vary = true,
|
||||
};
|
||||
particle_emit(&smoke);
|
||||
}
|
||||
|
||||
/* Spawn a single dust mote with the given visual properties. */
|
||||
static void spawn_dust_mote(Vec2 pos, Vec2 vel,
|
||||
float life_min, float life_max,
|
||||
|
||||
@@ -89,6 +89,12 @@ void particle_emit_muzzle_flash(Vec2 pos, Vec2 shoot_dir);
|
||||
/* Wall slide dust (small puffs while scraping against a wall) */
|
||||
void particle_emit_wall_slide_dust(Vec2 pos, int wall_dir);
|
||||
|
||||
/* Metal hit sparks (turret/machine takes non-lethal damage) */
|
||||
void particle_emit_hit_sparks(Vec2 pos);
|
||||
|
||||
/* Metal explosion (turret/machine death — shrapnel + flash) */
|
||||
void particle_emit_metal_explosion(Vec2 pos);
|
||||
|
||||
/* Ambient atmosphere dust (call each frame for Mars Surface levels).
|
||||
* Spawns subtle dust motes around the camera viewport that drift with wind.
|
||||
* cam_pos = camera top-left world position, vp = viewport size in pixels. */
|
||||
|
||||
Reference in New Issue
Block a user