// enemy_event.hpp - Sistema declaratiu d'events i accions per a enemics // © 2026 JailDesigner // // Cada enemic descriu al seu YAML què passa quan rep un event (on_hit, // on_hurt_end, on_destroy) com a llista d'accions. El motor només dispatcha; // el comportament viu a les dades. #pragma once #include #include #include #include "game/entities/enemy_ai.hpp" // AimMode enum class EnemyEventType : uint8_t { ON_HIT, // Impactat per una bala ON_NO_HEALTH, // health ha arribat a 0 o menys aquest frame (via DECREASE_HEALTH) ON_HURT_END, // Timer wounded ha expirat aquest frame ON_DESTROY, // L'acció destroy s'està executant (efectes col·laterals) }; 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 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) FIRE_BULLET, // Dispara una bala (config per nom) dirigida o aleatòria }; struct EnemyAction { EnemyActionType type; // Payload de FIRE_BULLET (ignorat per altres tipus). Paral·lel a AiTickAction // perquè un futur refactor pugui compartir doShoot/doFireBullet si val la pena. std::string bullet_config_name; float bullet_speed{200.0F}; AimMode aim_mode{AimMode::RANDOM}; float jitter_rad{0.0F}; }; struct EnemyEventConfig { std::vector on_hit; std::vector on_no_health; std::vector on_hurt_end; std::vector on_destroy; [[nodiscard]] auto getActions(EnemyEventType event) const -> const std::vector& { switch (event) { case EnemyEventType::ON_HIT: return on_hit; case EnemyEventType::ON_NO_HEALTH: return on_no_health; case EnemyEventType::ON_HURT_END: return on_hurt_end; case EnemyEventType::ON_DESTROY: return on_destroy; } return on_hit; // unreachable } };