#include "enemies.h" #include static enemy_t const slime = { .name = "Slime", .hitbox = (frect_t){ -FIX(3)/16, FIX(4)/16, -FIX(2)/16, FIX(3)/16 }, .sprite = (frect_t){ -FIX(5)/16, FIX(5)/16, -FIX(4)/16, FIX(3)/16 }, .anim_idle = anim_slime_idle_down, .anim_death = anim_slime_death, .movement_params = { .max_speed = FIX(1), .propulsion = FIX(12), }, .HP = { .base = FIX(10), .growth = FIX(5), .affinity = FIX(3), }, .ATK = { .base = FIX(5), .growth = FIX(2), .affinity = FIX(1), }, .DEF = { .base = FIX(2), .growth = FIX(1), .affinity = FIX(1)/2, }, }; static enemy_t const bat = { .name = "Bat", .hitbox = (frect_t){ -FIX(3)/16, FIX(4)/16, -FIX(2)/16, FIX(3)/16 }, .sprite = (frect_t){ -FIX(5)/16, FIX(5)/16, -FIX(4)/16, FIX(3)/16 }, .anim_idle = anim_bat_idle_down, .anim_death = anim_bat_death, .movement_params = { .max_speed = FIX(2), .propulsion = FIX(8), }, .HP = { .base = FIX(8), .growth = FIX(4), .affinity = FIX(2), }, .ATK = { .base = FIX(8), .growth = FIX(2), .affinity = FIX(2), }, .DEF = { .base = FIX(2), .growth = FIX(2), .affinity = FIX(1), }, }; enemy_t const * const enemies[] = { [ENEMY_SLIME] = &slime, [ENEMY_BAT] = &bat, }; int instantiate_stat(enemy_stat_t const *stat, int level) { fixed_t value = stat->base + stat->growth * (level - 1) + stat->affinity * (level * (level - 1) / 2); fixed_t variation = value / 8; value = (value - variation) + (rand() % (2 * variation)); return ffloor(value); } entity_t *enemy_spawn(int enemy_id, int level) { if(enemy_id < 0 || (size_t)enemy_id >= sizeof enemies / sizeof *enemies) return NULL; entity_t *e = malloc(sizeof *e); if(!e) return NULL; enemy_t const *data = enemies[enemy_id]; /* These will probably be overridden by the caller */ e->movement.x = 0; e->movement.y = 0; e->movement.vx = 0; e->movement.vy = 0; e->movement.facing = DOWN; e->movement.dash = 0; e->movement.dash_facing = DOWN; e->movement.dash_particle_cooldown = fix(0); e->movement_params = &data->movement_params; entity_set_anim(e, data->anim_idle); e->hitbox = data->hitbox; e->sprite = data->sprite; e->current_attack = NULL; e->attack_follows_movement = false; e->identity = enemy_id; e->HP = instantiate_stat(&data->HP, level); e->ATK = instantiate_stat(&data->ATK, level); e->DEF = instantiate_stat(&data->DEF, level); return e; }