Files
major_tom/src/game/entity_registry.c
Thomas 49ed2d6f7b Add spatial audio, spacecraft entity, and level intro sequence
Distance-based sound effects with stereo panning for explosions, impacts,
and pickups. Spacecraft entity with full state machine (fly-in, land, take
off, fly-out), engine/synth sound loops, thruster particles, and PNG
spritesheet. Moon level intro defers player spawn until ship lands.

Also untrack build/ objects that were committed by mistake.
2026-03-01 11:00:51 +00:00

119 lines
5.1 KiB
C

#include "game/entity_registry.h"
#include "game/player.h"
#include "game/enemy.h"
#include "game/projectile.h"
#include "game/hazards.h"
#include "game/powerup.h"
#include "game/drone.h"
#include "game/spacecraft.h"
#include <string.h>
#include <stdio.h>
EntityRegistry g_entity_registry = {0};
/* ── Wrapper spawn functions ──────────────────────
* Some spawn functions need extra args beyond (em, pos).
* We wrap them to match the EntitySpawnFn signature.
* ──────────────────────────────────────────────────── */
static Entity *spawn_platform_v(EntityManager *em, Vec2 pos) {
return mplat_spawn_dir(em, pos, vec2(0.0f, 1.0f));
}
static Entity *spawn_powerup_health(EntityManager *em, Vec2 pos) {
return powerup_spawn_health(em, pos);
}
static Entity *spawn_powerup_jetpack(EntityManager *em, Vec2 pos) {
return powerup_spawn_jetpack(em, pos);
}
static Entity *spawn_powerup_drone(EntityManager *em, Vec2 pos) {
return powerup_spawn_drone(em, pos);
}
static Entity *spawn_powerup_gun(EntityManager *em, Vec2 pos) {
return powerup_spawn_gun(em, pos);
}
/* ── Registry population ─────────────────────────── */
static void reg_add(const char *name, const char *display,
EntitySpawnFn fn, SDL_Color color, int w, int h) {
EntityRegistry *r = &g_entity_registry;
if (r->count >= MAX_REGISTRY_ENTRIES) return;
r->entries[r->count++] = (EntityRegEntry){
.name = name,
.display = display,
.spawn_fn = fn,
.color = color,
.width = w,
.height = h,
};
}
void entity_registry_init(EntityManager *em) {
g_entity_registry.count = 0;
/* Register all entity behaviors with the entity manager */
player_register(em);
player_set_entity_manager(em);
grunt_register(em);
flyer_register(em);
projectile_register(em);
turret_register(em);
mplat_register(em);
flame_vent_register(em);
force_field_register(em);
powerup_register(em);
drone_register(em);
asteroid_register(em);
spacecraft_register(em);
/* ════════════════════════════════════════════
* REGISTRY TABLE
*
* To add a new entity type to the game:
* 1. Create its .h/.c files
* 2. Register its behaviors above
* 3. Add one reg_add() line below
*
* The editor will pick it up automatically.
* ════════════════════════════════════════════ */
/* .lvl name display name spawn fn color (editor) w h */
reg_add("grunt", "Grunt", grunt_spawn, (SDL_Color){200, 60, 60, 255}, GRUNT_WIDTH, GRUNT_HEIGHT);
reg_add("flyer", "Flyer", flyer_spawn, (SDL_Color){140, 80, 200, 255}, FLYER_WIDTH, FLYER_HEIGHT);
reg_add("turret", "Turret", turret_spawn, (SDL_Color){160, 160, 160, 255}, TURRET_WIDTH, TURRET_HEIGHT);
reg_add("platform", "Platform (H)", mplat_spawn, (SDL_Color){80, 180, 80, 255}, MPLAT_WIDTH, MPLAT_HEIGHT);
reg_add("platform_v", "Platform (V)", spawn_platform_v, (SDL_Color){80, 160, 100, 255}, MPLAT_WIDTH, MPLAT_HEIGHT);
reg_add("flame_vent", "Flame Vent", flame_vent_spawn, (SDL_Color){255, 120, 40, 255}, FLAME_WIDTH, FLAME_HEIGHT);
reg_add("force_field", "Force Field", force_field_spawn, (SDL_Color){60, 140, 255, 255}, FFIELD_WIDTH, FFIELD_HEIGHT);
reg_add("powerup_hp", "Health Pickup", spawn_powerup_health, (SDL_Color){255, 80, 80, 255}, 12, 12);
reg_add("powerup_jet", "Jetpack Refill", spawn_powerup_jetpack,(SDL_Color){255, 200, 50, 255}, 12, 12);
reg_add("powerup_drone", "Drone Pickup", spawn_powerup_drone, (SDL_Color){80, 200, 255, 255}, 12, 12);
reg_add("powerup_gun", "Gun Pickup", spawn_powerup_gun, (SDL_Color){200, 200, 220, 255}, 12, 12);
reg_add("asteroid", "Asteroid", asteroid_spawn, (SDL_Color){140, 110, 80, 255}, ASTEROID_WIDTH, ASTEROID_HEIGHT);
reg_add("spacecraft", "Spacecraft", spacecraft_spawn, (SDL_Color){187, 187, 187, 255}, SPACECRAFT_WIDTH, SPACECRAFT_HEIGHT);
printf("Entity registry: %d types registered\n", g_entity_registry.count);
}
const EntityRegEntry *entity_registry_find(const char *name) {
for (int i = 0; i < g_entity_registry.count; i++) {
if (strcmp(g_entity_registry.entries[i].name, name) == 0) {
return &g_entity_registry.entries[i];
}
}
return NULL;
}
Entity *entity_registry_spawn(EntityManager *em, const char *name, Vec2 pos) {
const EntityRegEntry *entry = entity_registry_find(name);
if (!entry) {
fprintf(stderr, "entity_registry_spawn: unknown type '%s'\n", name);
return NULL;
}
return entry->spawn_fn(em, pos);
}