112 lines
2.7 KiB
C
112 lines
2.7 KiB
C
#include "enemies.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
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;
|
|
}
|