Updates to Mission Target logic. Tidying up of entity.c

This commit is contained in:
Steve 2015-10-27 07:24:17 +00:00
parent 705a2cebe9
commit 49832b114b
12 changed files with 256 additions and 118 deletions

View File

@ -8,12 +8,23 @@
"type" : "Nymph", "type" : "Nymph",
"side" : "SIDE_CSN" "side" : "SIDE_CSN"
}, },
"entities" : [ "fighters" : [
{
"name" : "Dart",
"type" : "Dart",
"side" : "SIDE_CSN",
"x" : 1800,
"y" : 200
}
],
"entitiesGroups" : [
{ {
"name" : "Waypoint", "name" : "Waypoint",
"type" : "ET_WAYPOINT", "type" : "ET_WAYPOINT",
"x" : 100, "number" : 10,
"y" : 100 "x" : 640,
"y" : -10000,
"scatter" : 10000
} }
] ]
} }

View File

@ -150,7 +150,7 @@ static void findTarget(void)
for (f = battle.entityHead.next ; f != NULL ; f = f->next) for (f = battle.entityHead.next ; f != NULL ; f = f->next)
{ {
if (f->side != self->side && f->health > 0 && canAttack(f)) if (f->type == ET_FIGHTER && f->side != self->side && f->health > 0 && canAttack(f))
{ {
dist = getDistance(self->x, self->y, f->x, f->y); dist = getDistance(self->x, self->y, f->x, f->y);
if (dist < closest) if (dist < closest)

View File

@ -21,7 +21,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "entities.h" #include "entities.h"
static void drawEntity(Entity *e); static void drawEntity(Entity *e);
static void doEntity(Entity *e, Entity *prev); static void doEntity(Entity *prev);
Entity *spawnEntity(void)
{
Entity *e = malloc(sizeof(Entity));
memset(e, 0, sizeof(Entity));
e->id = battle.entId++;
battle.entityTail->next = e;
battle.entityTail = e;
return e;
}
void doEntities(void) void doEntities(void)
{ {
@ -35,48 +47,63 @@ void doEntities(void)
{ {
self = e; self = e;
if (self->target != NULL && self->target->health <= 0)
{
self->action = self->defaultAction;
self->target = NULL;
}
self->x += self->dx;
self->y += self->dy;
if (self != player)
{
self->x -= battle.ssx;
self->y -= battle.ssy;
}
if (self->action != NULL)
{
if (--self->thinkTime <= 0)
{
self->thinkTime = 0;
self->action();
}
}
switch (e->type) switch (e->type)
{ {
case ET_FIGHTER: case ET_FIGHTER:
doFighter(e, prev); doFighter(prev);
break; break;
default: default:
doEntity(e, prev); doEntity(prev);
break; break;
} }
prev = self;
} }
} }
static void doEntity(Entity *e, Entity *prev) static void doEntity(Entity *prev)
{ {
e->x += e->dx; if (self->health <= 0)
e->y += e->dy;
e->x -= battle.ssx;
e->y -= battle.ssy;
if (e->action != NULL)
{ {
if (--e->thinkTime <= 0) if (self == battle.entityTail)
{
e->action();
}
}
if (e->health <= 0)
{
if (e == battle.entityTail)
{ {
battle.entityTail = prev; battle.entityTail = prev;
} }
prev->next = e->next; if (self == battle.missionTarget)
free(e); {
e = prev; battle.missionTarget = NULL;
} }
prev = e; prev->next = self->next;
free(self);
self = prev;
}
} }
void drawEntities(void) void drawEntities(void)

View File

@ -25,7 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern void blitRotated(SDL_Texture *t, int x, int y, int angle); extern void blitRotated(SDL_Texture *t, int x, int y, int angle);
extern void drawFighter(Entity *e); extern void drawFighter(Entity *e);
extern void doFighter(Entity *e, Entity *prev); extern void doFighter(Entity *prev);
extern Battle battle; extern Battle battle;
extern Entity *self; extern Entity *self;
extern Entity *player;

View File

@ -32,18 +32,15 @@ Entity *spawnFighter(char *name, int x, int y, int side)
{ {
Entity *f, *def; Entity *f, *def;
f = malloc(sizeof(Entity)); f = spawnEntity();
memset(f, 0, sizeof(Entity));
def = getFighterDef(name); def = getFighterDef(name);
memcpy(f, def, sizeof(Entity)); memcpy(f, def, sizeof(Entity));
f->id = battle.entId;
f->next = NULL; f->next = NULL;
battle.entityTail->next = f;
battle.entityTail = f;
f->x = x; f->x = x;
f->y = y; f->y = y;
f->side = side; f->side = side;
@ -153,16 +150,11 @@ static void randomizeDartGuns(Entity *dart)
} }
} }
void doFighter(Entity *f, Entity *prev) void doFighter(Entity *prev)
{ {
if (player != NULL) if (player != NULL)
{ {
if (f != player && f->health > 0) if (self->side == player->side)
{
separate();
}
if (f->side == player->side)
{ {
battle.numAllies++; battle.numAllies++;
} }
@ -172,92 +164,68 @@ void doFighter(Entity *f, Entity *prev)
} }
} }
if (self->target != NULL && self->target->health <= 0) if (self != player && self->health > 0)
{ {
self->action = self->defaultAction; separate();
self->target = NULL;
} }
if (!battle.missionTarget && f->flags & EF_MISSION_TARGET && f->health > 0) if (self->health > 0)
{ {
battle.missionTarget = f; self->reload = MAX(self->reload - 1, 0);
} self->shieldRecharge = MAX(self->shieldRecharge - 1, 0);
self->armourHit = MAX(self->armourHit - 25, 0);
f->x += f->dx; self->shieldHit = MAX(self->shieldHit - 5, 0);
f->y += f->dy; self->systemHit = MAX(self->systemHit - 25, 0);
if (f != player)
{
f->x -= battle.ssx;
f->y -= battle.ssy;
}
if (f->health > 0)
{
f->reload = MAX(f->reload - 1, 0);
f->shieldRecharge = MAX(f->shieldRecharge - 1, 0);
f->armourHit = MAX(f->armourHit - 25, 0);
f->shieldHit = MAX(f->shieldHit - 5, 0);
f->systemHit = MAX(f->systemHit - 25, 0);
if (self->thrust > 0.25) if (self->thrust > 0.25)
{ {
addEngineEffect(); addEngineEffect();
} }
if (!f->shieldRecharge) if (!self->shieldRecharge)
{ {
f->shield = MIN(f->shield + 1, f->maxShield); self->shield = MIN(self->shield + 1, self->maxShield);
f->shieldRecharge = f->shieldRechargeRate; self->shieldRecharge = self->shieldRechargeRate;
} }
if (f->action == NULL && f->defaultAction != NULL) if (self->action == NULL && self->defaultAction != NULL)
{ {
f->action = f->defaultAction; self->action = self->defaultAction;
} }
} }
if (f->action != NULL) if (self->alive == ALIVE_ALIVE)
{ {
if (--f->thinkTime <= 0) if (self->health <= 0)
{ {
f->thinkTime = 0; self->health = 0;
f->action(); self->alive = ALIVE_DYING;
} self->die();
}
if (f->alive == ALIVE_ALIVE) if (self == battle.missionTarget)
{
if (f->health <= 0)
{
f->health = 0;
f->alive = ALIVE_DYING;
f->die();
if (f == battle.missionTarget)
{ {
battle.missionTarget = NULL; battle.missionTarget = NULL;
} }
} }
else if (f->systemPower <= 0) else if (self->systemPower <= 0)
{ {
f->dx *= 0.99; self->dx *= 0.99;
f->dy *= 0.99; self->dy *= 0.99;
f->thrust = 0; self->thrust = 0;
f->shield = f->maxShield = 0; self->shield = self->maxShield = 0;
f->action = NULL; self->action = NULL;
if (f->alive == ALIVE_ALIVE) if (self->alive == ALIVE_ALIVE)
{ {
updateObjective(f->name, TT_DISABLE); updateObjective(self->name, TT_DISABLE);
battle.stats[STAT_DISABLED]++; battle.stats[STAT_DISABLED]++;
} }
} }
} }
if (f->alive == ALIVE_DEAD) if (self->alive == ALIVE_DEAD)
{ {
if (f == player) if (self == player)
{ {
battle.stats[STAT_PLAYER_KILLED]++; battle.stats[STAT_PLAYER_KILLED]++;
} }
@ -265,7 +233,7 @@ void doFighter(Entity *f, Entity *prev)
{ {
if (player->alive == ALIVE_ALIVE) if (player->alive == ALIVE_ALIVE)
{ {
if (f->side != player->side) if (self->side != player->side)
{ {
battle.stats[STAT_ENEMIES_KILLED]++; battle.stats[STAT_ENEMIES_KILLED]++;
} }
@ -277,26 +245,26 @@ void doFighter(Entity *f, Entity *prev)
} }
} }
updateObjective(f->name, TT_DESTROY); updateObjective(self->name, TT_DESTROY);
updateCondition(f->name, TT_DESTROY); updateCondition(self->name, TT_DESTROY);
checkTrigger(f->name, TRIGGER_KILLS); checkTrigger(self->name, TRIGGER_KILLS);
} }
if (f == battle.entityTail) if (self == battle.entityTail)
{ {
battle.entityTail = prev; battle.entityTail = prev;
} }
if (f == player) if (self == player)
{ {
player = NULL; player = NULL;
} }
prev->next = f->next; prev->next = self->next;
free(f); free(self);
f = prev; self = prev;
} }
} }

View File

@ -38,6 +38,7 @@ extern void updateCondition(char *name, int type);
extern Entity *getFighterDef(char *name); extern Entity *getFighterDef(char *name);
extern void addHudMessage(SDL_Color c, char *format, ...); extern void addHudMessage(SDL_Color c, char *format, ...);
extern void checkTrigger(char *name, int type); extern void checkTrigger(char *name, int type);
extern Entity *spawnEntity(void);
extern App app; extern App app;
extern Battle battle; extern Battle battle;

View File

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void selectTarget(void); static void selectTarget(void);
static void switchGuns(void); static void switchGuns(void);
static void selectMissionTarget(void);
static int availableGuns[BT_MAX]; static int availableGuns[BT_MAX];
@ -100,6 +101,11 @@ void doPlayer(void)
{ {
selectTarget(); selectTarget();
} }
if (!battle.missionTarget)
{
selectMissionTarget();
}
} }
player->angle = ((int)player->angle) % 360; player->angle = ((int)player->angle) % 360;
@ -136,20 +142,57 @@ static void selectTarget(void)
{ {
unsigned int closest = 65535; unsigned int closest = 65535;
unsigned int dist = 65535; unsigned int dist = 65535;
Entity *f; Entity *e;
player->target = NULL; player->target = NULL;
for (f = battle.entityHead.next ; f != NULL ; f = f->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
if (f != player && f->side != SIDE_NONE && f->side != player->side && f->alive == ALIVE_ALIVE) if (e != player && e->type == ET_FIGHTER && e->side != player->side && e->alive == ALIVE_ALIVE)
{ {
dist = getDistance(self->x, self->y, f->x, f->y); dist = getDistance(self->x, self->y, e->x, e->y);
if (dist < closest) if (dist < closest)
{ {
player->target = f; player->target = e;
closest = dist; closest = dist;
} }
} }
} }
} }
static void selectMissionTarget(void)
{
unsigned int closest = 65535;
unsigned int dist = 65535;
Entity *e;
battle.missionTarget = NULL;
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{
if (e->flags & EF_MISSION_TARGET && e->alive == ALIVE_ALIVE)
{
if (battle.missionTarget == NULL)
{
battle.missionTarget = e;
}
else if (battle.missionTarget->type == ET_WAYPOINT && e->type != ET_WAYPOINT)
{
battle.missionTarget = e;
}
else if (battle.missionTarget->type != ET_WAYPOINT)
{
dist = getDistance(self->x, self->y, e->x, e->y);
if (dist < closest)
{
battle.missionTarget = e;
closest = dist;
}
}
else if (battle.missionTarget->type == ET_WAYPOINT && e->type == ET_WAYPOINT && e->id < battle.missionTarget->id)
{
battle.missionTarget = e;
}
}
}
}

View File

@ -20,28 +20,54 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "waypoints.h" #include "waypoints.h"
static void rotate(void); static void think(void);
static int teamMatesClose(void);
Entity *spawnWaypoint(void) Entity *spawnWaypoint(void)
{ {
Entity *waypoint = malloc(sizeof(Entity)); Entity *waypoint = spawnEntity();
memset(waypoint, 0, sizeof(Entity));
battle.entityTail->next = waypoint;
battle.entityTail = waypoint;
waypoint->type = ET_WAYPOINT; waypoint->type = ET_WAYPOINT;
waypoint->health = waypoint->maxHealth = FPS; waypoint->health = waypoint->maxHealth = FPS;
waypoint->texture = getTexture("gfx/entities/waypoint.png"); waypoint->texture = getTexture("gfx/entities/waypoint.png");
waypoint->action = rotate; waypoint->flags = EF_MISSION_TARGET;
waypoint->action = think;
return waypoint; return waypoint;
} }
static void rotate(void) static void think(void)
{ {
self->angle += 0.1; self->thinkTime = 4;
self->angle++;
if (self->angle >= 360) if (self->angle >= 360)
{ {
self -= 360; self -= 360;
} }
if (getDistance(player->x, player->y, self->x, self->y) <= 32 && teamMatesClose())
{
self->health = 0;
}
}
static int teamMatesClose(void)
{
Entity *e;
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{
if (e->type == ET_FIGHTER && e->side == player->side)
{
if (getDistance(player->x, player->y, e->x, e->y) > 350)
{
addHudMessage(colors.cyan, "Cannot activate waypoint - team mates too far away");
self->thinkTime = FPS;
return 0;
}
}
}
return 1;
} }

View File

@ -24,6 +24,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../structs.h" #include "../structs.h"
extern SDL_Texture *getTexture(char *filename); extern SDL_Texture *getTexture(char *filename);
extern int getDistance(int x1, int y1, int x2, int y2);
extern void addHudMessage(SDL_Color c, char *format, ...);
extern Entity *spawnEntity(void);
extern Battle battle; extern Battle battle;
extern Colors colors;
extern Entity *self; extern Entity *self;
extern Entity *player;

View File

@ -56,6 +56,7 @@ 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_INVISIBLE (2 << 4)
enum enum
{ {

View File

@ -26,6 +26,7 @@ static void loadPlayer(cJSON *node);
static void loadFighters(cJSON *node); static void loadFighters(cJSON *node);
static void loadFighterGroups(cJSON *node); static void loadFighterGroups(cJSON *node);
static void loadEntities(cJSON *node); static void loadEntities(cJSON *node);
static void loadEntityGroups(cJSON *node);
static unsigned long hashcode(const char *str); static unsigned long hashcode(const char *str);
static char **toFighterTypeArray(char *types, int *numTypes); static char **toFighterTypeArray(char *types, int *numTypes);
@ -61,6 +62,8 @@ void loadMission(char *filename)
loadEntities(cJSON_GetObjectItem(root, "entities")); loadEntities(cJSON_GetObjectItem(root, "entities"));
loadEntityGroups(cJSON_GetObjectItem(root, "entityGroups"));
STRNCPY(music, cJSON_GetObjectItem(root, "music")->valuestring, MAX_NAME_LENGTH); STRNCPY(music, cJSON_GetObjectItem(root, "music")->valuestring, MAX_NAME_LENGTH);
cJSON_Delete(root); cJSON_Delete(root);
@ -283,6 +286,57 @@ static void loadEntities(cJSON *node)
} }
} }
static void loadEntityGroups(cJSON *node)
{
Entity *e;
char *name;
int i, type, x, y, scatter, number;
long flags;
scatter = 1;
flags = 0;
if (node)
{
node = node->child;
while (node)
{
type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
name = cJSON_GetObjectItem(node, "name")->valuestring;
number = cJSON_GetObjectItem(node, "number")->valueint;
x = cJSON_GetObjectItem(node, "x")->valueint;
y = cJSON_GetObjectItem(node, "y")->valueint;
if (cJSON_GetObjectItem(node, "flags"))
{
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring);
}
for (i = 0 ; i < number ; i++)
{
switch (type)
{
case ET_WAYPOINT:
e = spawnWaypoint();
break;
}
STRNCPY(e->name, name, MAX_NAME_LENGTH);
e->id = battle.entId++;
e->x = x;
e->y = y;
e->flags = flags;
e->x += (rand() % scatter) - (rand() % scatter);
e->y += (rand() % scatter) - (rand() % scatter);
}
node = node->next;
}
}
}
static char **toFighterTypeArray(char *types, int *numTypes) static char **toFighterTypeArray(char *types, int *numTypes)
{ {
int i; int i;

View File

@ -71,7 +71,7 @@ struct Weapon {
struct Entity { struct Entity {
int type; int type;
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
int active; int id;
int side; int side;
float x; float x;
float y; float y;
@ -213,6 +213,7 @@ struct StarSystem {
}; };
typedef struct { typedef struct {
int entId;
float ssx; float ssx;
float ssy; float ssy;
int numAllies; int numAllies;