From 0c88500690e58fe02957c4a806b7bd12de9e1e74 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 22 Feb 2016 12:47:30 +0000 Subject: [PATCH] Start of avoidance code for capital ships. --- src/battle/capitalShips.c | 96 +++++++++++++++++++++++---------------- src/battle/capitalShips.h | 2 + src/battle/fighters.c | 3 +- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/battle/capitalShips.c b/src/battle/capitalShips.c index d38633e..1d84ff3 100644 --- a/src/battle/capitalShips.c +++ b/src/battle/capitalShips.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "capitalShips.h" -static void separate(void); +static int steer(void); static void think(void); static void gunThink(void); static void gunDie(void); @@ -32,6 +32,7 @@ static void loadCapitalShipDef(char *filename); static void loadComponents(Entity *parent, cJSON *components); static void loadGuns(Entity *parent, cJSON *guns); static void loadEngines(Entity *parent, cJSON *engines); +static Entity *findClosestCapitalShip(PointF ahead, PointF ahead2); static Entity defHead, *defTail; @@ -80,8 +81,6 @@ void doCapitalShip(void) { if (self->alive == ALIVE_ALIVE) { - separate(); - if (self->health <= 0) { self->health = 0; @@ -115,9 +114,7 @@ static void think(void) findAITarget(); } - wantedAngle = getAngle(self->x, self->y, self->targetLocation.x, self->targetLocation.y); - - wantedAngle %= 360; + wantedAngle = steer(); if (fabs(wantedAngle - self->angle) > TURN_THRESHOLD) { @@ -171,51 +168,71 @@ static void findAITarget(void) } } -static void separate(void) +static int steer(void) { - int angle; - int distance; - float dx, dy, force; - int count; - Entity *e, **candidates; - int i; + int wantedAngle; + Entity *other; + PointF ahead, ahead2, avoid; + float length; - dx = dy = 0; - count = 0; - force = 0; + ahead.x = self->x + (self->dx * self->h); + ahead.y = self->y + (self->dy * self->w); - candidates = getAllEntsWithin(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, self); + ahead2.x = self->x + (self->dx * self->h * 0.5); + ahead2.y = self->y + (self->dy * self->w * 0.5); + + other = findClosestCapitalShip(ahead, ahead2); + + if (other != NULL) + { + avoid.x = ahead.x - other->x; + avoid.y = ahead.y - other->y; + + length = sqrt(avoid.x * avoid.x + avoid.y * avoid.y); + avoid.x /= length; + avoid.y /= length; + + avoid.x *= AVOID_FORCE; + avoid.y *= AVOID_FORCE; + + avoid.x += self->x; + avoid.y += self->y; + + wantedAngle = getAngle(self->x, self->y, avoid.x, avoid.y); + } + else + { + wantedAngle = getAngle(self->x, self->y, self->targetLocation.x, self->targetLocation.y); + } + + wantedAngle %= 360; + + return wantedAngle; +} + +static Entity *findClosestCapitalShip(PointF ahead, PointF ahead2) +{ + int i, collision; + Entity *e, **candidates, *closest; + + closest = NULL; + + candidates = getAllEntsWithin(self->x - 1000, self->y - 1000, 2000, 2000, self); for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { - if (e->type == ET_CAPITAL_SHIP) + if (e->active && e->type == ET_CAPITAL_SHIP) { - distance = getDistance(e->x, e->y, self->x, self->y); + collision = getDistance(ahead.x, ahead.y, e->x, e->y) < e->separationRadius || getDistance(ahead2.x, ahead2.y, e->x, e->y) < e->separationRadius; - if (distance > 0 && distance < self->separationRadius) + if (collision && (!closest || getDistance(self->x, self->y, closest->x, closest->y) < getDistance(self->x, self->y, e->x, e->y))) { - angle = getAngle(self->x, self->y, e->x, e->y); - - dx += sin(TO_RAIDANS(angle)); - dy += -cos(TO_RAIDANS(angle)); - force += (self->separationRadius - distance) * 0.005; - - count++; + closest = e; } } } - if (count > 0) - { - dx /= count; - dy /= count; - - dx *= force; - dy *= force; - - self->dx -= dx; - self->dy -= dy; - } + return closest; } static void gunThink(void) @@ -351,9 +368,8 @@ static void loadCapitalShipDef(char *filename) e->die = die; SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); - e->separationRadius = MAX(e->w, e->h); - SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); + e->separationRadius = MAX(e->w, e->h) * 0.75; loadComponents(e, cJSON_GetObjectItem(root, "components")); diff --git a/src/battle/capitalShips.h b/src/battle/capitalShips.h index 83f7045..d9a91e7 100644 --- a/src/battle/capitalShips.h +++ b/src/battle/capitalShips.h @@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TURN_SPEED 0.1 #define TURN_THRESHOLD 2 +#define AVOID_FORCE 500 + #include "../common.h" #include "../json/cJSON.h" diff --git a/src/battle/fighters.c b/src/battle/fighters.c index 4e4fd48..724e36e 100644 --- a/src/battle/fighters.c +++ b/src/battle/fighters.c @@ -712,8 +712,7 @@ static void loadFighterDef(char *filename) e->deathType = lookup(cJSON_GetObjectItem(root, "deathType")->valuestring); } - e->separationRadius = MAX(e->w, e->h); - e->separationRadius *= 3; + e->separationRadius = MAX(e->w, e->h) * 3; /* all craft default to 100 system power */ e->systemPower = 100;