#include "comp/entity.h" #include "comp/physical.h" #include "comp/visible.h" #include "comp/mechanical.h" #include "comp/fighter.h" #include "enemies.h" #include /* Declare animations for an enemy */ #define ANIMS(name, I, W, A, H, D) \ .anim_idle = &anims_ ## name ## _ ## I, \ .anim_walking = &anims_ ## name ## _ ## W, \ .anim_attack = &anims_ ## name ## _ ## A, \ .anim_hit = &anims_ ## name ## _ ## H, \ .anim_death = &anims_ ## name ## _ ## D static enemy_t const slime_1 = { .name = "Slime", .level = 1, ANIMS(slime, Idle, Walking, Idle, Hit, Death), .hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 }, .limits = { .max_speed = fix(1), .friction = fix(0.6), }, .stats = { .HP = fix(1.4), .ATK = fix(1.3), .MAG = fix(1.0), .DEF = fix(1.4), }, .shadow_size = 4, .xp = 2, .z = 0, }; static enemy_t const bat_2 = { .name = "Bat", .level = 2, ANIMS(bat, Idle, Idle, Idle, Hit, Death), .hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 }, .limits = { .max_speed = fix(1.8), .friction = fix(0.8), }, .stats = { .HP = fix(1.5), .ATK = fix(1.5), .MAG = fix(1.3), .DEF = fix(1.2), }, .shadow_size = 4, .xp = 6, .z = fix(0.75), }; static enemy_t const fire_slime_4 = { .name = "Fire slime", .level = 4, ANIMS(fire_slime, Idle, Walking, Idle, Hit, Death), .hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 }, .limits = { .max_speed = fix(1), .friction = fix(0.6), }, .stats = { .HP = fix(1.4), .ATK = fix(1.2), .MAG = fix(1.4), .DEF = fix(1.4), }, .shadow_size = 4, .xp = 14, .z = 0, }; static enemy_t const gunslinger_8 = { .name = "Gunslinger", .level = 8, ANIMS(gunslinger, Idle, Walking, Fire, Hit, Death), .hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 }, .limits = { .max_speed = fix(1.8), .friction = fix(0.8), }, .stats = { .HP = fix(1.3), .ATK = fix(1.6), .MAG = fix(1.4), .DEF = fix(1.2), }, .shadow_size = 4, .xp = 30, .z = fix(0.375), }; static enemy_t const * const enemies[] = { [ENEMY_SLIME_1] = &slime_1, [ENEMY_BAT_2] = &bat_2, [ENEMY_FIRE_SLIME_4] = &fire_slime_4, [ENEMY_GUNSLINGER_8] = &gunslinger_8, }; enemy_t const *enemy_data(int enemy_id) { return enemies[enemy_id]; } entity_t *enemy_make(int enemy_id) { if(enemy_id < 0 || (size_t)enemy_id >= sizeof enemies / sizeof *enemies) return NULL; entity_t *e = entity_make(physical, visible, mechanical, fighter); if(e == NULL) return NULL; enemy_t const *data = enemies[enemy_id]; /* These will probably be overridden by the caller */ physical_t *p = getcomp(e, physical); p->x = fix(0); p->y = fix(0); p->hitbox = data->hitbox; p->facing = LEFT; visible_t *v = getcomp(e, visible); v->z = data->z; v->sprite_plane = VERTICAL; v->shadow_size = data->shadow_size; visible_set_anim(e, data->anim_idle, 1); mechanical_t *m = getcomp(e, mechanical); m->limits = &data->limits; m->vx = fix(0); m->vy = fix(0); m->dash = fix(0); m->dash_facing = LEFT; /* Instantiate fighter statistics */ fighter_t *f = getcomp(e, fighter); memset(f, 0, sizeof *f); f->enemy_data = data; fighter_set_stats(f, &data->stats, data->level, fix(1.0)); f->HP = f->HP_max; f->combo_length = 1; return e; }