diff --git a/data/capitalShips/test.json b/data/capitalShips/test.json index c3a5403..6ef3755 100644 --- a/data/capitalShips/test.json +++ b/data/capitalShips/test.json @@ -1,46 +1,106 @@ { "name" : "Test Frigate", - "health" : 1, + "health" : 0, "shield" : 500, "shieldRechargeRate" : 60, "texture" : "gfx/capitalShips/test/body.png", "components" : [ { - "health" : 100, + "health" : 350, "texture" : "gfx/capitalShips/test/core.png", "x" : 0, - "y" : -100, - "flags" : "EF_TAKES_DAMAGE" + "y" : -125, + "flags" : "EF_TAKES_DAMAGE+EF_STATIC" }, { - "health" : 100, + "health" : 200, "texture" : "gfx/capitalShips/test/engine1.png", "x" : -112, "y" : 281, - "flags" : "EF_TAKES_DAMAGE" + "flags" : "EF_TAKES_DAMAGE+EF_STATIC" }, { - "health" : 100, + "health" : 200, "texture" : "gfx/capitalShips/test/engine1.png", "x" : 112, "y" : 281, - "flags" : "EF_TAKES_DAMAGE" + "flags" : "EF_TAKES_DAMAGE+EF_STATIC" }, { - "health" : 100, + "health" : 200, "texture" : "gfx/capitalShips/test/engine2.png", "x" : -34, "y" : 268, - "flags" : "EF_TAKES_DAMAGE" + "flags" : "EF_TAKES_DAMAGE+EF_STATIC" }, { - "health" : 100, + "health" : 200, "texture" : "gfx/capitalShips/test/engine2.png", "x" : 34, "y" : 268, - "flags" : "EF_TAKES_DAMAGE" + "flags" : "EF_TAKES_DAMAGE+EF_STATIC" } ], "guns" : [ + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : -110, + "y" : 20, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + }, + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : -110, + "y" : 100, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + }, + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : -110, + "y" : 180, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + }, + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : 110, + "y" : 20, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + }, + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : 110, + "y" : 100, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + }, + { + "health" : 100, + "texture" : "gfx/cannons/rocketTurret.png", + "x" : 110, + "y" : 180, + "reloadTime" : 10, + "type" : "BT_PARTICLE", + "flags" : "EF_TAKES_DAMAGE+EF_STATIC", + "aiFlags" : "AIF_AGGRESSIVE+AIF_LONG_RANGE_FIRE" + } ] } diff --git a/data/fighters/rocketTurret.json b/data/fighters/rocketTurret.json index 48ecb08..7e1d649 100644 --- a/data/fighters/rocketTurret.json +++ b/data/fighters/rocketTurret.json @@ -14,5 +14,5 @@ } ], "flags" : "EF_STATIC+EF_TAKES_DAMAGE", - "aiFlags" : "AIF_MISSILE_BOAT+AIF_AGGRESSIVE+AIF_INSTANT_DIE" + "aiFlags" : "AIF_MISSILE_BOAT+AIF_AGGRESSIVE+AIF_INSTANT_DIE+AIF_LONG_RANGE_FIRE" } diff --git a/src/battle/ai.c b/src/battle/ai.c index 93a3eb0..41e81a1 100644 --- a/src/battle/ai.c +++ b/src/battle/ai.c @@ -190,10 +190,11 @@ static void huntTarget(void) static void huntAndAttackTarget(void) { int dist = getDistance(self->x, self->y, self->target->x, self->target->y); + int range = self->aiFlags & AIF_LONG_RANGE_FIRE ? 1250 : 625; faceTarget(self->target); - if (dist <= 500 && hasClearShot()) + if (dist <= range && hasClearShot()) { preAttack(); } @@ -224,7 +225,7 @@ static void findTarget(void) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { - if (e->active && e->type == ET_FIGHTER && (!(e->flags & EF_DISABLED)) && e->side != self->side && e->health > 0 && canAttack(e)) + if (e->active && (e->flags & EF_TAKES_DAMAGE) && (!(e->flags & EF_DISABLED)) && e->side != self->side && e->health > 0 && canAttack(e)) { dist = getDistance(self->x, self->y, e->x, e->y); @@ -316,17 +317,17 @@ static int isInFOV(Entity *f, int fov) static int hasClearShot(void) { int dist; - Entity *f; + Entity *e; if (isInFOV(self->target, 4)) { dist = getDistance(self->x, self->y, self->target->x, self->target->y); - for (f = battle.entityHead.next ; f != NULL ; f = f->next) + for (e = battle.entityHead.next ; e != NULL ; e = e->next) { - if (f->active && f != self && f != self->target && (getDistance(self->x, self->y, f->x, f->y) < dist)) + if (e->active && e != self && e != self->owner && e != self->target && (getDistance(self->x, self->y, e->x, e->y) < dist)) { - if (isInFOV(f, 8)) + if (isInFOV(e, 8)) { return 0; } @@ -460,7 +461,7 @@ static int nearEnemies(void) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { - if (e->type == ET_FIGHTER && e->side != self->side && !(e->flags & EF_DISABLED)) + if ((e->flags & EF_TAKES_DAMAGE) && e->side != self->side && !(e->flags & EF_DISABLED)) { self->targetLocation.x += e->x; self->targetLocation.y += e->y; @@ -597,7 +598,7 @@ static int nearTowableCraft(void) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { - if (e->type == ET_FIGHTER && (e->flags & (EF_DISABLED|EF_MISSION_TARGET)) == (EF_DISABLED|EF_MISSION_TARGET)) + if ((e->flags & (EF_DISABLED|EF_MISSION_TARGET)) == (EF_DISABLED|EF_MISSION_TARGET)) { distance = getDistance(self->x, self->y, e->x, e->y); diff --git a/src/battle/capitalShips.c b/src/battle/capitalShips.c index 9de5047..8d93d95 100644 --- a/src/battle/capitalShips.c +++ b/src/battle/capitalShips.c @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "capitalShips.h" +static void think(void); +static void gunThink(void); static void componentDie(void); static void loadCapitalShipDef(char *filename); static void loadComponents(Entity *parent, cJSON *components); @@ -60,6 +62,16 @@ Entity *spawnCapitalShip(char *name, int x, int y, int side) return capitalShip; } +static void think(void) +{ + +} + +static void gunThink(void) +{ + doAI(); +} + static void componentDie(void) { self->alive = ALIVE_DEAD; @@ -121,6 +133,7 @@ static void loadCapitalShipDef(char *filename) e->shieldRechargeRate = cJSON_GetObjectItem(root, "shieldRechargeRate")->valueint; e->texture = getTexture(cJSON_GetObjectItem(root, "texture")->valuestring); + e->action = think; e->die = die; SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); @@ -163,6 +176,11 @@ static void loadComponents(Entity *parent, cJSON *components) SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); + if (cJSON_GetObjectItem(component, "aiFlags")) + { + e->aiFlags = flagsToLong(cJSON_GetObjectItem(component, "aiFlags")->valuestring); + } + if (cJSON_GetObjectItem(component, "flags")) { e->flags = flagsToLong(cJSON_GetObjectItem(component, "flags")->valuestring); @@ -179,6 +197,54 @@ static void loadComponents(Entity *parent, cJSON *components) static void loadGuns(Entity *parent, cJSON *guns) { + Entity *e; + cJSON *gun; + + parent->health = 0; + + if (guns) + { + gun = guns->child; + + while (gun) + { + e = malloc(sizeof(Entity)); + memset(e, 0, sizeof(Entity)); + defTail->next = e; + defTail = e; + + e->active = 1; + + e->type = ET_CAPITAL_SHIP_GUN; + STRNCPY(e->name, parent->name, MAX_NAME_LENGTH); + STRNCPY(e->defName, parent->defName, MAX_NAME_LENGTH); + e->health = e->maxHealth = cJSON_GetObjectItem(gun, "health")->valueint; + e->reloadTime = cJSON_GetObjectItem(gun, "reloadTime")->valueint; + e->offsetX = cJSON_GetObjectItem(gun, "x")->valueint; + e->offsetY = cJSON_GetObjectItem(gun, "y")->valueint; + e->texture = getTexture(cJSON_GetObjectItem(gun, "texture")->valuestring); + e->guns[0].type = lookup(cJSON_GetObjectItem(gun, "type")->valuestring); + + if (cJSON_GetObjectItem(gun, "aiFlags")) + { + e->aiFlags = flagsToLong(cJSON_GetObjectItem(gun, "aiFlags")->valuestring); + } + + if (cJSON_GetObjectItem(gun, "flags")) + { + e->flags = flagsToLong(cJSON_GetObjectItem(gun, "flags")->valuestring); + } + + SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); + + e->action = gunThink; + e->die = componentDie; + + gun = gun->next; + + parent->health++; + } + } } void destroyCapitalShipDefs(void) diff --git a/src/battle/capitalShips.h b/src/battle/capitalShips.h index 5b0c4b5..c27497a 100644 --- a/src/battle/capitalShips.h +++ b/src/battle/capitalShips.h @@ -29,6 +29,8 @@ extern SDL_Texture *getTexture(char *filename); extern char *readFile(char *filename); extern char *getFileLocation(char *filename); extern long flagsToLong(char *flags); +extern long lookup(char *name); +extern void doAI(void); extern Battle battle; extern Entity *self; diff --git a/src/battle/entities.c b/src/battle/entities.c index daa133e..9feacf4 100644 --- a/src/battle/entities.c +++ b/src/battle/entities.c @@ -54,6 +54,14 @@ void doEntities(void) destroyGrid(); + for (e = battle.entityHead.next ; e != NULL ; e = e->next) + { + if (e->active) + { + addToGrid(e); + } + } + for (e = battle.entityHead.next ; e != NULL ; e = e->next) { if (e->active) @@ -111,8 +119,6 @@ void doEntities(void) e->x += e->dx; e->y += e->dy; - - addToGrid(e); } else { @@ -264,6 +270,11 @@ static void alignComponents(void) e->x = x; e->y = y; + if (e->type == ET_CAPITAL_SHIP_COMPONENT) + { + e->angle = e->owner->angle; + } + if (e->owner->alive == ALIVE_DYING) { e->alive = ALIVE_DEAD; diff --git a/src/battle/fighters.c b/src/battle/fighters.c index 1aeb6fc..64720fc 100644 --- a/src/battle/fighters.c +++ b/src/battle/fighters.c @@ -326,7 +326,7 @@ static void separate(void) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { - if (e->type == ET_FIGHTER) + if (e->flags & EF_TAKES_DAMAGE) { distance = getDistance(e->x, e->y, self->x, self->y); diff --git a/src/battle/rope.c b/src/battle/rope.c index 7cfed29..7739624 100644 --- a/src/battle/rope.c +++ b/src/battle/rope.c @@ -83,13 +83,13 @@ void doRope(Entity *owner) } } -void drawRope(Entity *owner) +void drawRope(Entity *e) { - if (owner->towing) + if (e->towing) { SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, SDL_ALPHA_OPAQUE); - SDL_RenderDrawLine(app.renderer, owner->x - battle.camera.x, owner->y - battle.camera.y, owner->towing->x - battle.camera.x, owner->towing->y - battle.camera.y); + SDL_RenderDrawLine(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y, e->towing->x - battle.camera.x, e->towing->y - battle.camera.y); } } diff --git a/src/defs.h b/src/defs.h index fb270a9..0e2874f 100644 --- a/src/defs.h +++ b/src/defs.h @@ -95,6 +95,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define AIF_MISSILE_BOAT (2 << 9) #define AIF_AGGRESSIVE (2 << 10) #define AIF_INSTANT_DIE (2 << 11) +#define AIF_LONG_RANGE_FIRE (2 << 12) /* player abilities */ #define BOOST_RECHARGE_TIME (FPS * 7) diff --git a/src/system/lookup.c b/src/system/lookup.c index 20e5435..45addf0 100644 --- a/src/system/lookup.c +++ b/src/system/lookup.c @@ -59,6 +59,7 @@ void initLookups(void) addLookup("AIF_MISSILE_BOAT", AIF_MISSILE_BOAT); addLookup("AIF_AGGRESSIVE", AIF_AGGRESSIVE); addLookup("AIF_INSTANT_DIE", AIF_INSTANT_DIE); + addLookup("AIF_LONG_RANGE_FIRE", AIF_LONG_RANGE_FIRE); addLookup("TT_DESTROY", TT_DESTROY); addLookup("TT_DISABLE", TT_DISABLE);