tune(enemy): big_pentagon orb circular, firework petit per hit, sense wounded chain

This commit is contained in:
2026-05-25 22:28:36 +02:00
parent f64c72f9a6
commit 14b10c663e
9 changed files with 99 additions and 77 deletions
+10
View File
@@ -33,3 +33,13 @@ namespace Defaults::Enemies::Debris {
constexpr float PARTIAL_PIECE_SCALE = 0.3F;
} // namespace Defaults::Enemies::Debris
namespace Defaults::Enemies::Fireworks {
// Paràmetres del firework "petit" per a l'acció CREATE_FIREWORKS_SMALL
// (feedback per impacte parcial en enemics HP>1). Pocs punts i baixa
// velocitat: una espurna breu, no una explosió.
constexpr int SMALL_N_POINTS = 20;
constexpr float SMALL_SPEED = 250.0F;
} // namespace Defaults::Enemies::Fireworks
+1
View File
@@ -193,6 +193,7 @@ namespace {
if (s == "create_debris") { return EnemyActionType::CREATE_DEBRIS; }
if (s == "create_debris_partial") { return EnemyActionType::CREATE_DEBRIS_PARTIAL; }
if (s == "create_fireworks") { return EnemyActionType::CREATE_FIREWORKS; }
if (s == "create_fireworks_small") { return EnemyActionType::CREATE_FIREWORKS_SMALL; }
if (s == "apply_impulse") { return EnemyActionType::APPLY_IMPULSE; }
if (s == "decrease_health") { return EnemyActionType::DECREASE_HEALTH; }
if (s == "flash") { return EnemyActionType::FLASH; }
+10 -9
View File
@@ -18,15 +18,16 @@ enum class EnemyEventType : uint8_t {
};
enum class EnemyActionType : uint8_t {
SET_HURT, // Entra estat wounded (o destrueix si ja era wounded)
DESTROY, // Dispara on_destroy + desactiva físicament
ADD_SCORE, // Suma config.score al shooter + floating score
CREATE_DEBRIS, // Explosió de debris amb herència de velocitat
CREATE_DEBRIS_PARTIAL, // Debris de xip parcial (trossos a escala 0.3, per hits HP>1)
CREATE_FIREWORKS, // Burst radial de firework
APPLY_IMPULSE, // Aplica l'impuls de la bala impactant
DECREASE_HEALTH, // Decrementa health_; si <=0, dispatcha ON_NO_HEALTH
FLASH, // Flash visual breu (feedback per impacte parcial)
SET_HURT, // Entra estat wounded (o destrueix si ja era wounded)
DESTROY, // Dispara on_destroy + desactiva físicament
ADD_SCORE, // Suma config.score al shooter + floating score
CREATE_DEBRIS, // Explosió de debris amb herència de velocitat
CREATE_DEBRIS_PARTIAL, // Debris de xip parcial (trossos a escala 0.3, per hits HP>1)
CREATE_FIREWORKS, // Burst radial de firework
CREATE_FIREWORKS_SMALL, // Burst petit (pocs punts, poca velocitat) — feedback per hit
APPLY_IMPULSE, // Aplica l'impuls de la bala impactant
DECREASE_HEALTH, // Decrementa health_; si <=0, dispatcha ON_NO_HEALTH
FLASH, // Flash visual breu (feedback per impacte parcial)
};
struct EnemyAction {
+3 -31
View File
@@ -83,36 +83,6 @@ namespace Systems::Collision {
}
}
void detectWoundedChain(Context& ctx) {
const std::size_t N = ctx.enemies.size();
for (std::size_t i = 0; i < N; i++) {
Enemy& a = ctx.enemies[i];
if (!a.isCollidable()) {
continue;
}
for (std::size_t j = i + 1; j < N; j++) {
Enemy& b = ctx.enemies[j];
if (!b.isCollidable()) {
continue;
}
const bool A_WOUNDED = a.isWounded();
const bool B_WOUNDED = b.isWounded();
if (A_WOUNDED == B_WOUNDED) {
continue; // ambos sanos o ambos heridos: nada que propagar
}
if (!Physics::checkCollision(a, b, Defaults::Game::COLLISION_WOUNDED_CHAIN_AMPLIFIER)) {
continue;
}
// El sano queda herido, propagando el shooter original.
if (A_WOUNDED) {
b.hurt(a.getLastHitBy());
} else {
a.hurt(b.getLastHitBy());
}
}
}
}
void detectShipEnemy(Context& ctx) {
constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
@@ -263,7 +233,9 @@ namespace Systems::Collision {
void detectAll(Context& ctx) {
processWoundedDeaths(ctx); // expiran ANTES de ser tocadas por bala este frame
detectBulletEnemy(ctx);
detectWoundedChain(ctx); // un herit pot ferir a un sa al fregar-lo
// Wounded chain desactivat: era massa fàcil que un enemic ferit topés
// amb el big_pentagon (10 HP) i el matés instantàniament. La regla
// "ferit-toca-sa → ferit" queda permanentment fora.
detectShipEnemy(ctx);
detectBulletPlayer(ctx);
detectEnemyBulletShip(ctx);
-6
View File
@@ -56,12 +56,6 @@ namespace Systems::Collision {
// al `last_hit_by_` del enemy (si está set).
void processWoundedDeaths(Context& ctx);
// Si un enemy herido colisiona con uno sano (ni herido ni invulnerable),
// el sano también queda herido (efecto cadena). Propaga `last_hit_by_` para
// que el shooter original siga acreditándose la muerte en cascada. El rebote
// físico ya lo resuelve PhysicsWorld; aquí solo propagamos el estado.
void detectWoundedChain(Context& ctx);
// Detecta colisiones ship → enemy. Si hit, llama on_player_hit(player_id).
void detectShipEnemy(Context& ctx);
+15 -5
View File
@@ -51,14 +51,17 @@ namespace Systems::EnemyEvents {
piece_scale);
}
void doCreateFireworks(Systems::Collision::Context& ctx, const Enemy& enemy) {
// Helper compartit per CREATE_FIREWORKS i CREATE_FIREWORKS_SMALL:
// mateixa crida a spawn(), només canvien n_points, initial_speed i
// glow_color segons el "tamany" del burst (mort vs feedback per hit).
void spawnFireworksForEnemy(Systems::Collision::Context& ctx, const Enemy& enemy, int n_points, float initial_speed, SDL_Color glow_color) {
ctx.firework_manager.spawn(enemy.getCenter(),
Defaults::FX::Firework::DEFAULT_COLOR,
Defaults::FX::Firework::SPEED,
Defaults::FX::Firework::N_POINTS,
initial_speed,
n_points,
Defaults::FX::Firework::INITIAL_BRIGHTNESS,
/*glow=*/true,
enemy.getConfig().colors.wounded);
glow_color);
}
void doApplyImpulse(Enemy& enemy, const Bullet* bullet) {
@@ -123,7 +126,14 @@ namespace Systems::EnemyEvents {
spawnDebrisForEnemy(ctx, enemy, bullet, Defaults::Enemies::Debris::PARTIAL_PIECE_SCALE);
break;
case EnemyActionType::CREATE_FIREWORKS:
doCreateFireworks(ctx, enemy);
// Burst de mort: glow amb el color wounded (daurat) per
// marcar la mort com a esdeveniment "calent".
spawnFireworksForEnemy(ctx, enemy, Defaults::FX::Firework::N_POINTS, Defaults::FX::Firework::SPEED, enemy.getConfig().colors.wounded);
break;
case EnemyActionType::CREATE_FIREWORKS_SMALL:
// Burst d'impacte: glow amb el color de l'enemic, perquè
// l'espurna llegisca com a "tros del propi cos saltant".
spawnFireworksForEnemy(ctx, enemy, Defaults::Enemies::Fireworks::SMALL_N_POINTS, Defaults::Enemies::Fireworks::SMALL_SPEED, enemy.getConfig().colors.normal);
break;
case EnemyActionType::APPLY_IMPULSE:
if (!will_die) {