diff --git a/src/battle/ai.c b/src/battle/ai.c index a6b2c00..a216846 100644 --- a/src/battle/ai.c +++ b/src/battle/ai.c @@ -41,11 +41,13 @@ static void moveToItem(void); static int nearTowableCraft(void); static void moveToTowableCraft(void); static void lookForPlayer(void); +static int lookForLeader(void); static void fleeEnemies(void); static int isRetreating(void); static int getActionChance(int type); static void doFighterAI(void); static void doGunAI(void); +static void moveToLeader(void); void doAI(void) { @@ -123,7 +125,15 @@ static void doFighterAI(void) if (!self->target) { - if (self->aiFlags & AIF_MOVES_TO_PLAYER && player != NULL) + /* takes priority over move to player */ + if (self->aiFlags & AIF_MOVES_TO_LEADER) + { + if (!lookForLeader()) + { + applyFighterBrakes(); + } + } + else if (self->aiFlags & AIF_MOVES_TO_PLAYER && player != NULL) { moveToPlayer(); } @@ -659,6 +669,8 @@ static int nearTowableCraft(void) candidates = getAllEntsWithin(self->x - (self->w / 2) - (GRID_CELL_WIDTH / 2), self->y - (self->h / 2) - (GRID_CELL_HEIGHT / 2), GRID_CELL_WIDTH, GRID_CELL_HEIGHT, self); + closest = MAX_TARGET_RANGE; + self->target = NULL; for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) @@ -705,3 +717,51 @@ static void lookForPlayer(void) applyFighterBrakes(); } + +static int lookForLeader(void) +{ + long closest, distance; + Entity *e; + + self->leader = NULL; + + for (e = battle.entityHead.next ; e != NULL ; e = e->next) + { + if (e->active && e->flags & EF_AI_LEADER) + { + distance = getDistance(self->x, self->y, e->x, e->y); + + if (distance < closest) + { + self->leader = e; + closest = distance; + } + } + } + + if (self->leader) + { + moveToLeader(); + return 1; + } + + return 0; +} + +static void moveToLeader(void) +{ + int dist = getDistance(self->x, self->y, self->leader->x, self->leader->y); + + if (dist <= 250) + { + applyFighterBrakes(); + + self->aiActionTime = MIN(FPS, self->aiActionTime); + } + else + { + faceTarget(self->leader); + + applyFighterThrust(); + } +} diff --git a/src/defs.h b/src/defs.h index 631a0a7..a1d5807 100644 --- a/src/defs.h +++ b/src/defs.h @@ -99,6 +99,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define AIF_AGGRESSIVE (2 << 10) #define AIF_INSTANT_DIE (2 << 11) #define AIF_LONG_RANGE_FIRE (2 << 12) +#define AIF_MOVES_TO_LEADER (2 << 13) /* player abilities */ #define BOOST_RECHARGE_TIME (FPS * 7) diff --git a/src/structs.h b/src/structs.h index 6c36c48..2d8cd9d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -126,6 +126,7 @@ struct Entity { SDL_Point targetLocation; Entity *towing; Entity *target; + Entity *leader; Entity *owner; void (*action)(void); void (*die)(void); diff --git a/src/system/lookup.c b/src/system/lookup.c index 9998d58..acedae0 100644 --- a/src/system/lookup.c +++ b/src/system/lookup.c @@ -47,6 +47,7 @@ void initLookups(void) addLookup("EF_TAKES_DAMAGE", EF_TAKES_DAMAGE); addLookup("EF_SECONDARY_TARGET", EF_SECONDARY_TARGET); addLookup("EF_AI_TARGET", EF_AI_TARGET); + addLookup("EF_AI_LEADER", EF_AI_LEADER); addLookup("AIF_NONE", AIF_NONE); addLookup("AIF_MOVES_TO_PLAYER", AIF_MOVES_TO_PLAYER); @@ -62,6 +63,7 @@ void initLookups(void) addLookup("AIF_AGGRESSIVE", AIF_AGGRESSIVE); addLookup("AIF_INSTANT_DIE", AIF_INSTANT_DIE); addLookup("AIF_LONG_RANGE_FIRE", AIF_LONG_RANGE_FIRE); + addLookup("AIF_MOVES_TO_LEADER", AIF_MOVES_TO_LEADER); addLookup("TT_DESTROY", TT_DESTROY); addLookup("TT_DISABLE", TT_DISABLE);