#ifndef JNR_ENTITY_H #define JNR_ENTITY_H #include #include #include "config.h" #include "engine/physics.h" #include "engine/animation.h" #include "util/vec2.h" /* Forward declarations */ typedef struct Tilemap Tilemap; typedef struct Camera Camera; typedef enum EntityType { ENT_NONE = 0, ENT_PLAYER, ENT_ENEMY_GRUNT, ENT_ENEMY_FLYER, ENT_PROJECTILE, ENT_PICKUP, ENT_PARTICLE, ENT_TURRET, ENT_MOVING_PLATFORM, ENT_FLAME_VENT, ENT_FORCE_FIELD, ENT_POWERUP, ENT_DRONE, ENT_ASTEROID, ENT_SPACECRAFT, ENT_LASER_TURRET, ENT_ENEMY_CHARGER, ENT_SPAWNER, ENT_TYPE_COUNT } EntityType; /* Entity flags */ #define ENTITY_INVINCIBLE (1 << 0) #define ENTITY_FACING_LEFT (1 << 1) #define ENTITY_DEAD (1 << 2) #define ENTITY_ALWAYS_UPDATE (1 << 3) /* never culled by distance */ typedef struct Entity { EntityType type; bool active; Body body; Animation anim; int health; int max_health; int damage; uint32_t flags; float timer; /* general-purpose timer */ void *data; /* type-specific data pointer */ } Entity; /* Function pointer types for entity behaviors */ typedef void (*EntityUpdateFn)(Entity *self, float dt, const Tilemap *map); typedef void (*EntityRenderFn)(Entity *self, const Camera *cam); typedef void (*EntityDestroyFn)(Entity *self); typedef struct EntityManager { Entity entities[MAX_ENTITIES]; int count; /* dispatch tables */ EntityUpdateFn update_fn[ENT_TYPE_COUNT]; EntityRenderFn render_fn[ENT_TYPE_COUNT]; EntityDestroyFn destroy_fn[ENT_TYPE_COUNT]; } EntityManager; void entity_manager_init(EntityManager *em); Entity *entity_spawn(EntityManager *em, EntityType type, Vec2 pos); void entity_destroy(EntityManager *em, Entity *e); void entity_update_all(EntityManager *em, float dt, const Tilemap *map, const Camera *cam); void entity_render_all(EntityManager *em, const Camera *cam); void entity_manager_clear(EntityManager *em); /* Register behavior functions for an entity type */ void entity_register(EntityManager *em, EntityType type, EntityUpdateFn update, EntityRenderFn render, EntityDestroyFn destroy); /* Returns true if the entity is a hostile enemy type. * Single source of truth — add new enemy types here. */ bool entity_is_enemy(const Entity *e); #endif /* JNR_ENTITY_H */