84 lines
3.1 KiB
C++
84 lines
3.1 KiB
C++
// enemy_ai.hpp - Sistema declaratiu d'IA per a enemics
|
|
// © 2026 JailDesigner
|
|
//
|
|
// Cada enemic declara al seu YAML quin movement primitiu fa servir i, opcional-
|
|
// ment, una llista d'accions periòdiques (tick). El motor només dispatcha; el
|
|
// comportament viu a les dades. Patró paral·lel al d'events declaratius
|
|
// (enemy_event.hpp).
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Primitiva de moviment activa per a un enemic. Substitueix el switch
|
|
// hardcoded sobre EnemyType.
|
|
enum class MovementType : uint8_t {
|
|
ZIGZAG, // Canvi de direcció probabilístic agressiu (Pentagon/Star)
|
|
TRACKING, // LERP discret cap al ship cada N segons (Square)
|
|
RECTILINEAR_PROXIMITY, // Rectilini + boost rotació visual prop del ship (Pinwheel)
|
|
WANDER, // Canvi de direcció probabilístic suau, sense target
|
|
CHASE, // Steering continu cap al ship més proper
|
|
FLEE, // Steering continu allunyant-se del ship més proper
|
|
};
|
|
|
|
// Accions que s'executen periòdicament (un timer per acció). Futur (Fase C):
|
|
// SHOOT amb aim_mode/jitter/bullet config.
|
|
enum class AiActionType : uint8_t {
|
|
SHOOT,
|
|
};
|
|
|
|
enum class AimMode : uint8_t {
|
|
RANDOM, // Angle uniformement aleatori
|
|
AIMED, // atan2(nearest_ship - center) + soroll gaussià (jitter_rad)
|
|
};
|
|
|
|
// Camps de tots els movements; només el subset rellevant per al type actiu
|
|
// s'usa. Els altres queden a 0.0F. Mateixa filosofia que la BehaviorCfg
|
|
// llegacy però amb el type explícit dins.
|
|
struct MovementConfig {
|
|
MovementType type{MovementType::ZIGZAG};
|
|
|
|
// ZIGZAG i WANDER (canvi de direcció probabilístic; comparteixen camps).
|
|
float angle_change_max{0.0F};
|
|
float zigzag_prob_per_second{0.0F};
|
|
|
|
// TRACKING
|
|
float tracking_strength{0.0F};
|
|
float tracking_interval{0.0F};
|
|
|
|
// RECTILINEAR_PROXIMITY
|
|
float rotation_proximity_multiplier{0.0F};
|
|
float proximity_distance{0.0F};
|
|
|
|
// CHASE / FLEE: força del steering per segon (LERP velocity ↔ direcció ideal).
|
|
// 1.0 = en ~1s la velocitat queda totalment realineada cap al target.
|
|
float chase_strength{0.0F};
|
|
float flee_strength{0.0F};
|
|
};
|
|
|
|
// Acció periòdica. interval = segons entre disparades; el dispatcher manté un
|
|
// timer per acció (paral·lel a aquesta llista) i dispara quan arriba a 0.
|
|
struct AiTickAction {
|
|
AiActionType type{AiActionType::SHOOT};
|
|
float interval{1.0F};
|
|
AimMode aim_mode{AimMode::RANDOM};
|
|
float jitter_rad{0.0F};
|
|
std::string bullet_config_name; // referit per nom (Fase C); buit a Fase A/B
|
|
};
|
|
|
|
struct EnemyAiConfig {
|
|
MovementConfig movement;
|
|
std::vector<AiTickAction> tick;
|
|
};
|
|
|
|
// Estat per-instància que la primitiva de moviment manté entre frames (timers
|
|
// d'interval, contadors de canvi de direcció...). Es viu dins de Enemy i el
|
|
// sistema d'IA hi escriu via getAiState().
|
|
struct EnemyAiState {
|
|
float direction_change_timer{0.0F}; // ZIGZAG
|
|
float tracking_timer{0.0F}; // TRACKING
|
|
float tracking_strength{0.0F}; // TRACKING (cau de cfg, mutable per dificultat)
|
|
};
|