Files
major_tom/src/engine/entity.h
Thomas af0a9904c2 Fix laser beam blocked by own tile, consolidate enemy-type checks
Beam raycast now skips the tile the turret is mounted on, so
wall-embedded laser turrets can shoot outward.

Extract entity_is_enemy() into engine/entity.c as single source
of truth for enemy-type checks. Replaces triplicated type lists
in level.c, drone.c, and projectile.c that caused the collision
bug when new enemy types were added.
2026-03-02 20:56:45 +00:00

88 lines
2.5 KiB
C

#ifndef JNR_ENTITY_H
#define JNR_ENTITY_H
#include <stdbool.h>
#include <stdint.h>
#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 */