#ifndef JNR_ENEMY_H #define JNR_ENEMY_H #include "engine/entity.h" #include "engine/camera.h" #include "engine/tilemap.h" /* ── Grunt enemy ───────────────────────────────────── */ /* A ground-patrolling enemy that walks back and forth */ #define GRUNT_WIDTH 12 #define GRUNT_HEIGHT 16 #define GRUNT_SPEED 40.0f /* horizontal walk speed (px/s) */ #define GRUNT_HEALTH 2 typedef struct GruntData { float patrol_dir; /* 1.0 or -1.0 */ float death_timer; /* countdown after dying */ } GruntData; void grunt_register(EntityManager *em); Entity *grunt_spawn(EntityManager *em, Vec2 pos); /* ── Flyer enemy ───────────────────────────────────── */ /* A flying enemy that bobs up and down, moves toward */ /* the player when in range */ #define FLYER_WIDTH 14 #define FLYER_HEIGHT 12 #define FLYER_SPEED 50.0f /* horizontal chase speed (px/s) */ #define FLYER_BOB_AMP 20.0f /* vertical bob amplitude */ #define FLYER_BOB_SPD 2.5f /* bob frequency (radians/s) */ #define FLYER_HEALTH 1 #define FLYER_DETECT 120.0f /* detection range (px) */ #define FLYER_SHOOT_CD 2.0f /* seconds between shots */ typedef struct FlyerData { float bob_timer; /* for sine wave bobbing */ float base_y; /* original y position */ float death_timer; float shoot_timer; /* cooldown for shooting */ } FlyerData; void flyer_register(EntityManager *em); Entity *flyer_spawn(EntityManager *em, Vec2 pos); /* ── Charger enemy ─────────────────────────────────── */ /* Ground patrol that detects the player, telegraphs */ /* briefly, then charges at high speed. Stuns on wall. */ #define CHARGER_WIDTH 14 #define CHARGER_HEIGHT 16 #define CHARGER_PATROL_SPEED 30.0f /* slow patrol (px/s) */ #define CHARGER_CHARGE_SPEED 150.0f /* charge rush speed (px/s) */ #define CHARGER_DETECT_RANGE 200.0f /* horizontal detect (px) */ #define CHARGER_CHARGE_TIME 2.0f /* max charge duration (s) */ #define CHARGER_HEALTH 2 typedef enum ChargerState { CHARGER_PATROL, CHARGER_ALERT, /* telegraph before charging */ CHARGER_CHARGE, /* full-speed horizontal rush */ CHARGER_STUNNED, /* hit a wall, briefly vulnerable */ } ChargerState; typedef struct ChargerData { ChargerState state; float patrol_dir; /* 1.0 or -1.0 */ float state_timer; /* countdown for current state */ float death_timer; } ChargerData; void charger_register(EntityManager *em); Entity *charger_spawn(EntityManager *em, Vec2 pos); /* ── Spawner enemy ─────────────────────────────────── */ /* Stationary, periodically spawns grunt enemies up to */ /* a cap. Destructible. */ #define SPAWNER_WIDTH 16 #define SPAWNER_HEIGHT 16 #define SPAWNER_HEALTH 3 #define SPAWNER_INTERVAL 4.5f /* seconds between spawns */ #define SPAWNER_MAX_ALIVE 3 /* max grunts alive at once */ typedef struct SpawnerData { float spawn_timer; /* countdown to next spawn */ float death_timer; float pulse_timer; /* visual pulse before spawn */ } SpawnerData; void spawner_register(EntityManager *em); Entity *spawner_spawn(EntityManager *em, Vec2 pos); #endif /* JNR_ENEMY_H */