Allow enemies to flee.
This commit is contained in:
parent
6409e4ec11
commit
a87395cc23
|
@ -5,12 +5,6 @@
|
||||||
"planet" : "gfx/planets/spirit.png",
|
"planet" : "gfx/planets/spirit.png",
|
||||||
"music" : "",
|
"music" : "",
|
||||||
"objectives" : [
|
"objectives" : [
|
||||||
{
|
|
||||||
"description" : "Reach Waypoints",
|
|
||||||
"targetName" : "Waypoint",
|
|
||||||
"targetValue" : 1,
|
|
||||||
"targetType" : "TT_WAYPOINT"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description" : "Destroy Fighters",
|
"description" : "Destroy Fighters",
|
||||||
"targetName" : "Dart",
|
"targetName" : "Dart",
|
||||||
|
@ -19,22 +13,6 @@
|
||||||
"active" : 0
|
"active" : 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"triggers" : [
|
|
||||||
{
|
|
||||||
"type" : "TRIGGER_WAYPOINT",
|
|
||||||
"targetName" : "Waypoint #1",
|
|
||||||
"targetValue" : "1",
|
|
||||||
"action" : "TA_ACTIVE_ENTITY",
|
|
||||||
"actionValue" : "Dart"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type" : "TRIGGER_WAYPOINT",
|
|
||||||
"targetName" : "Waypoint #1",
|
|
||||||
"targetValue" : "1",
|
|
||||||
"action" : "TA_ACTIVE_OBJECTIVE",
|
|
||||||
"actionValue" : "1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"player" : {
|
"player" : {
|
||||||
"type" : "ATAF",
|
"type" : "ATAF",
|
||||||
"side" : "SIDE_CSN"
|
"side" : "SIDE_CSN"
|
||||||
|
@ -46,15 +24,17 @@
|
||||||
"side" : "SIDE_PIRATE",
|
"side" : "SIDE_PIRATE",
|
||||||
"x" : 640,
|
"x" : 640,
|
||||||
"y" : 0,
|
"y" : 0,
|
||||||
"active" : 0
|
"flags" : "EF_FLEES+EF_MISSION_TARGET"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"entityGroups" : [
|
"fighterGroups" : [
|
||||||
{
|
{
|
||||||
"type" : "ET_WAYPOINT",
|
"name" : "Dart",
|
||||||
"number" : 1,
|
"types" : "UnarmedDart",
|
||||||
"x" : 0,
|
"side" : "SIDE_PIRATE",
|
||||||
"y" : 1000
|
"x" : 640,
|
||||||
|
"y" : 0,
|
||||||
|
"number" : 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,12 @@ static int targetOutOfRange(void);
|
||||||
static void moveToPlayer(void);
|
static void moveToPlayer(void);
|
||||||
static int canAttack(Entity *f);
|
static int canAttack(Entity *f);
|
||||||
static int selectWeapon(int type);
|
static int selectWeapon(int type);
|
||||||
|
static void flee(void);
|
||||||
|
|
||||||
void doAI(void)
|
void doAI(void)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!self->target || targetOutOfRange() || self->target->systemPower <= 0)
|
if (!self->target || targetOutOfRange() || self->target->systemPower <= 0)
|
||||||
{
|
{
|
||||||
findTarget();
|
findTarget();
|
||||||
|
@ -60,10 +61,11 @@ void doAI(void)
|
||||||
{
|
{
|
||||||
moveToPlayer();
|
moveToPlayer();
|
||||||
}
|
}
|
||||||
else
|
else if (!(self->flags & EF_FLEEING))
|
||||||
{
|
{
|
||||||
applyFighterBrakes();
|
applyFighterBrakes();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,6 +102,17 @@ void doAI(void)
|
||||||
self->action = huntAndAttackTarget;
|
self->action = huntAndAttackTarget;
|
||||||
self->aiActionTime = FPS * 1;
|
self->aiActionTime = FPS * 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player != NULL && battle.numEnemies <= 2 && self->flags & EF_FLEES)
|
||||||
|
{
|
||||||
|
self->action = flee;
|
||||||
|
self->aiActionTime = FPS * 3;
|
||||||
|
if (!(self->flags & EF_FLEEING) && (self->flags & EF_MISSION_TARGET) && self->side != player->side)
|
||||||
|
{
|
||||||
|
addHudMessage(colors.cyan, "Mission target is escaping!");
|
||||||
|
self->flags |= EF_FLEEING;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int targetOutOfRange(void)
|
static int targetOutOfRange(void)
|
||||||
|
@ -308,6 +321,27 @@ static void dodge(void)
|
||||||
nextAction();
|
nextAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flee(void)
|
||||||
|
{
|
||||||
|
int dir;
|
||||||
|
int wantedAngle = 180 + getAngle(self->x, self->y, player->x, player->y);
|
||||||
|
|
||||||
|
wantedAngle %= 360;
|
||||||
|
|
||||||
|
if (fabs(wantedAngle - self->angle) > TURN_THRESHOLD)
|
||||||
|
{
|
||||||
|
dir = ((int)(wantedAngle - self->angle + 360)) % 360 > 180 ? -1 : 1;
|
||||||
|
|
||||||
|
self->angle += dir * TURN_SPEED;
|
||||||
|
|
||||||
|
self->angle = mod(self->angle, 360);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyFighterThrust();
|
||||||
|
|
||||||
|
nextAction();
|
||||||
|
}
|
||||||
|
|
||||||
static void nextAction(void)
|
static void nextAction(void)
|
||||||
{
|
{
|
||||||
if (--self->aiActionTime <= 0)
|
if (--self->aiActionTime <= 0)
|
||||||
|
|
|
@ -32,7 +32,9 @@ extern void fireGuns(Entity *owner);
|
||||||
extern float getAngle(int x1, int y1, int x2, int y2);
|
extern float getAngle(int x1, int y1, int x2, int y2);
|
||||||
extern void applyFighterThrust(void);
|
extern void applyFighterThrust(void);
|
||||||
extern void applyFighterBrakes(void);
|
extern void applyFighterBrakes(void);
|
||||||
|
extern void addHudMessage(SDL_Color c, char *format, ...);
|
||||||
|
|
||||||
extern Battle battle;
|
extern Battle battle;
|
||||||
|
extern Colors colors;
|
||||||
extern Entity *self;
|
extern Entity *self;
|
||||||
extern Entity *player;
|
extern Entity *player;
|
||||||
|
|
|
@ -38,11 +38,12 @@ Entity *spawnEntity(void)
|
||||||
|
|
||||||
void doEntities(void)
|
void doEntities(void)
|
||||||
{
|
{
|
||||||
|
int numAllies, numEnemies;
|
||||||
Entity *e, *prev;
|
Entity *e, *prev;
|
||||||
|
|
||||||
prev = &battle.entityHead;
|
prev = &battle.entityHead;
|
||||||
|
|
||||||
battle.numAllies = battle.numEnemies = 0;
|
numAllies = numEnemies = 0;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +57,9 @@ void doEntities(void)
|
||||||
if (e->active)
|
if (e->active)
|
||||||
{
|
{
|
||||||
self = e;
|
self = e;
|
||||||
|
|
||||||
|
e->x += e->dx;
|
||||||
|
e->y += e->dy;
|
||||||
|
|
||||||
if (e->target != NULL && e->target->health <= 0)
|
if (e->target != NULL && e->target->health <= 0)
|
||||||
{
|
{
|
||||||
|
@ -63,9 +67,6 @@ void doEntities(void)
|
||||||
e->target = NULL;
|
e->target = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->x += e->dx;
|
|
||||||
e->y += e->dy;
|
|
||||||
|
|
||||||
if (e->action != NULL)
|
if (e->action != NULL)
|
||||||
{
|
{
|
||||||
if (--e->thinkTime <= 0)
|
if (--e->thinkTime <= 0)
|
||||||
|
@ -79,6 +80,19 @@ void doEntities(void)
|
||||||
{
|
{
|
||||||
case ET_FIGHTER:
|
case ET_FIGHTER:
|
||||||
doFighter();
|
doFighter();
|
||||||
|
|
||||||
|
if (player != NULL)
|
||||||
|
{
|
||||||
|
if (self->side == player->side)
|
||||||
|
{
|
||||||
|
numAllies++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numEnemies++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -111,6 +125,9 @@ void doEntities(void)
|
||||||
|
|
||||||
prev = e;
|
prev = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
battle.numAllies = numAllies;
|
||||||
|
battle.numEnemies = numEnemies;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doEntity(void)
|
static void doEntity(void)
|
||||||
|
|
|
@ -27,6 +27,7 @@ static void spinDie(void);
|
||||||
static void straightDie(void);
|
static void straightDie(void);
|
||||||
static void randomizeDart(Entity *dart);
|
static void randomizeDart(Entity *dart);
|
||||||
static void randomizeDartGuns(Entity *dart);
|
static void randomizeDartGuns(Entity *dart);
|
||||||
|
static void checkHasFled(void);
|
||||||
|
|
||||||
Entity *spawnFighter(char *name, int x, int y, int side)
|
Entity *spawnFighter(char *name, int x, int y, int side)
|
||||||
{
|
{
|
||||||
|
@ -152,18 +153,6 @@ static void randomizeDartGuns(Entity *dart)
|
||||||
|
|
||||||
void doFighter(void)
|
void doFighter(void)
|
||||||
{
|
{
|
||||||
if (player != NULL)
|
|
||||||
{
|
|
||||||
if (self->side == player->side)
|
|
||||||
{
|
|
||||||
battle.numAllies++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
battle.numEnemies++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self != player && self->health > 0)
|
if (self != player && self->health > 0)
|
||||||
{
|
{
|
||||||
separate();
|
separate();
|
||||||
|
@ -221,6 +210,13 @@ void doFighter(void)
|
||||||
battle.stats[STAT_DISABLED]++;
|
battle.stats[STAT_DISABLED]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (player != NULL && self->flags & EF_FLEEING && battle.stats[STAT_TIME] % FPS == 0)
|
||||||
|
{
|
||||||
|
checkHasFled();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->alive == ALIVE_DEAD)
|
if (self->alive == ALIVE_DEAD)
|
||||||
|
@ -481,3 +477,25 @@ static void straightDie(void)
|
||||||
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void checkHasFled(void)
|
||||||
|
{
|
||||||
|
long distance = getDistance(self->x, self->y, player->x, player->y);
|
||||||
|
|
||||||
|
if (distance > 5000)
|
||||||
|
{
|
||||||
|
if (self->side != player->side)
|
||||||
|
{
|
||||||
|
addHudMessage(colors.red, "Mission target has escaped.");
|
||||||
|
battle.stats[STAT_ENEMIES_ESCAPED]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
battle.stats[STAT_ALLIES_ESCAPED]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTrigger("ESCAPE", TRIGGER_ESCAPES);
|
||||||
|
|
||||||
|
self->alive = ALIVE_DEAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ static int conditionMet(Trigger *trigger)
|
||||||
|
|
||||||
case TRIGGER_WAYPOINT:
|
case TRIGGER_WAYPOINT:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case TRIGGER_ESCAPES:
|
||||||
|
return trigger->targetValue == battle.stats[STAT_ENEMIES_ESCAPED];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -56,6 +56,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define EF_DISABLE (2 << 1)
|
#define EF_DISABLE (2 << 1)
|
||||||
#define EF_IMMORTAL (2 << 2)
|
#define EF_IMMORTAL (2 << 2)
|
||||||
#define EF_MISSION_TARGET (2 << 3)
|
#define EF_MISSION_TARGET (2 << 3)
|
||||||
|
#define EF_FLEES (2 << 4)
|
||||||
|
#define EF_FLEEING (2 << 5)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -154,7 +156,8 @@ enum
|
||||||
{
|
{
|
||||||
TRIGGER_TIME,
|
TRIGGER_TIME,
|
||||||
TRIGGER_KILLS,
|
TRIGGER_KILLS,
|
||||||
TRIGGER_WAYPOINT
|
TRIGGER_WAYPOINT,
|
||||||
|
TRIGGER_ESCAPES
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -206,6 +209,8 @@ enum
|
||||||
STAT_ALLIES_KILLED,
|
STAT_ALLIES_KILLED,
|
||||||
STAT_PLAYER_KILLED,
|
STAT_PLAYER_KILLED,
|
||||||
STAT_DISABLED,
|
STAT_DISABLED,
|
||||||
|
STAT_ENEMIES_ESCAPED,
|
||||||
|
STAT_ALLIES_ESCAPED,
|
||||||
STAT_TIME,
|
STAT_TIME,
|
||||||
STAT_MAX
|
STAT_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,8 @@ static char *statDescription[] = {
|
||||||
"Allies Killed",
|
"Allies Killed",
|
||||||
"Times Killed",
|
"Times Killed",
|
||||||
"Enemies Disabled",
|
"Enemies Disabled",
|
||||||
|
"Enemies Escaped",
|
||||||
|
"Allies Escaped",
|
||||||
"STAT_TIME"
|
"STAT_TIME"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ void initLookups(void)
|
||||||
addLookup("EF_DISABLE", EF_DISABLE);
|
addLookup("EF_DISABLE", EF_DISABLE);
|
||||||
addLookup("EF_IMMORTAL", EF_IMMORTAL);
|
addLookup("EF_IMMORTAL", EF_IMMORTAL);
|
||||||
addLookup("EF_MISSION_TARGET", EF_MISSION_TARGET);
|
addLookup("EF_MISSION_TARGET", EF_MISSION_TARGET);
|
||||||
|
addLookup("EF_FLEES", EF_FLEES);
|
||||||
|
|
||||||
addLookup("TT_DESTROY", TT_DESTROY);
|
addLookup("TT_DESTROY", TT_DESTROY);
|
||||||
addLookup("TT_DISABLE", TT_DISABLE);
|
addLookup("TT_DISABLE", TT_DISABLE);
|
||||||
|
|
Loading…
Reference in New Issue