Files
orni-attack/source/game/entities/enemy_ai.hpp
T

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)
};