bats now back off after an attack
This commit is contained in:
parent
d330c22d66
commit
33b8fda4da
|
@ -6,6 +6,7 @@
|
|||
#include "aoe.h"
|
||||
#include "enemies.h"
|
||||
#include "skills.h"
|
||||
#include <gint/defs/util.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Declare animations for an enemy */
|
||||
|
@ -35,6 +36,11 @@ static enemy_t const slime_1 = {
|
|||
.shadow_size = 4,
|
||||
.xp = 2,
|
||||
.z = 0,
|
||||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
struct bat_ai {
|
||||
fixed_t retreat_period;
|
||||
};
|
||||
|
||||
static enemy_t const bat_2 = {
|
||||
|
@ -56,6 +62,7 @@ static enemy_t const bat_2 = {
|
|||
.shadow_size = 4,
|
||||
.xp = 6,
|
||||
.z = fix(0.75),
|
||||
.ai_data_size = sizeof(struct bat_ai),
|
||||
};
|
||||
|
||||
static enemy_t const fire_slime_4 = {
|
||||
|
@ -77,6 +84,7 @@ static enemy_t const fire_slime_4 = {
|
|||
.shadow_size = 4,
|
||||
.xp = 14,
|
||||
.z = 0,
|
||||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
static enemy_t const gunslinger_8 = {
|
||||
|
@ -98,6 +106,7 @@ static enemy_t const gunslinger_8 = {
|
|||
.shadow_size = 4,
|
||||
.xp = 30,
|
||||
.z = fix(0.25),
|
||||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
static enemy_t const * const enemies[] = {
|
||||
|
@ -151,13 +160,18 @@ entity_t *enemy_make(int enemy_id)
|
|||
fighter_set_stats(f, &data->stats, data->level, fix(1.0));
|
||||
f->HP = f->HP_max;
|
||||
f->combo_length = 1;
|
||||
f->enemy = malloc(sizeof *f->enemy);
|
||||
f->enemy = malloc(sizeof *f->enemy + data->ai_data_size);
|
||||
f->enemy->id = data;
|
||||
f->enemy->pathfind_dir = (vec2){ 0, 0 };
|
||||
f->enemy->pathfind_cycles = 0;
|
||||
f->enemy->ai_data = (void *)f->enemy + sizeof *f->enemy;
|
||||
|
||||
/* Specify skills */
|
||||
if(enemy_id == ENEMY_GUNSLINGER_8) {
|
||||
/* Specify skills and initialize AI data */
|
||||
if(enemy_id == ENEMY_BAT_2) {
|
||||
struct bat_ai *ai_data = f->enemy->ai_data;
|
||||
ai_data->retreat_period = 0;
|
||||
}
|
||||
else if(enemy_id == ENEMY_GUNSLINGER_8) {
|
||||
f->skills[0] = AOE_PROJECTILE;
|
||||
}
|
||||
|
||||
|
@ -216,6 +230,28 @@ static bool move_within_range_of_player(game_t *g, entity_t *e, fixed_t range,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool move_away_from_player_range(game_t *g, entity_t *e, fixed_t range,
|
||||
fixed_t dt)
|
||||
{
|
||||
physical_t *p = getcomp(e, physical);
|
||||
fighter_t *f = getcomp(e, fighter);
|
||||
if(!p || !f || !f->enemy)
|
||||
return true;
|
||||
|
||||
if(dist2(physical_pos(e), physical_pos(g->player)) > fmul(range, range))
|
||||
return true;
|
||||
|
||||
/* Escape opposite the direction of normal movement */
|
||||
vec2 direction = f->enemy->pathfind_dir;
|
||||
direction = (vec2){ -direction.x, -direction.y };
|
||||
|
||||
mechanical_move(e, direction, dt, g->map);
|
||||
if(p->x < getcomp(g->player, physical)->x) p->facing = RIGHT;
|
||||
else p->facing = LEFT;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool contact_attack(game_t *g, entity_t *e)
|
||||
{
|
||||
fighter_t *f = getcomp(e, fighter);
|
||||
|
@ -254,12 +290,27 @@ void enemy_ai(game_t *g, entity_t *e, fixed_t dt)
|
|||
{
|
||||
fighter_t *f = getcomp(e, fighter);
|
||||
|
||||
if(f->enemy->id == &slime_1 || f->enemy->id == &bat_2) {
|
||||
if(f->enemy->id == &slime_1) {
|
||||
if(move_within_range_of_player(g, e, fix(1.0), dt)) {
|
||||
contact_attack(g, e);
|
||||
}
|
||||
}
|
||||
|
||||
else if(f->enemy->id == &bat_2) {
|
||||
struct bat_ai *ai_data = f->enemy->ai_data;
|
||||
|
||||
/* After an attack, move away for a couple of seconds */
|
||||
if(ai_data->retreat_period > 0) {
|
||||
move_away_from_player_range(g, e, fix(3.0), dt);
|
||||
ai_data->retreat_period = max(ai_data->retreat_period-dt, fix(0));
|
||||
}
|
||||
/* Otherwise, get close and attack */
|
||||
else if(move_within_range_of_player(g, e, fix(1.0), dt)) {
|
||||
contact_attack(g, e);
|
||||
ai_data->retreat_period = fix(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
else if(f->enemy->id == &fire_slime_4) {
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ typedef struct
|
|||
uint16_t xp;
|
||||
/* Rendering elevation */
|
||||
fixed_t z;
|
||||
/* Size of the monster-specific data structure for IA */
|
||||
size_t ai_data_size;
|
||||
|
||||
} enemy_t;
|
||||
|
||||
|
@ -51,6 +53,8 @@ typedef struct enemy_data {
|
|||
vec2 pathfind_dir;
|
||||
/* Number of frames left until next pathfinding cycle */
|
||||
uint8_t pathfind_cycles;
|
||||
/* Pointer to AI-specific data */
|
||||
void *ai_data;
|
||||
|
||||
} enemy_data_t;
|
||||
|
||||
|
|
Loading…
Reference in New Issue