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

109 lines
3.8 KiB
C++

// enemy_config.hpp - Configuració d'un tipus d'enemic carregada des de YAML
// © 2026 JailDesigner
//
// Una instància per tipus (Pentagon/Square/Pinwheel), carregada un cop al
// startup per EnemyRegistry i compartida entre totes les instàncies d'aquell
// tipus. Estructura paral·lela a PlayerConfig.
#pragma once
#include <SDL3/SDL.h>
#include <optional>
#include <string>
#include "external/fkyaml_node.hpp"
#include "game/entities/enemy.hpp" // EnemyType
#include "game/entities/enemy_event.hpp"
struct EnemyConfig {
struct ShapeCfg {
std::string path;
float scale; // multiplicador visual + hitbox sobre la mida nativa del .shp
float collision_factor; // ajust opcional del hitbox respecte el cercle circumscrit (default 1.0)
};
struct PhysicsCfg {
float mass;
float speed;
float rotation_delta_min;
float rotation_delta_max;
float restitution; // rebot contra parets (1.0 = perfectament elàstic)
float linear_damping; // fricció lineal (s^-1)
float angular_damping;
};
// Camps específics de cada AI. Els no aplicables a un tipus queden a 0.0F
// i no s'usen — el dispatch viu a Enemy::behaviorXxx.
struct BehaviorCfg {
// Pentagon
float zigzag_prob_per_second{0.0F};
float angle_change_max{0.0F};
// Square
float tracking_strength{0.0F};
float tracking_interval{0.0F};
// Pinwheel
float rotation_proximity_multiplier{0.0F};
float proximity_distance{0.0F};
};
// Animacions decoratives. Compartides estructuralment entre tots els tipus
// però amb valors propis per personalitzar la "personalitat" visual de cada un.
struct AnimationCfg {
struct PulseCfg {
float trigger_prob_per_second; // probabilitat per segon d'iniciar un pulse
float duration_min;
float duration_max;
float amplitude_min; // amplitud d'escala (±)
float amplitude_max;
float frequency_min; // Hz
float frequency_max;
};
struct RotationAccelCfg {
float trigger_prob_per_second;
float duration_min; // segons de transició al nou speed
float duration_max;
float multiplier_min; // multiplicador sobre rotation_delta_base
float multiplier_max;
};
PulseCfg pulse;
RotationAccelCfg rotation_accel;
};
struct WoundedCfg {
float duration; // segons en estat ferit abans d'explotar
float blink_hz; // freqüència del parpelleig color normal ↔ wounded
};
struct SpawnCfg {
float invulnerability_duration; // segons d'invulnerabilitat post-spawn
float invulnerability_brightness_start; // brightness inicial (corba LERP)
float invulnerability_brightness_end; // brightness final
float invulnerability_scale_start; // escala inicial (corba LERP, 0 = invisible)
float invulnerability_scale_end; // escala final (1 = mida nativa)
float safety_distance; // px mínim respecte al player al spawn
};
struct ColorsCfg {
SDL_Color normal;
SDL_Color wounded;
};
std::string name;
EnemyType ai_type;
ShapeCfg shape;
PhysicsCfg physics;
BehaviorCfg behavior;
AnimationCfg animation;
WoundedCfg wounded;
SpawnCfg spawn;
ColorsCfg colors;
int score;
EnemyEventConfig events;
// Parseja un descriptor d'enemic. expected_ai_type valida que ai_type del
// YAML coincideix amb el tipus que el caller espera (segons el directori).
static auto fromYaml(const fkyaml::node& node, EnemyType expected_ai_type)
-> std::optional<EnemyConfig>;
};