Added getJSONValue to aid with optional JSON data.
This commit is contained in:
parent
b6012a2e21
commit
95cb35d5a1
|
@ -38,24 +38,24 @@ static Entity defHead, *defTail;
|
||||||
Entity *spawnCapitalShip(char *name, int x, int y, int side)
|
Entity *spawnCapitalShip(char *name, int x, int y, int side)
|
||||||
{
|
{
|
||||||
Entity *def, *e, *capitalShip;
|
Entity *def, *e, *capitalShip;
|
||||||
|
|
||||||
capitalShip = NULL;
|
capitalShip = NULL;
|
||||||
|
|
||||||
for (def = defHead.next ; def != NULL ; def = def->next)
|
for (def = defHead.next ; def != NULL ; def = def->next)
|
||||||
{
|
{
|
||||||
if ((strcmp(def->name, name) == 0) || (def->owner != NULL && strcmp(def->owner->name, name) == 0))
|
if ((strcmp(def->name, name) == 0) || (def->owner != NULL && strcmp(def->owner->name, name) == 0))
|
||||||
{
|
{
|
||||||
e = spawnEntity();
|
e = spawnEntity();
|
||||||
|
|
||||||
memcpy(e, def, sizeof(Entity));
|
memcpy(e, def, sizeof(Entity));
|
||||||
|
|
||||||
e->id = battle.entId;
|
e->id = battle.entId;
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
|
|
||||||
e->x = x;
|
e->x = x;
|
||||||
e->y = y;
|
e->y = y;
|
||||||
e->side = side;
|
e->side = side;
|
||||||
|
|
||||||
if (e->type == ET_CAPITAL_SHIP)
|
if (e->type == ET_CAPITAL_SHIP)
|
||||||
{
|
{
|
||||||
capitalShip = e;
|
capitalShip = e;
|
||||||
|
@ -66,13 +66,13 @@ Entity *spawnCapitalShip(char *name, int x, int y, int side)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!capitalShip)
|
if (!capitalShip)
|
||||||
{
|
{
|
||||||
printf("Error: no such capital ship '%s'\n", name);
|
printf("Error: no such capital ship '%s'\n", name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return capitalShip;
|
return capitalShip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +85,12 @@ void doCapitalShip(void)
|
||||||
self->health = 0;
|
self->health = 0;
|
||||||
self->alive = ALIVE_DYING;
|
self->alive = ALIVE_DYING;
|
||||||
self->die();
|
self->die();
|
||||||
|
|
||||||
if (self == battle.missionTarget)
|
if (self == battle.missionTarget)
|
||||||
{
|
{
|
||||||
battle.missionTarget = NULL;
|
battle.missionTarget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->side == SIDE_ALLIES)
|
if (self->side == SIDE_ALLIES)
|
||||||
{
|
{
|
||||||
battle.stats[STAT_CAPITAL_SHIPS_LOST]++;
|
battle.stats[STAT_CAPITAL_SHIPS_LOST]++;
|
||||||
|
@ -107,25 +107,25 @@ static void think(void)
|
||||||
{
|
{
|
||||||
float dir;
|
float dir;
|
||||||
int wantedAngle;
|
int wantedAngle;
|
||||||
|
|
||||||
if (--self->aiActionTime <= 0)
|
if (--self->aiActionTime <= 0)
|
||||||
{
|
{
|
||||||
findAITarget();
|
findAITarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
wantedAngle = steer();
|
wantedAngle = steer();
|
||||||
|
|
||||||
if (fabs(wantedAngle - self->angle) > TURN_THRESHOLD)
|
if (fabs(wantedAngle - self->angle) > TURN_THRESHOLD)
|
||||||
{
|
{
|
||||||
dir = ((int)(wantedAngle - self->angle + 360)) % 360 > 180 ? -1 : 1;
|
dir = ((int)(wantedAngle - self->angle + 360)) % 360 > 180 ? -1 : 1;
|
||||||
|
|
||||||
dir *= TURN_SPEED;
|
dir *= TURN_SPEED;
|
||||||
|
|
||||||
self->angle += dir;
|
self->angle += dir;
|
||||||
|
|
||||||
self->angle = fmod(self->angle, 360);
|
self->angle = fmod(self->angle, 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFighterThrust();
|
applyFighterThrust();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,16 +133,16 @@ static void findAITarget(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
unsigned int dist, closest;
|
unsigned int dist, closest;
|
||||||
|
|
||||||
self->target = NULL;
|
self->target = NULL;
|
||||||
dist = closest = MAX_TARGET_RANGE;
|
dist = closest = MAX_TARGET_RANGE;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->active && e->side != self->side && e->flags & EF_AI_TARGET)
|
if (e->active && e->side != self->side && e->flags & EF_AI_TARGET)
|
||||||
{
|
{
|
||||||
dist = getDistance(self->x, self->y, e->x, e->y);
|
dist = getDistance(self->x, self->y, e->x, e->y);
|
||||||
|
|
||||||
if (!self->target || dist < closest)
|
if (!self->target || dist < closest)
|
||||||
{
|
{
|
||||||
self->target = e;
|
self->target = e;
|
||||||
|
@ -150,19 +150,19 @@ static void findAITarget(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->target)
|
if (self->target)
|
||||||
{
|
{
|
||||||
self->targetLocation.x = self->target->x + (rand() % 1000 - rand() % 1000);
|
self->targetLocation.x = self->target->x + (rand() % 1000 - rand() % 1000);
|
||||||
self->targetLocation.y = self->target->y + (rand() % 1000 - rand() % 1000);
|
self->targetLocation.y = self->target->y + (rand() % 1000 - rand() % 1000);
|
||||||
|
|
||||||
self->aiActionTime = FPS * 15;
|
self->aiActionTime = FPS * 15;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->targetLocation.x = 500 + (rand() % (BATTLE_AREA_WIDTH - 1000));
|
self->targetLocation.x = 500 + (rand() % (BATTLE_AREA_WIDTH - 1000));
|
||||||
self->targetLocation.y = 500 + (rand() % (BATTLE_AREA_HEIGHT - 1000));
|
self->targetLocation.y = 500 + (rand() % (BATTLE_AREA_HEIGHT - 1000));
|
||||||
|
|
||||||
self->aiActionTime = FPS * (30 + (rand() % 120));
|
self->aiActionTime = FPS * (30 + (rand() % 120));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,53 +176,53 @@ static int steer(void)
|
||||||
int count;
|
int count;
|
||||||
Entity *e, **candidates;
|
Entity *e, **candidates;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dx = dy = 0;
|
dx = dy = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
force = 0;
|
force = 0;
|
||||||
|
|
||||||
candidates = getAllEntsWithin(self->x - 1000, self->y - 1000, 2000, 2000, self);
|
candidates = getAllEntsWithin(self->x - 1000, self->y - 1000, 2000, 2000, self);
|
||||||
|
|
||||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||||
{
|
{
|
||||||
if (e->type == ET_CAPITAL_SHIP)
|
if (e->type == ET_CAPITAL_SHIP)
|
||||||
{
|
{
|
||||||
distance = getDistance(e->x, e->y, self->x, self->y);
|
distance = getDistance(e->x, e->y, self->x, self->y);
|
||||||
|
|
||||||
if (distance > 0 && distance < self->separationRadius)
|
if (distance > 0 && distance < self->separationRadius)
|
||||||
{
|
{
|
||||||
angle = getAngle(self->x, self->y, e->x, e->y);
|
angle = getAngle(self->x, self->y, e->x, e->y);
|
||||||
|
|
||||||
dx += sin(TO_RAIDANS(angle));
|
dx += sin(TO_RAIDANS(angle));
|
||||||
dy += -cos(TO_RAIDANS(angle));
|
dy += -cos(TO_RAIDANS(angle));
|
||||||
force += (self->separationRadius - distance);
|
force += (self->separationRadius - distance);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
dx /= count;
|
dx /= count;
|
||||||
dy /= count;
|
dy /= count;
|
||||||
|
|
||||||
dx *= force;
|
dx *= force;
|
||||||
dy *= force;
|
dy *= force;
|
||||||
|
|
||||||
self->dx -= (dx * 0.001);
|
self->dx -= (dx * 0.001);
|
||||||
self->dy -= (dy * 0.001);
|
self->dy -= (dy * 0.001);
|
||||||
|
|
||||||
self->targetLocation.x -= dx;
|
self->targetLocation.x -= dx;
|
||||||
self->targetLocation.y -= dy;
|
self->targetLocation.y -= dy;
|
||||||
|
|
||||||
self->aiActionTime = FPS * 10;
|
self->aiActionTime = FPS * 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
wantedAngle = getAngle(self->x, self->y, self->targetLocation.x, self->targetLocation.y);
|
wantedAngle = getAngle(self->x, self->y, self->targetLocation.x, self->targetLocation.y);
|
||||||
|
|
||||||
wantedAngle %= 360;
|
wantedAngle %= 360;
|
||||||
|
|
||||||
return wantedAngle;
|
return wantedAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,9 +237,9 @@ static void componentDie(void)
|
||||||
addSmallExplosion();
|
addSmallExplosion();
|
||||||
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
||||||
addDebris(self->x, self->y, 3 + rand() % 4);
|
addDebris(self->x, self->y, 3 + rand() % 4);
|
||||||
|
|
||||||
self->owner->health--;
|
self->owner->health--;
|
||||||
|
|
||||||
if (self->owner->health > 0)
|
if (self->owner->health > 0)
|
||||||
{
|
{
|
||||||
runScriptFunction("CAP_HEALTH %s %d", self->owner->name, self->owner->health);
|
runScriptFunction("CAP_HEALTH %s %d", self->owner->name, self->owner->health);
|
||||||
|
@ -262,12 +262,12 @@ static void engineThink(void)
|
||||||
static void engineDie(void)
|
static void engineDie(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
self->alive = ALIVE_DEAD;
|
self->alive = ALIVE_DEAD;
|
||||||
addSmallExplosion();
|
addSmallExplosion();
|
||||||
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
||||||
addDebris(self->x, self->y, 4 + rand() % 9);
|
addDebris(self->x, self->y, 4 + rand() % 9);
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e != self && e->owner == self->owner && e->type == ET_CAPITAL_SHIP_ENGINE)
|
if (e != self && e->owner == self->owner && e->type == ET_CAPITAL_SHIP_ENGINE)
|
||||||
|
@ -275,14 +275,14 @@ static void engineDie(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no more engines - stop moving */
|
/* no more engines - stop moving */
|
||||||
if (self->owner->health > 0)
|
if (self->owner->health > 0)
|
||||||
{
|
{
|
||||||
self->owner->speed = 0;
|
self->owner->speed = 0;
|
||||||
self->owner->action = NULL;
|
self->owner->action = NULL;
|
||||||
self->owner->dx = self->owner->dy = 0;
|
self->owner->dx = self->owner->dy = 0;
|
||||||
|
|
||||||
runScriptFunction("CAP_ENGINES_DESTROYED %s", self->owner->name);
|
runScriptFunction("CAP_ENGINES_DESTROYED %s", self->owner->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,11 +290,11 @@ static void engineDie(void)
|
||||||
static void die(void)
|
static void die(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
self->alive = ALIVE_DEAD;
|
self->alive = ALIVE_DEAD;
|
||||||
|
|
||||||
addDebris(self->x, self->y, 50);
|
addDebris(self->x, self->y, 50);
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->owner == self)
|
if (e->owner == self)
|
||||||
|
@ -302,9 +302,9 @@ static void die(void)
|
||||||
e->health = 0;
|
e->health = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateObjective(self->name, TT_DESTROY);
|
updateObjective(self->name, TT_DESTROY);
|
||||||
|
|
||||||
updateObjective(self->groupName, TT_DESTROY);
|
updateObjective(self->groupName, TT_DESTROY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,21 +313,21 @@ void loadCapitalShipDefs(void)
|
||||||
char **filenames;
|
char **filenames;
|
||||||
char path[MAX_FILENAME_LENGTH];
|
char path[MAX_FILENAME_LENGTH];
|
||||||
int count, i;
|
int count, i;
|
||||||
|
|
||||||
memset(&defHead, 0, sizeof(Entity));
|
memset(&defHead, 0, sizeof(Entity));
|
||||||
defTail = &defHead;
|
defTail = &defHead;
|
||||||
|
|
||||||
filenames = getFileList(getFileLocation("data/capitalShips"), &count);
|
filenames = getFileList(getFileLocation("data/capitalShips"), &count);
|
||||||
|
|
||||||
for (i = 0 ; i < count ; i++)
|
for (i = 0 ; i < count ; i++)
|
||||||
{
|
{
|
||||||
sprintf(path, "data/capitalShips/%s", filenames[i]);
|
sprintf(path, "data/capitalShips/%s", filenames[i]);
|
||||||
|
|
||||||
loadCapitalShipDef(path);
|
loadCapitalShipDef(path);
|
||||||
|
|
||||||
free(filenames[i]);
|
free(filenames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filenames);
|
free(filenames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,41 +336,41 @@ static void loadCapitalShipDef(char *filename)
|
||||||
cJSON *root;
|
cJSON *root;
|
||||||
char *text;
|
char *text;
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
||||||
|
|
||||||
text = readFile(getFileLocation(filename));
|
text = readFile(getFileLocation(filename));
|
||||||
|
|
||||||
e = malloc(sizeof(Entity));
|
e = malloc(sizeof(Entity));
|
||||||
memset(e, 0, sizeof(Entity));
|
memset(e, 0, sizeof(Entity));
|
||||||
defTail->next = e;
|
defTail->next = e;
|
||||||
defTail = e;
|
defTail = e;
|
||||||
|
|
||||||
e->type = ET_CAPITAL_SHIP;
|
e->type = ET_CAPITAL_SHIP;
|
||||||
e->active = 1;
|
e->active = 1;
|
||||||
|
|
||||||
root = cJSON_Parse(text);
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
|
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
|
||||||
e->shield = e->maxShield = cJSON_GetObjectItem(root, "shield")->valueint;
|
e->shield = e->maxShield = cJSON_GetObjectItem(root, "shield")->valueint;
|
||||||
e->shieldRechargeRate = cJSON_GetObjectItem(root, "shieldRechargeRate")->valueint;
|
e->shieldRechargeRate = cJSON_GetObjectItem(root, "shieldRechargeRate")->valueint;
|
||||||
e->texture = getTexture(cJSON_GetObjectItem(root, "texture")->valuestring);
|
e->texture = getTexture(cJSON_GetObjectItem(root, "texture")->valuestring);
|
||||||
e->speed = 1;
|
e->speed = 1;
|
||||||
|
|
||||||
e->action = think;
|
e->action = think;
|
||||||
e->die = die;
|
e->die = die;
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
|
|
||||||
e->separationRadius = MAX(e->w, e->h);
|
e->separationRadius = MAX(e->w, e->h);
|
||||||
|
|
||||||
loadComponents(e, cJSON_GetObjectItem(root, "components"));
|
loadComponents(e, cJSON_GetObjectItem(root, "components"));
|
||||||
|
|
||||||
loadGuns(e, cJSON_GetObjectItem(root, "guns"));
|
loadGuns(e, cJSON_GetObjectItem(root, "guns"));
|
||||||
|
|
||||||
loadEngines(e, cJSON_GetObjectItem(root, "engines"));
|
loadEngines(e, cJSON_GetObjectItem(root, "engines"));
|
||||||
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
@ -379,52 +379,52 @@ static void loadComponents(Entity *parent, cJSON *components)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
cJSON *component;
|
cJSON *component;
|
||||||
|
|
||||||
parent->health = 0;
|
parent->health = 0;
|
||||||
|
|
||||||
if (components)
|
if (components)
|
||||||
{
|
{
|
||||||
component = components->child;
|
component = components->child;
|
||||||
|
|
||||||
while (component)
|
while (component)
|
||||||
{
|
{
|
||||||
e = malloc(sizeof(Entity));
|
e = malloc(sizeof(Entity));
|
||||||
memset(e, 0, sizeof(Entity));
|
memset(e, 0, sizeof(Entity));
|
||||||
defTail->next = e;
|
defTail->next = e;
|
||||||
defTail = e;
|
defTail = e;
|
||||||
|
|
||||||
e->active = 1;
|
e->active = 1;
|
||||||
|
|
||||||
e->type = ET_CAPITAL_SHIP_COMPONENT;
|
e->type = ET_CAPITAL_SHIP_COMPONENT;
|
||||||
e->health = e->maxHealth = cJSON_GetObjectItem(component, "health")->valueint;
|
e->health = e->maxHealth = cJSON_GetObjectItem(component, "health")->valueint;
|
||||||
e->offsetX = cJSON_GetObjectItem(component, "x")->valueint;
|
e->offsetX = cJSON_GetObjectItem(component, "x")->valueint;
|
||||||
e->offsetY = cJSON_GetObjectItem(component, "y")->valueint;
|
e->offsetY = cJSON_GetObjectItem(component, "y")->valueint;
|
||||||
e->texture = getTexture(cJSON_GetObjectItem(component, "texture")->valuestring);
|
e->texture = getTexture(cJSON_GetObjectItem(component, "texture")->valuestring);
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(component, "flags"))
|
if (cJSON_GetObjectItem(component, "flags"))
|
||||||
{
|
{
|
||||||
e->flags = flagsToLong(cJSON_GetObjectItem(component, "flags")->valuestring, NULL);
|
e->flags = flagsToLong(cJSON_GetObjectItem(component, "flags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(component, "aiFlags"))
|
if (cJSON_GetObjectItem(component, "aiFlags"))
|
||||||
{
|
{
|
||||||
e->aiFlags = flagsToLong(cJSON_GetObjectItem(component, "aiFlags")->valuestring, NULL);
|
e->aiFlags = flagsToLong(cJSON_GetObjectItem(component, "aiFlags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->systemPower = 100;
|
e->systemPower = 100;
|
||||||
|
|
||||||
e->die = componentDie;
|
e->die = componentDie;
|
||||||
|
|
||||||
e->owner = parent;
|
e->owner = parent;
|
||||||
|
|
||||||
component = component->next;
|
component = component->next;
|
||||||
|
|
||||||
parent->health++;
|
parent->health++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->maxHealth = parent->health;
|
parent->maxHealth = parent->health;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,20 +432,20 @@ static void loadGuns(Entity *parent, cJSON *guns)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
cJSON *gun;
|
cJSON *gun;
|
||||||
|
|
||||||
if (guns)
|
if (guns)
|
||||||
{
|
{
|
||||||
gun = guns->child;
|
gun = guns->child;
|
||||||
|
|
||||||
while (gun)
|
while (gun)
|
||||||
{
|
{
|
||||||
e = malloc(sizeof(Entity));
|
e = malloc(sizeof(Entity));
|
||||||
memset(e, 0, sizeof(Entity));
|
memset(e, 0, sizeof(Entity));
|
||||||
defTail->next = e;
|
defTail->next = e;
|
||||||
defTail = e;
|
defTail = e;
|
||||||
|
|
||||||
e->active = 1;
|
e->active = 1;
|
||||||
|
|
||||||
e->type = ET_CAPITAL_SHIP_GUN;
|
e->type = ET_CAPITAL_SHIP_GUN;
|
||||||
e->health = e->maxHealth = cJSON_GetObjectItem(gun, "health")->valueint;
|
e->health = e->maxHealth = cJSON_GetObjectItem(gun, "health")->valueint;
|
||||||
e->reloadTime = cJSON_GetObjectItem(gun, "reloadTime")->valueint;
|
e->reloadTime = cJSON_GetObjectItem(gun, "reloadTime")->valueint;
|
||||||
|
@ -453,31 +453,27 @@ static void loadGuns(Entity *parent, cJSON *guns)
|
||||||
e->offsetY = cJSON_GetObjectItem(gun, "y")->valueint;
|
e->offsetY = cJSON_GetObjectItem(gun, "y")->valueint;
|
||||||
e->texture = getTexture(cJSON_GetObjectItem(gun, "texture")->valuestring);
|
e->texture = getTexture(cJSON_GetObjectItem(gun, "texture")->valuestring);
|
||||||
e->guns[0].type = lookup(cJSON_GetObjectItem(gun, "type")->valuestring);
|
e->guns[0].type = lookup(cJSON_GetObjectItem(gun, "type")->valuestring);
|
||||||
|
e->missiles = getJSONValue(gun, "missiles", 0);
|
||||||
if (cJSON_GetObjectItem(gun, "missiles"))
|
|
||||||
{
|
|
||||||
e->missiles = cJSON_GetObjectItem(gun, "missiles")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(gun, "flags"))
|
if (cJSON_GetObjectItem(gun, "flags"))
|
||||||
{
|
{
|
||||||
e->flags = flagsToLong(cJSON_GetObjectItem(gun, "flags")->valuestring, NULL);
|
e->flags = flagsToLong(cJSON_GetObjectItem(gun, "flags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(gun, "aiFlags"))
|
if (cJSON_GetObjectItem(gun, "aiFlags"))
|
||||||
{
|
{
|
||||||
e->aiFlags = flagsToLong(cJSON_GetObjectItem(gun, "aiFlags")->valuestring, NULL);
|
e->aiFlags = flagsToLong(cJSON_GetObjectItem(gun, "aiFlags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
|
|
||||||
e->systemPower = 100;
|
e->systemPower = 100;
|
||||||
|
|
||||||
e->action = gunThink;
|
e->action = gunThink;
|
||||||
e->die = gunDie;
|
e->die = gunDie;
|
||||||
|
|
||||||
e->owner = parent;
|
e->owner = parent;
|
||||||
|
|
||||||
gun = gun->next;
|
gun = gun->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,40 +483,40 @@ static void loadEngines(Entity *parent, cJSON *engines)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
cJSON *engine;
|
cJSON *engine;
|
||||||
|
|
||||||
if (engines)
|
if (engines)
|
||||||
{
|
{
|
||||||
engine = engines->child;
|
engine = engines->child;
|
||||||
|
|
||||||
while (engine)
|
while (engine)
|
||||||
{
|
{
|
||||||
e = malloc(sizeof(Entity));
|
e = malloc(sizeof(Entity));
|
||||||
memset(e, 0, sizeof(Entity));
|
memset(e, 0, sizeof(Entity));
|
||||||
defTail->next = e;
|
defTail->next = e;
|
||||||
defTail = e;
|
defTail = e;
|
||||||
|
|
||||||
e->active = 1;
|
e->active = 1;
|
||||||
|
|
||||||
e->type = ET_CAPITAL_SHIP_ENGINE;
|
e->type = ET_CAPITAL_SHIP_ENGINE;
|
||||||
e->health = e->maxHealth = cJSON_GetObjectItem(engine, "health")->valueint;
|
e->health = e->maxHealth = cJSON_GetObjectItem(engine, "health")->valueint;
|
||||||
e->offsetX = cJSON_GetObjectItem(engine, "x")->valueint;
|
e->offsetX = cJSON_GetObjectItem(engine, "x")->valueint;
|
||||||
e->offsetY = cJSON_GetObjectItem(engine, "y")->valueint;
|
e->offsetY = cJSON_GetObjectItem(engine, "y")->valueint;
|
||||||
e->texture = getTexture(cJSON_GetObjectItem(engine, "texture")->valuestring);
|
e->texture = getTexture(cJSON_GetObjectItem(engine, "texture")->valuestring);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(engine, "flags"))
|
if (cJSON_GetObjectItem(engine, "flags"))
|
||||||
{
|
{
|
||||||
e->flags = flagsToLong(cJSON_GetObjectItem(engine, "flags")->valuestring, NULL);
|
e->flags = flagsToLong(cJSON_GetObjectItem(engine, "flags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
|
|
||||||
e->systemPower = 100;
|
e->systemPower = 100;
|
||||||
|
|
||||||
e->action = engineThink;
|
e->action = engineThink;
|
||||||
e->die = engineDie;
|
e->die = engineDie;
|
||||||
|
|
||||||
e->owner = parent;
|
e->owner = parent;
|
||||||
|
|
||||||
engine = engine->next;
|
engine = engine->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,7 +525,7 @@ static void loadEngines(Entity *parent, cJSON *engines)
|
||||||
void updateCapitalShipComponentProperties(Entity *parent)
|
void updateCapitalShipComponentProperties(Entity *parent)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->owner == parent)
|
if (e->owner == parent)
|
||||||
|
@ -539,16 +535,16 @@ void updateCapitalShipComponentProperties(Entity *parent)
|
||||||
case ET_CAPITAL_SHIP_ENGINE:
|
case ET_CAPITAL_SHIP_ENGINE:
|
||||||
sprintf(e->name, "%s (Engine)", parent->name);
|
sprintf(e->name, "%s (Engine)", parent->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ET_CAPITAL_SHIP_COMPONENT:
|
case ET_CAPITAL_SHIP_COMPONENT:
|
||||||
sprintf(e->name, "%s (Component)", parent->name);
|
sprintf(e->name, "%s (Component)", parent->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ET_CAPITAL_SHIP_GUN:
|
case ET_CAPITAL_SHIP_GUN:
|
||||||
sprintf(e->name, "%s (Gun)", parent->name);
|
sprintf(e->name, "%s (Gun)", parent->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->active = parent->active;
|
e->active = parent->active;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,7 +553,7 @@ void updateCapitalShipComponentProperties(Entity *parent)
|
||||||
void destroyCapitalShipDefs(void)
|
void destroyCapitalShipDefs(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
while (defHead.next)
|
while (defHead.next)
|
||||||
{
|
{
|
||||||
e = defHead.next;
|
e = defHead.next;
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern void addDebris(int x, int y, int amount);
|
||||||
extern void runScriptFunction(char *format, ...);
|
extern void runScriptFunction(char *format, ...);
|
||||||
extern void updateObjective(char *name, int type);
|
extern void updateObjective(char *name, int type);
|
||||||
extern char **getFileList(char *dir, int *count);
|
extern char **getFileList(char *dir, int *count);
|
||||||
|
extern int getJSONValue(cJSON *node, char *name, int defValue);
|
||||||
|
|
||||||
extern Battle battle;
|
extern Battle battle;
|
||||||
extern Entity *self;
|
extern Entity *self;
|
||||||
|
|
|
@ -36,20 +36,20 @@ static Entity defHead, *defTail;
|
||||||
Entity *spawnFighter(char *name, int x, int y, int side)
|
Entity *spawnFighter(char *name, int x, int y, int side)
|
||||||
{
|
{
|
||||||
Entity *e, *def;
|
Entity *e, *def;
|
||||||
|
|
||||||
e = spawnEntity();
|
e = spawnEntity();
|
||||||
|
|
||||||
def = getFighterDef(name);
|
def = getFighterDef(name);
|
||||||
|
|
||||||
memcpy(e, def, sizeof(Entity));
|
memcpy(e, def, sizeof(Entity));
|
||||||
|
|
||||||
e->id = battle.entId;
|
e->id = battle.entId;
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
|
|
||||||
e->x = x;
|
e->x = x;
|
||||||
e->y = y;
|
e->y = y;
|
||||||
e->side = side;
|
e->side = side;
|
||||||
|
|
||||||
switch (side)
|
switch (side)
|
||||||
{
|
{
|
||||||
case SIDE_ALLIES:
|
case SIDE_ALLIES:
|
||||||
|
@ -59,91 +59,91 @@ Entity *spawnFighter(char *name, int x, int y, int side)
|
||||||
e->aiFlags |= AIF_MOVES_TO_PLAYER;
|
e->aiFlags |= AIF_MOVES_TO_PLAYER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIDE_PIRATE:
|
case SIDE_PIRATE:
|
||||||
e->aiAggression = rand() % 3;
|
e->aiAggression = rand() % 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIDE_PANDORAN:
|
case SIDE_PANDORAN:
|
||||||
e->aiAggression = 3 + rand() % 2;
|
e->aiAggression = 3 + rand() % 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIDE_REBEL:
|
case SIDE_REBEL:
|
||||||
e->aiAggression = 1 + rand() % 3;
|
e->aiAggression = 1 + rand() % 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, "ATAF") == 0)
|
if (strcmp(name, "ATAF") == 0)
|
||||||
{
|
{
|
||||||
e->aiAggression = 4;
|
e->aiAggression = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, "Dart") == 0)
|
if (strcmp(name, "Dart") == 0)
|
||||||
{
|
{
|
||||||
randomizeDart(e);
|
randomizeDart(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, "Civilian") == 0 && rand() % 2 == 0)
|
if (strcmp(name, "Civilian") == 0 && rand() % 2 == 0)
|
||||||
{
|
{
|
||||||
e->texture = getTexture("gfx/craft/civilian02.png");
|
e->texture = getTexture("gfx/craft/civilian02.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->aiFlags & AIF_AGGRESSIVE)
|
if (e->aiFlags & AIF_AGGRESSIVE)
|
||||||
{
|
{
|
||||||
e->aiAggression = 4;
|
e->aiAggression = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->action = doAI;
|
e->action = doAI;
|
||||||
e->die = die;
|
e->die = die;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void randomizeDart(Entity *dart)
|
static void randomizeDart(Entity *dart)
|
||||||
{
|
{
|
||||||
char texture[MAX_DESCRIPTION_LENGTH];
|
char texture[MAX_DESCRIPTION_LENGTH];
|
||||||
|
|
||||||
if (rand() % 5 == 0)
|
if (rand() % 5 == 0)
|
||||||
{
|
{
|
||||||
dart->health = dart->maxHealth = 5 + (rand() % 21);
|
dart->health = dart->maxHealth = 5 + (rand() % 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rand() % 5 == 0)
|
if (rand() % 5 == 0)
|
||||||
{
|
{
|
||||||
dart->shield = dart->maxShield = 1 + (rand() % 16);
|
dart->shield = dart->maxShield = 1 + (rand() % 16);
|
||||||
dart->shieldRechargeRate = 30 + (rand() % 90);
|
dart->shieldRechargeRate = 30 + (rand() % 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rand() % 5 == 0)
|
if (rand() % 5 == 0)
|
||||||
{
|
{
|
||||||
dart->speed = 2 + (rand() % 3);
|
dart->speed = 2 + (rand() % 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rand() % 5 == 0)
|
if (rand() % 5 == 0)
|
||||||
{
|
{
|
||||||
dart->reloadTime = 24 + (rand() % 11);
|
dart->reloadTime = 24 + (rand() % 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
randomizeDartGuns(dart);
|
randomizeDartGuns(dart);
|
||||||
|
|
||||||
dart->missiles = rand() % 3;
|
dart->missiles = rand() % 3;
|
||||||
|
|
||||||
sprintf(texture, "gfx/fighters/dart0%d.png", 1 + rand() % 7);
|
sprintf(texture, "gfx/fighters/dart0%d.png", 1 + rand() % 7);
|
||||||
|
|
||||||
dart->texture = getTexture(texture);
|
dart->texture = getTexture(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void randomizeDartGuns(Entity *dart)
|
static void randomizeDartGuns(Entity *dart)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (rand() % 4)
|
switch (rand() % 4)
|
||||||
{
|
{
|
||||||
/* Single plasma gun */
|
/* Single plasma gun */
|
||||||
case 0:
|
case 0:
|
||||||
dart->guns[0].type = BT_PLASMA;
|
dart->guns[0].type = BT_PLASMA;
|
||||||
dart->guns[0].x = dart->guns[0].y = 0;
|
dart->guns[0].x = dart->guns[0].y = 0;
|
||||||
|
|
||||||
for (i = 1 ; i < MAX_FIGHTER_GUNS ; i++)
|
for (i = 1 ; i < MAX_FIGHTER_GUNS ; i++)
|
||||||
{
|
{
|
||||||
if (dart->guns[i].type)
|
if (dart->guns[i].type)
|
||||||
|
@ -152,25 +152,25 @@ static void randomizeDartGuns(Entity *dart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Dual plasma guns */
|
/* Dual plasma guns */
|
||||||
case 1:
|
case 1:
|
||||||
dart->guns[0].type = BT_PLASMA;
|
dart->guns[0].type = BT_PLASMA;
|
||||||
dart->guns[1].type = BT_PLASMA;
|
dart->guns[1].type = BT_PLASMA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Triple particle guns */
|
/* Triple particle guns */
|
||||||
case 2:
|
case 2:
|
||||||
dart->guns[2].type = BT_PARTICLE;
|
dart->guns[2].type = BT_PARTICLE;
|
||||||
dart->guns[2].y = -10;
|
dart->guns[2].y = -10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
/* Plasma / Laser cannons */
|
/* Plasma / Laser cannons */
|
||||||
case 3:
|
case 3:
|
||||||
dart->guns[0].type = BT_PLASMA;
|
dart->guns[0].type = BT_PLASMA;
|
||||||
dart->guns[0].x = dart->guns[0].y = 0;
|
dart->guns[0].x = dart->guns[0].y = 0;
|
||||||
|
|
||||||
dart->guns[1].type = BT_LASER;
|
dart->guns[1].type = BT_LASER;
|
||||||
dart->guns[1].x = dart->guns[1].y = 0;
|
dart->guns[1].x = dart->guns[1].y = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -191,20 +191,20 @@ void doFighter(void)
|
||||||
{
|
{
|
||||||
separate();
|
separate();
|
||||||
}
|
}
|
||||||
|
|
||||||
attachRope();
|
attachRope();
|
||||||
|
|
||||||
if (self->thrust > 0.25)
|
if (self->thrust > 0.25)
|
||||||
{
|
{
|
||||||
addEngineEffect();
|
addEngineEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->health <= 0)
|
if (self->health <= 0)
|
||||||
{
|
{
|
||||||
self->health = 0;
|
self->health = 0;
|
||||||
self->alive = ALIVE_DYING;
|
self->alive = ALIVE_DYING;
|
||||||
self->die();
|
self->die();
|
||||||
|
|
||||||
if (self == battle.missionTarget)
|
if (self == battle.missionTarget)
|
||||||
{
|
{
|
||||||
battle.missionTarget = NULL;
|
battle.missionTarget = NULL;
|
||||||
|
@ -217,38 +217,38 @@ void doFighter(void)
|
||||||
self->thrust = 0;
|
self->thrust = 0;
|
||||||
self->shield = self->maxShield = 0;
|
self->shield = self->maxShield = 0;
|
||||||
self->action = NULL;
|
self->action = NULL;
|
||||||
|
|
||||||
if ((self->flags & EF_DISABLED) == 0)
|
if ((self->flags & EF_DISABLED) == 0)
|
||||||
{
|
{
|
||||||
playBattleSound(SND_POWER_DOWN, self->x, self->y);
|
playBattleSound(SND_POWER_DOWN, self->x, self->y);
|
||||||
|
|
||||||
self->flags |= EF_DISABLED;
|
self->flags |= EF_DISABLED;
|
||||||
self->flags |= EF_SECONDARY_TARGET;
|
self->flags |= EF_SECONDARY_TARGET;
|
||||||
|
|
||||||
battle.stats[STAT_ENEMIES_DISABLED]++;
|
battle.stats[STAT_ENEMIES_DISABLED]++;
|
||||||
|
|
||||||
updateObjective(self->name, TT_DISABLE);
|
updateObjective(self->name, TT_DISABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->target != NULL && self->target->alive != ALIVE_ALIVE)
|
if (self->target != NULL && self->target->alive != ALIVE_ALIVE)
|
||||||
{
|
{
|
||||||
self->target = NULL;
|
self->target = NULL;
|
||||||
|
|
||||||
if (self != player)
|
if (self != player)
|
||||||
{
|
{
|
||||||
self->action = doAI;
|
self->action = doAI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->alive == ALIVE_ESCAPED)
|
if (self->alive == ALIVE_ESCAPED)
|
||||||
{
|
{
|
||||||
if (self == player)
|
if (self == player)
|
||||||
{
|
{
|
||||||
completeMission();
|
completeMission();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->side != SIDE_ALLIES && (!(self->flags & EF_DISABLED)))
|
if (self->side != SIDE_ALLIES && (!(self->flags & EF_DISABLED)))
|
||||||
{
|
{
|
||||||
addHudMessage(colors.red, _("Mission target has escaped."));
|
addHudMessage(colors.red, _("Mission target has escaped."));
|
||||||
|
@ -258,12 +258,12 @@ void doFighter(void)
|
||||||
{
|
{
|
||||||
battle.stats[STAT_CIVILIANS_RESCUED]++;
|
battle.stats[STAT_CIVILIANS_RESCUED]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateObjective(self->name, TT_ESCAPED);
|
updateObjective(self->name, TT_ESCAPED);
|
||||||
|
|
||||||
updateCondition(self->name, TT_ESCAPED);
|
updateCondition(self->name, TT_ESCAPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->alive == ALIVE_DEAD)
|
if (self->alive == ALIVE_DEAD)
|
||||||
{
|
{
|
||||||
if (self == player)
|
if (self == player)
|
||||||
|
@ -277,7 +277,7 @@ void doFighter(void)
|
||||||
if (self->side != SIDE_ALLIES)
|
if (self->side != SIDE_ALLIES)
|
||||||
{
|
{
|
||||||
battle.stats[STAT_ENEMIES_KILLED]++;
|
battle.stats[STAT_ENEMIES_KILLED]++;
|
||||||
|
|
||||||
runScriptFunction("ENEMIES_KILLED %d", battle.stats[STAT_ENEMIES_KILLED]);
|
runScriptFunction("ENEMIES_KILLED %d", battle.stats[STAT_ENEMIES_KILLED]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -297,17 +297,17 @@ void doFighter(void)
|
||||||
{
|
{
|
||||||
addHudMessage(colors.red, _("Ally has been killed"));
|
addHudMessage(colors.red, _("Ally has been killed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
runScriptFunction("ALLIES_KILLED %d", battle.stats[STAT_ALLIES_KILLED]);
|
runScriptFunction("ALLIES_KILLED %d", battle.stats[STAT_ALLIES_KILLED]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateObjective(self->name, TT_DESTROY);
|
updateObjective(self->name, TT_DESTROY);
|
||||||
updateObjective(self->groupName, TT_DESTROY);
|
updateObjective(self->groupName, TT_DESTROY);
|
||||||
|
|
||||||
adjustObjectiveTargetValue(self->name, TT_ESCAPED, -1);
|
adjustObjectiveTargetValue(self->name, TT_ESCAPED, -1);
|
||||||
|
|
||||||
updateCondition(self->name, TT_DESTROY);
|
updateCondition(self->name, TT_DESTROY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,40 +321,40 @@ static void separate(void)
|
||||||
int count;
|
int count;
|
||||||
Entity *e, **candidates;
|
Entity *e, **candidates;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dx = dy = 0;
|
dx = dy = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
force = 0;
|
force = 0;
|
||||||
|
|
||||||
candidates = getAllEntsWithin(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, self);
|
candidates = getAllEntsWithin(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, self);
|
||||||
|
|
||||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||||
{
|
{
|
||||||
if (e->flags & EF_TAKES_DAMAGE)
|
if (e->flags & EF_TAKES_DAMAGE)
|
||||||
{
|
{
|
||||||
distance = getDistance(e->x, e->y, self->x, self->y);
|
distance = getDistance(e->x, e->y, self->x, self->y);
|
||||||
|
|
||||||
if (distance > 0 && distance < self->separationRadius)
|
if (distance > 0 && distance < self->separationRadius)
|
||||||
{
|
{
|
||||||
angle = getAngle(self->x, self->y, e->x, e->y);
|
angle = getAngle(self->x, self->y, e->x, e->y);
|
||||||
|
|
||||||
dx += sin(TO_RAIDANS(angle));
|
dx += sin(TO_RAIDANS(angle));
|
||||||
dy += -cos(TO_RAIDANS(angle));
|
dy += -cos(TO_RAIDANS(angle));
|
||||||
force += (self->separationRadius - distance) * 0.005;
|
force += (self->separationRadius - distance) * 0.005;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
dx /= count;
|
dx /= count;
|
||||||
dy /= count;
|
dy /= count;
|
||||||
|
|
||||||
dx *= force;
|
dx *= force;
|
||||||
dy *= force;
|
dy *= force;
|
||||||
|
|
||||||
self->dx -= dx;
|
self->dx -= dx;
|
||||||
self->dy -= dy;
|
self->dy -= dy;
|
||||||
}
|
}
|
||||||
|
@ -363,11 +363,11 @@ static void separate(void)
|
||||||
void applyFighterThrust(void)
|
void applyFighterThrust(void)
|
||||||
{
|
{
|
||||||
float v;
|
float v;
|
||||||
|
|
||||||
self->dx += sin(TO_RAIDANS(self->angle)) * 0.1;
|
self->dx += sin(TO_RAIDANS(self->angle)) * 0.1;
|
||||||
self->dy += -cos(TO_RAIDANS(self->angle)) * 0.1;
|
self->dy += -cos(TO_RAIDANS(self->angle)) * 0.1;
|
||||||
self->thrust = sqrt((self->dx * self->dx) + (self->dy * self->dy));
|
self->thrust = sqrt((self->dx * self->dx) + (self->dy * self->dy));
|
||||||
|
|
||||||
if (self->thrust > self->speed * self->speed)
|
if (self->thrust > self->speed * self->speed)
|
||||||
{
|
{
|
||||||
v = (self->speed / sqrt(self->thrust));
|
v = (self->speed / sqrt(self->thrust));
|
||||||
|
@ -381,25 +381,25 @@ void applyFighterBrakes(void)
|
||||||
{
|
{
|
||||||
self->dx *= 0.95;
|
self->dx *= 0.95;
|
||||||
self->dy *= 0.95;
|
self->dy *= 0.95;
|
||||||
|
|
||||||
self->thrust = sqrt((self->dx * self->dx) + (self->dy * self->dy));
|
self->thrust = sqrt((self->dx * self->dx) + (self->dy * self->dy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void damageFighter(Entity *e, int amount, long flags)
|
void damageFighter(Entity *e, int amount, long flags)
|
||||||
{
|
{
|
||||||
int prevShield = e->shield;
|
int prevShield = e->shield;
|
||||||
|
|
||||||
e->aiDamageTimer = FPS;
|
e->aiDamageTimer = FPS;
|
||||||
e->aiDamagePerSec += amount;
|
e->aiDamagePerSec += amount;
|
||||||
|
|
||||||
if (flags & BF_SYSTEM_DAMAGE)
|
if (flags & BF_SYSTEM_DAMAGE)
|
||||||
{
|
{
|
||||||
playBattleSound(SND_MAG_HIT, e->x, e->y);
|
playBattleSound(SND_MAG_HIT, e->x, e->y);
|
||||||
|
|
||||||
e->systemPower = MAX(0, e->systemPower - amount);
|
e->systemPower = MAX(0, e->systemPower - amount);
|
||||||
|
|
||||||
e->systemHit = 255;
|
e->systemHit = 255;
|
||||||
|
|
||||||
if (e->systemPower == 0)
|
if (e->systemPower == 0)
|
||||||
{
|
{
|
||||||
e->shield = e->maxShield = 0;
|
e->shield = e->maxShield = 0;
|
||||||
|
@ -409,14 +409,14 @@ void damageFighter(Entity *e, int amount, long flags)
|
||||||
else if (flags & BF_SHIELD_DAMAGE)
|
else if (flags & BF_SHIELD_DAMAGE)
|
||||||
{
|
{
|
||||||
e->shield -= amount;
|
e->shield -= amount;
|
||||||
|
|
||||||
if (e->shield <= 0 && prevShield > 0)
|
if (e->shield <= 0 && prevShield > 0)
|
||||||
{
|
{
|
||||||
playBattleSound(SND_SHIELD_BREAK, e->x, e->y);
|
playBattleSound(SND_SHIELD_BREAK, e->x, e->y);
|
||||||
addShieldSplinterEffect(e);
|
addShieldSplinterEffect(e);
|
||||||
e->shield = -(FPS * 10);
|
e->shield = -(FPS * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->shield = MAX(-(FPS * 10), e->shield);
|
e->shield = MAX(-(FPS * 10), e->shield);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -424,7 +424,7 @@ void damageFighter(Entity *e, int amount, long flags)
|
||||||
if (e->shield > 0)
|
if (e->shield > 0)
|
||||||
{
|
{
|
||||||
e->shield -= amount;
|
e->shield -= amount;
|
||||||
|
|
||||||
if (e->shield < 0)
|
if (e->shield < 0)
|
||||||
{
|
{
|
||||||
e->health += e->shield;
|
e->health += e->shield;
|
||||||
|
@ -435,21 +435,21 @@ void damageFighter(Entity *e, int amount, long flags)
|
||||||
{
|
{
|
||||||
e->health -= amount;
|
e->health -= amount;
|
||||||
e->armourHit = 255;
|
e->armourHit = 255;
|
||||||
|
|
||||||
playBattleSound(SND_ARMOUR_HIT, e->x, e->y);
|
playBattleSound(SND_ARMOUR_HIT, e->x, e->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->shield > 0)
|
if (e->shield > 0)
|
||||||
{
|
{
|
||||||
e->shieldHit = 255;
|
e->shieldHit = 255;
|
||||||
|
|
||||||
/* don't allow the shield to recharge immediately after taking a hit */
|
/* don't allow the shield to recharge immediately after taking a hit */
|
||||||
e->shieldRecharge = e->shieldRechargeRate;
|
e->shieldRecharge = e->shieldRechargeRate;
|
||||||
|
|
||||||
playBattleSound(SND_SHIELD_HIT, e->x, e->y);
|
playBattleSound(SND_SHIELD_HIT, e->x, e->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sometimes run away if you take too much damage in a short space of time
|
* Sometimes run away if you take too much damage in a short space of time
|
||||||
*/
|
*/
|
||||||
|
@ -471,7 +471,7 @@ void damageFighter(Entity *e, int amount, long flags)
|
||||||
static void die(void)
|
static void die(void)
|
||||||
{
|
{
|
||||||
int n = rand() % 3;
|
int n = rand() % 3;
|
||||||
|
|
||||||
switch (self->deathType)
|
switch (self->deathType)
|
||||||
{
|
{
|
||||||
case DT_ANY:
|
case DT_ANY:
|
||||||
|
@ -484,22 +484,22 @@ static void die(void)
|
||||||
n = 2;
|
n = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self == player && battle.isEpic)
|
if (self == player && battle.isEpic)
|
||||||
{
|
{
|
||||||
n = 1;
|
n = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
self->action = spinDie;
|
self->action = spinDie;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
self->action = straightDie;
|
self->action = straightDie;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
self->action = immediateDie;
|
self->action = immediateDie;
|
||||||
break;
|
break;
|
||||||
|
@ -521,14 +521,14 @@ static void spinDie(void)
|
||||||
self->armourHit = 0;
|
self->armourHit = 0;
|
||||||
self->shieldHit = 0;
|
self->shieldHit = 0;
|
||||||
self->systemHit = 0;
|
self->systemHit = 0;
|
||||||
|
|
||||||
self->angle += 8;
|
self->angle += 8;
|
||||||
|
|
||||||
if (rand() % 2 == 0)
|
if (rand() % 2 == 0)
|
||||||
{
|
{
|
||||||
addSmallFighterExplosion();
|
addSmallFighterExplosion();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->health <= -(FPS * 1.5))
|
if (self->health <= -(FPS * 1.5))
|
||||||
{
|
{
|
||||||
self->alive = ALIVE_DEAD;
|
self->alive = ALIVE_DEAD;
|
||||||
|
@ -545,12 +545,12 @@ static void straightDie(void)
|
||||||
self->armourHit = 0;
|
self->armourHit = 0;
|
||||||
self->shieldHit = 0;
|
self->shieldHit = 0;
|
||||||
self->systemHit = 0;
|
self->systemHit = 0;
|
||||||
|
|
||||||
if (rand() % 2 == 0)
|
if (rand() % 2 == 0)
|
||||||
{
|
{
|
||||||
addSmallFighterExplosion();
|
addSmallFighterExplosion();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->health <= -(FPS * 1.5))
|
if (self->health <= -(FPS * 1.5))
|
||||||
{
|
{
|
||||||
self->alive = ALIVE_DEAD;
|
self->alive = ALIVE_DEAD;
|
||||||
|
@ -563,7 +563,7 @@ static void straightDie(void)
|
||||||
void retreatEnemies(void)
|
void retreatEnemies(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->type == ET_FIGHTER && e->side != SIDE_ALLIES)
|
if (e->type == ET_FIGHTER && e->side != SIDE_ALLIES)
|
||||||
|
@ -576,13 +576,13 @@ void retreatEnemies(void)
|
||||||
void retreatAllies(void)
|
void retreatAllies(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->type == ET_FIGHTER && e->side == SIDE_ALLIES)
|
if (e->type == ET_FIGHTER && e->side == SIDE_ALLIES)
|
||||||
{
|
{
|
||||||
e->flags |= EF_RETREATING;
|
e->flags |= EF_RETREATING;
|
||||||
|
|
||||||
e->aiFlags |= AIF_AVOIDS_COMBAT;
|
e->aiFlags |= AIF_AVOIDS_COMBAT;
|
||||||
e->aiFlags |= AIF_UNLIMITED_RANGE;
|
e->aiFlags |= AIF_UNLIMITED_RANGE;
|
||||||
e->aiFlags |= AIF_GOAL_EXTRACTION;
|
e->aiFlags |= AIF_GOAL_EXTRACTION;
|
||||||
|
@ -595,7 +595,7 @@ void retreatAllies(void)
|
||||||
static Entity *getFighterDef(char *name)
|
static Entity *getFighterDef(char *name)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
for (e = defHead.next ; e != NULL ; e = e->next)
|
for (e = defHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (strcmp(e->name, name) == 0)
|
if (strcmp(e->name, name) == 0)
|
||||||
|
@ -603,7 +603,7 @@ static Entity *getFighterDef(char *name)
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Error: no such fighter '%s'\n", name);
|
printf("Error: no such fighter '%s'\n", name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ void loadFighterDefs(void)
|
||||||
{
|
{
|
||||||
memset(&defHead, 0, sizeof(Entity));
|
memset(&defHead, 0, sizeof(Entity));
|
||||||
defTail = &defHead;
|
defTail = &defHead;
|
||||||
|
|
||||||
loadFighterDefList("data/fighters");
|
loadFighterDefList("data/fighters");
|
||||||
loadFighterDefList("data/craft");
|
loadFighterDefList("data/craft");
|
||||||
loadFighterDefList("data/turrets");
|
loadFighterDefList("data/turrets");
|
||||||
|
@ -623,18 +623,18 @@ static void loadFighterDefList(char *dir)
|
||||||
char **filenames;
|
char **filenames;
|
||||||
char path[MAX_FILENAME_LENGTH];
|
char path[MAX_FILENAME_LENGTH];
|
||||||
int count, i;
|
int count, i;
|
||||||
|
|
||||||
filenames = getFileList(getFileLocation(dir), &count);
|
filenames = getFileList(getFileLocation(dir), &count);
|
||||||
|
|
||||||
for (i = 0 ; i < count ; i++)
|
for (i = 0 ; i < count ; i++)
|
||||||
{
|
{
|
||||||
sprintf(path, "%s/%s", dir, filenames[i]);
|
sprintf(path, "%s/%s", dir, filenames[i]);
|
||||||
|
|
||||||
loadFighterDef(path);
|
loadFighterDef(path);
|
||||||
|
|
||||||
free(filenames[i]);
|
free(filenames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filenames);
|
free(filenames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,21 +644,21 @@ static void loadFighterDef(char *filename)
|
||||||
char *text;
|
char *text;
|
||||||
Entity *e;
|
Entity *e;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
||||||
|
|
||||||
text = readFile(getFileLocation(filename));
|
text = readFile(getFileLocation(filename));
|
||||||
|
|
||||||
e = malloc(sizeof(Entity));
|
e = malloc(sizeof(Entity));
|
||||||
memset(e, 0, sizeof(Entity));
|
memset(e, 0, sizeof(Entity));
|
||||||
defTail->next = e;
|
defTail->next = e;
|
||||||
defTail = e;
|
defTail = e;
|
||||||
|
|
||||||
e->type = ET_FIGHTER;
|
e->type = ET_FIGHTER;
|
||||||
e->active = 1;
|
e->active = 1;
|
||||||
|
|
||||||
root = cJSON_Parse(text);
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
|
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
|
||||||
e->health = e->maxHealth = cJSON_GetObjectItem(root, "health")->valueint;
|
e->health = e->maxHealth = cJSON_GetObjectItem(root, "health")->valueint;
|
||||||
|
@ -667,61 +667,55 @@ static void loadFighterDef(char *filename)
|
||||||
e->reloadTime = cJSON_GetObjectItem(root, "reloadTime")->valueint;
|
e->reloadTime = cJSON_GetObjectItem(root, "reloadTime")->valueint;
|
||||||
e->shieldRechargeRate = cJSON_GetObjectItem(root, "shieldRechargeRate")->valueint;
|
e->shieldRechargeRate = cJSON_GetObjectItem(root, "shieldRechargeRate")->valueint;
|
||||||
e->texture = getTexture(cJSON_GetObjectItem(root, "texture")->valuestring);
|
e->texture = getTexture(cJSON_GetObjectItem(root, "texture")->valuestring);
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "guns"))
|
if (cJSON_GetObjectItem(root, "guns"))
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
for (node = cJSON_GetObjectItem(root, "guns")->child ; node != NULL ; node = node->next)
|
for (node = cJSON_GetObjectItem(root, "guns")->child ; node != NULL ; node = node->next)
|
||||||
{
|
{
|
||||||
e->guns[i].type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
e->guns[i].type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
||||||
e->guns[i].x = cJSON_GetObjectItem(node, "x")->valueint;
|
e->guns[i].x = cJSON_GetObjectItem(node, "x")->valueint;
|
||||||
e->guns[i].y = cJSON_GetObjectItem(node, "y")->valueint;
|
e->guns[i].y = cJSON_GetObjectItem(node, "y")->valueint;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i >= MAX_FIGHTER_GUNS)
|
if (i >= MAX_FIGHTER_GUNS)
|
||||||
{
|
{
|
||||||
printf("ERROR: cannot assign more than %d guns to a fighter\n", MAX_FIGHTER_GUNS);
|
printf("ERROR: cannot assign more than %d guns to a fighter\n", MAX_FIGHTER_GUNS);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "combinedGuns"))
|
e->combinedGuns = getJSONValue(root, "combinedGuns", 0);
|
||||||
{
|
|
||||||
e->combinedGuns = cJSON_GetObjectItem(root, "combinedGuns")->valueint;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e->selectedGunType = e->guns[0].type;
|
e->selectedGunType = e->guns[0].type;
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "missiles"))
|
e->missiles = getJSONValue(root, "missiles", 0);
|
||||||
{
|
|
||||||
e->missiles = cJSON_GetObjectItem(root, "missiles")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "flags"))
|
if (cJSON_GetObjectItem(root, "flags"))
|
||||||
{
|
{
|
||||||
e->flags = flagsToLong(cJSON_GetObjectItem(root, "flags")->valuestring, NULL);
|
e->flags = flagsToLong(cJSON_GetObjectItem(root, "flags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "aiFlags"))
|
if (cJSON_GetObjectItem(root, "aiFlags"))
|
||||||
{
|
{
|
||||||
e->aiFlags = flagsToLong(cJSON_GetObjectItem(root, "aiFlags")->valuestring, NULL);
|
e->aiFlags = flagsToLong(cJSON_GetObjectItem(root, "aiFlags")->valuestring, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "deathType"))
|
if (cJSON_GetObjectItem(root, "deathType"))
|
||||||
{
|
{
|
||||||
e->deathType = lookup(cJSON_GetObjectItem(root, "deathType")->valuestring);
|
e->deathType = lookup(cJSON_GetObjectItem(root, "deathType")->valuestring);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->separationRadius = MAX(e->w, e->h) * 3;
|
e->separationRadius = MAX(e->w, e->h) * 3;
|
||||||
|
|
||||||
/* all craft default to 100 system power */
|
/* all craft default to 100 system power */
|
||||||
e->systemPower = 100;
|
e->systemPower = 100;
|
||||||
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
@ -729,7 +723,7 @@ static void loadFighterDef(char *filename)
|
||||||
void destroyFighterDefs(void)
|
void destroyFighterDefs(void)
|
||||||
{
|
{
|
||||||
Entity *e;
|
Entity *e;
|
||||||
|
|
||||||
while (defHead.next)
|
while (defHead.next)
|
||||||
{
|
{
|
||||||
e = defHead.next;
|
e = defHead.next;
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern char *getFileLocation(char *filename);
|
||||||
extern void addDebris(int x, int y, int amount);
|
extern void addDebris(int x, int y, int amount);
|
||||||
extern char **getFileList(char *dir, int *count);
|
extern char **getFileList(char *dir, int *count);
|
||||||
extern char *getTranslatedString(char *string);
|
extern char *getTranslatedString(char *string);
|
||||||
|
extern int getJSONValue(cJSON *node, char *name, int defValue);
|
||||||
|
|
||||||
extern App app;
|
extern App app;
|
||||||
extern Battle battle;
|
extern Battle battle;
|
||||||
|
|
|
@ -41,79 +41,78 @@ Mission *loadMissionMeta(char *filename)
|
||||||
Challenge *challenge;
|
Challenge *challenge;
|
||||||
cJSON *root, *node;
|
cJSON *root, *node;
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
||||||
|
|
||||||
text = readFile(getFileLocation(filename));
|
text = readFile(getFileLocation(filename));
|
||||||
|
|
||||||
root = cJSON_Parse(text);
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
mission = malloc(sizeof(Mission));
|
mission = malloc(sizeof(Mission));
|
||||||
memset(mission, 0, sizeof(Mission));
|
memset(mission, 0, sizeof(Mission));
|
||||||
|
|
||||||
STRNCPY(mission->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(mission->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(mission->description, _(cJSON_GetObjectItem(root, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
STRNCPY(mission->description, _(cJSON_GetObjectItem(root, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
||||||
STRNCPY(mission->filename, filename, MAX_DESCRIPTION_LENGTH);
|
STRNCPY(mission->filename, filename, MAX_DESCRIPTION_LENGTH);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "requires"))
|
mission->requires = getJSONValue(root, "requires", 0);
|
||||||
{
|
|
||||||
mission->requires = cJSON_GetObjectItem(root, "requires")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "epic"))
|
if (cJSON_GetObjectItem(root, "epic"))
|
||||||
{
|
{
|
||||||
mission->epic = 1;
|
mission->epic = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = cJSON_GetObjectItem(root, "player");
|
node = cJSON_GetObjectItem(root, "player");
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
STRNCPY(mission->pilot, cJSON_GetObjectItem(node, "pilot")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(mission->pilot, cJSON_GetObjectItem(node, "pilot")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(mission->squadron, cJSON_GetObjectItem(node, "squadron")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(mission->squadron, cJSON_GetObjectItem(node, "squadron")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(mission->craft, cJSON_GetObjectItem(node, "type")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(mission->craft, cJSON_GetObjectItem(node, "type")->valuestring, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = cJSON_GetObjectItem(root, "challenge");
|
node = cJSON_GetObjectItem(root, "challenge");
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
mission->challengeData.isChallenge = 1;
|
mission->challengeData.isChallenge = 1;
|
||||||
mission->challengeData.timeLimit = cJSON_GetObjectItem(node, "timeLimit")->valueint * FPS;
|
|
||||||
mission->challengeData.killLimit = cJSON_GetObjectItem(node, "killLimit")->valueint;
|
mission->challengeData.timeLimit = getJSONValue(node, "timeLimit", 0);
|
||||||
mission->challengeData.noMissiles = cJSON_GetObjectItem(node, "noMissiles") ? 1 : 0;
|
mission->challengeData.killLimit = getJSONValue(node, "killLimit", 0);
|
||||||
mission->challengeData.noECM = cJSON_GetObjectItem(node, "noECM") ? 1 : 0;
|
mission->challengeData.waypointLimit = getJSONValue(node, "waypointLimit", 0);
|
||||||
mission->challengeData.noBoost = cJSON_GetObjectItem(node, "noBoost") ? 1 : 0;
|
mission->challengeData.noMissiles = getJSONValue(node, "noMissiles", 0);
|
||||||
mission->challengeData.noGuns = cJSON_GetObjectItem(node, "noGuns") ? 1 : 0;
|
mission->challengeData.noECM = getJSONValue(node, "noECM", 0);
|
||||||
|
mission->challengeData.noBoost = getJSONValue(node, "noBoost", 0);
|
||||||
|
mission->challengeData.noGuns = getJSONValue(node, "noGuns", 0);
|
||||||
|
|
||||||
node = cJSON_GetObjectItem(node, "challenges");
|
node = cJSON_GetObjectItem(node, "challenges");
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
while (node && i < MAX_CHALLENGES)
|
while (node && i < MAX_CHALLENGES)
|
||||||
{
|
{
|
||||||
challenge = malloc(sizeof(Challenge));
|
challenge = malloc(sizeof(Challenge));
|
||||||
memset(challenge, 0, sizeof(Challenge));
|
memset(challenge, 0, sizeof(Challenge));
|
||||||
|
|
||||||
challenge->type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
challenge->type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
||||||
challenge->value = cJSON_GetObjectItem(node, "value")->valueint;
|
challenge->value = cJSON_GetObjectItem(node, "value")->valueint;
|
||||||
|
|
||||||
mission->challengeData.challenges[i] = challenge;
|
mission->challengeData.challenges[i] = challenge;
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
free(text);
|
free(text);
|
||||||
|
|
||||||
return mission;
|
return mission;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,63 +121,56 @@ void loadMission(char *filename)
|
||||||
cJSON *root;
|
cJSON *root;
|
||||||
char *text, music[MAX_DESCRIPTION_LENGTH], *background, *planet;
|
char *text, music[MAX_DESCRIPTION_LENGTH], *background, *planet;
|
||||||
float planetScale;
|
float planetScale;
|
||||||
|
|
||||||
startSectionTransition();
|
startSectionTransition();
|
||||||
|
|
||||||
stopMusic();
|
stopMusic();
|
||||||
|
|
||||||
text = readFile(getFileLocation(filename));
|
text = readFile(getFileLocation(filename));
|
||||||
|
|
||||||
root = cJSON_Parse(text);
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
srand(hashcode(filename));
|
srand(hashcode(filename));
|
||||||
|
|
||||||
loadObjectives(cJSON_GetObjectItem(root, "objectives"));
|
loadObjectives(cJSON_GetObjectItem(root, "objectives"));
|
||||||
|
|
||||||
loadPlayer(cJSON_GetObjectItem(root, "player"));
|
loadPlayer(cJSON_GetObjectItem(root, "player"));
|
||||||
|
|
||||||
loadFighters(cJSON_GetObjectItem(root, "fighters"));
|
loadFighters(cJSON_GetObjectItem(root, "fighters"));
|
||||||
|
|
||||||
loadCapitalShips(cJSON_GetObjectItem(root, "capitalShips"));
|
loadCapitalShips(cJSON_GetObjectItem(root, "capitalShips"));
|
||||||
|
|
||||||
loadEntities(cJSON_GetObjectItem(root, "entities"));
|
loadEntities(cJSON_GetObjectItem(root, "entities"));
|
||||||
|
|
||||||
loadItems(cJSON_GetObjectItem(root, "items"));
|
loadItems(cJSON_GetObjectItem(root, "items"));
|
||||||
|
|
||||||
loadLocations(cJSON_GetObjectItem(root, "locations"));
|
loadLocations(cJSON_GetObjectItem(root, "locations"));
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "epic"))
|
if (cJSON_GetObjectItem(root, "epic"))
|
||||||
{
|
{
|
||||||
loadEpicData(cJSON_GetObjectItem(root, "epic"));
|
loadEpicData(cJSON_GetObjectItem(root, "epic"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "manualComplete"))
|
battle.manualComplete = getJSONValue(root, "manualComplete", 0);
|
||||||
{
|
battle.unwinnable = getJSONValue(root, "unwinnable", 0);
|
||||||
battle.manualComplete = cJSON_GetObjectItem(root, "manualComplete")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(root, "unwinnable"))
|
|
||||||
{
|
|
||||||
battle.unwinnable = cJSON_GetObjectItem(root, "unwinnable")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
initScript(cJSON_GetObjectItem(root, "script"));
|
initScript(cJSON_GetObjectItem(root, "script"));
|
||||||
|
|
||||||
/* music, planet, and background loading must come last, so AUTO works properly */
|
/* music, planet, and background loading must come last, so AUTO works properly */
|
||||||
|
|
||||||
STRNCPY(music, cJSON_GetObjectItem(root, "music")->valuestring, MAX_DESCRIPTION_LENGTH);
|
STRNCPY(music, cJSON_GetObjectItem(root, "music")->valuestring, MAX_DESCRIPTION_LENGTH);
|
||||||
if (strcmp(music, "AUTO") == 0)
|
if (strcmp(music, "AUTO") == 0)
|
||||||
{
|
{
|
||||||
STRNCPY(music, getAutoMusic(filename), MAX_DESCRIPTION_LENGTH);
|
STRNCPY(music, getAutoMusic(filename), MAX_DESCRIPTION_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
background = cJSON_GetObjectItem(root, "background")->valuestring;
|
background = cJSON_GetObjectItem(root, "background")->valuestring;
|
||||||
if (strcmp(background, "AUTO") == 0)
|
if (strcmp(background, "AUTO") == 0)
|
||||||
{
|
{
|
||||||
background = getAutoBackground(filename);
|
background = getAutoBackground(filename);
|
||||||
}
|
}
|
||||||
battle.background = getTexture(background);
|
battle.background = getTexture(background);
|
||||||
|
|
||||||
planet = cJSON_GetObjectItem(root, "planet")->valuestring;
|
planet = cJSON_GetObjectItem(root, "planet")->valuestring;
|
||||||
if (strcmp(planet, "AUTO") == 0)
|
if (strcmp(planet, "AUTO") == 0)
|
||||||
{
|
{
|
||||||
|
@ -192,13 +184,13 @@ void loadMission(char *filename)
|
||||||
SDL_QueryTexture(battle.planetTexture, NULL, NULL, &battle.planetWidth, &battle.planetHeight);
|
SDL_QueryTexture(battle.planetTexture, NULL, NULL, &battle.planetWidth, &battle.planetHeight);
|
||||||
battle.planetWidth *= planetScale;
|
battle.planetWidth *= planetScale;
|
||||||
battle.planetHeight *= planetScale;
|
battle.planetHeight *= planetScale;
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
free(text);
|
free(text);
|
||||||
|
|
||||||
endSectionTransition();
|
endSectionTransition();
|
||||||
|
|
||||||
/* only increment num missions / challenges started if there are some (Free Flight excluded, for example) */
|
/* only increment num missions / challenges started if there are some (Free Flight excluded, for example) */
|
||||||
if (battle.objectiveHead.next)
|
if (battle.objectiveHead.next)
|
||||||
{
|
{
|
||||||
|
@ -208,26 +200,26 @@ void loadMission(char *filename)
|
||||||
{
|
{
|
||||||
game.stats[STAT_CHALLENGES_STARTED]++;
|
game.stats[STAT_CHALLENGES_STARTED]++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
battle.status = MS_IN_PROGRESS;
|
battle.status = MS_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
activateNextWaypoint();
|
activateNextWaypoint();
|
||||||
|
|
||||||
countNumEnemies();
|
countNumEnemies();
|
||||||
|
|
||||||
initPlayer();
|
initPlayer();
|
||||||
|
|
||||||
initMissionInfo();
|
initMissionInfo();
|
||||||
|
|
||||||
playMusic(music);
|
playMusic(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getAutoBackground(char *filename)
|
static char *getAutoBackground(char *filename)
|
||||||
{
|
{
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
if (!game.currentMission->challengeData.isChallenge)
|
if (!game.currentMission->challengeData.isChallenge)
|
||||||
{
|
{
|
||||||
hash = hashcode(game.selectedStarSystem);
|
hash = hashcode(game.selectedStarSystem);
|
||||||
|
@ -236,14 +228,14 @@ static char *getAutoBackground(char *filename)
|
||||||
{
|
{
|
||||||
hash = hashcode(filename);
|
hash = hashcode(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBackgroundTextureName(hash);
|
return getBackgroundTextureName(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getAutoPlanet(char *filename)
|
static char *getAutoPlanet(char *filename)
|
||||||
{
|
{
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
if (!game.currentMission->challengeData.isChallenge)
|
if (!game.currentMission->challengeData.isChallenge)
|
||||||
{
|
{
|
||||||
hash = hashcode(game.selectedStarSystem);
|
hash = hashcode(game.selectedStarSystem);
|
||||||
|
@ -252,14 +244,14 @@ static char *getAutoPlanet(char *filename)
|
||||||
{
|
{
|
||||||
hash = hashcode(filename);
|
hash = hashcode(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getPlanetTextureName(hash);
|
return getPlanetTextureName(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getAutoMusic(char *filename)
|
static char *getAutoMusic(char *filename)
|
||||||
{
|
{
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
if (!game.currentMission->challengeData.isChallenge)
|
if (!game.currentMission->challengeData.isChallenge)
|
||||||
{
|
{
|
||||||
hash = hashcode(game.selectedStarSystem);
|
hash = hashcode(game.selectedStarSystem);
|
||||||
|
@ -268,7 +260,7 @@ static char *getAutoMusic(char *filename)
|
||||||
{
|
{
|
||||||
hash = hashcode(filename);
|
hash = hashcode(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getMusicFilename(hash);
|
return getMusicFilename(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,13 +271,13 @@ void completeMission(void)
|
||||||
battle.status = MS_COMPLETE;
|
battle.status = MS_COMPLETE;
|
||||||
battle.missionFinishedTimer = FPS;
|
battle.missionFinishedTimer = FPS;
|
||||||
selectWidget("continue", "battleWon");
|
selectWidget("continue", "battleWon");
|
||||||
|
|
||||||
game.stats[STAT_MISSIONS_COMPLETED]++;
|
game.stats[STAT_MISSIONS_COMPLETED]++;
|
||||||
|
|
||||||
completeConditions();
|
completeConditions();
|
||||||
|
|
||||||
retreatEnemies();
|
retreatEnemies();
|
||||||
|
|
||||||
player->flags |= EF_IMMORTAL;
|
player->flags |= EF_IMMORTAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,9 +289,9 @@ void failMission(void)
|
||||||
battle.status = MS_FAILED;
|
battle.status = MS_FAILED;
|
||||||
battle.missionFinishedTimer = FPS;
|
battle.missionFinishedTimer = FPS;
|
||||||
selectWidget("retry", "battleLost");
|
selectWidget("retry", "battleLost");
|
||||||
|
|
||||||
failIncompleteObjectives();
|
failIncompleteObjectives();
|
||||||
|
|
||||||
player->flags |= EF_IMMORTAL;
|
player->flags |= EF_IMMORTAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,40 +299,32 @@ void failMission(void)
|
||||||
static void loadObjectives(cJSON *node)
|
static void loadObjectives(cJSON *node)
|
||||||
{
|
{
|
||||||
Objective *o;
|
Objective *o;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
o = malloc(sizeof(Objective));
|
o = malloc(sizeof(Objective));
|
||||||
memset(o, 0, sizeof(Objective));
|
memset(o, 0, sizeof(Objective));
|
||||||
battle.objectiveTail->next = o;
|
battle.objectiveTail->next = o;
|
||||||
battle.objectiveTail = o;
|
battle.objectiveTail = o;
|
||||||
|
|
||||||
o->active = 1;
|
o->active = 1;
|
||||||
STRNCPY(o->description, _(cJSON_GetObjectItem(node, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
STRNCPY(o->description, _(cJSON_GetObjectItem(node, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
||||||
STRNCPY(o->targetName, cJSON_GetObjectItem(node, "targetName")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(o->targetName, cJSON_GetObjectItem(node, "targetName")->valuestring, MAX_NAME_LENGTH);
|
||||||
o->targetValue = cJSON_GetObjectItem(node, "targetValue")->valueint;
|
o->targetValue = cJSON_GetObjectItem(node, "targetValue")->valueint;
|
||||||
o->targetType = lookup(cJSON_GetObjectItem(node, "targetType")->valuestring);
|
o->targetType = lookup(cJSON_GetObjectItem(node, "targetType")->valuestring);
|
||||||
|
o->active = getJSONValue(node, "active", 0);
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
o->isCondition = getJSONValue(node, "isCondition", 0);
|
||||||
|
|
||||||
|
o->isEliminateAll = getJSONValue(node, "isEliminateAll", 0);
|
||||||
|
if (isEliminateAll)
|
||||||
{
|
{
|
||||||
o->active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "isCondition"))
|
|
||||||
{
|
|
||||||
o->isCondition = cJSON_GetObjectItem(node, "isCondition")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "isEliminateAll"))
|
|
||||||
{
|
|
||||||
o->isEliminateAll = cJSON_GetObjectItem(node, "isEliminateAll")->valueint;
|
|
||||||
o->targetValue = 1;
|
o->targetValue = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,25 +334,25 @@ static void loadPlayer(cJSON *node)
|
||||||
{
|
{
|
||||||
char *type;
|
char *type;
|
||||||
int side;
|
int side;
|
||||||
|
|
||||||
type = cJSON_GetObjectItem(node, "type")->valuestring;
|
type = cJSON_GetObjectItem(node, "type")->valuestring;
|
||||||
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
||||||
|
|
||||||
player = spawnFighter(type, 0, 0, side);
|
player = spawnFighter(type, 0, 0, side);
|
||||||
player->x = BATTLE_AREA_WIDTH / 2;
|
player->x = BATTLE_AREA_WIDTH / 2;
|
||||||
player->y = BATTLE_AREA_HEIGHT / 2;
|
player->y = BATTLE_AREA_HEIGHT / 2;
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "x"))
|
if (cJSON_GetObjectItem(node, "x"))
|
||||||
{
|
{
|
||||||
player->x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
player->x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
||||||
player->y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
player->y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, "Tug") == 0)
|
if (strcmp(type, "Tug") == 0)
|
||||||
{
|
{
|
||||||
battle.stats[STAT_TUG]++;
|
battle.stats[STAT_TUG]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, "Shuttle") == 0)
|
if (strcmp(type, "Shuttle") == 0)
|
||||||
{
|
{
|
||||||
battle.stats[STAT_SHUTTLE]++;
|
battle.stats[STAT_SHUTTLE]++;
|
||||||
|
@ -383,11 +367,11 @@ static void loadFighters(cJSON *node)
|
||||||
int i, numTypes, addFlags, addAIFlags;
|
int i, numTypes, addFlags, addAIFlags;
|
||||||
long flags, aiFlags;
|
long flags, aiFlags;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
name = NULL;
|
name = NULL;
|
||||||
|
@ -397,61 +381,41 @@ static void loadFighters(cJSON *node)
|
||||||
scatter = 1;
|
scatter = 1;
|
||||||
active = 1;
|
active = 1;
|
||||||
number = 1;
|
number = 1;
|
||||||
|
|
||||||
types = toTypeArray(cJSON_GetObjectItem(node, "types")->valuestring, &numTypes);
|
types = toTypeArray(cJSON_GetObjectItem(node, "types")->valuestring, &numTypes);
|
||||||
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
||||||
x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
||||||
y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
||||||
|
name = getJSONValueStr(node, "name", NULL);
|
||||||
if (cJSON_GetObjectItem(node, "name"))
|
groupName = getJSONValueStr(node, "groupName", NULL);
|
||||||
{
|
number = getJSONValue(node, "number", 0);
|
||||||
name = cJSON_GetObjectItem(node, "name")->valuestring;
|
scatter = getJSONValue(node, "scatter", 0);
|
||||||
}
|
active = getJSONValue(node, "active", 0);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "groupName"))
|
|
||||||
{
|
|
||||||
groupName = cJSON_GetObjectItem(node, "groupName")->valuestring;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "number"))
|
|
||||||
{
|
|
||||||
number = cJSON_GetObjectItem(node, "number")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "scatter"))
|
|
||||||
{
|
|
||||||
scatter = cJSON_GetObjectItem(node, "scatter")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
|
||||||
{
|
|
||||||
active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "flags"))
|
if (cJSON_GetObjectItem(node, "flags"))
|
||||||
{
|
{
|
||||||
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "aiFlags"))
|
if (cJSON_GetObjectItem(node, "aiFlags"))
|
||||||
{
|
{
|
||||||
aiFlags = flagsToLong(cJSON_GetObjectItem(node, "aiFlags")->valuestring, &addAIFlags);
|
aiFlags = flagsToLong(cJSON_GetObjectItem(node, "aiFlags")->valuestring, &addAIFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < number ; i++)
|
for (i = 0 ; i < number ; i++)
|
||||||
{
|
{
|
||||||
type = types[rand() % numTypes];
|
type = types[rand() % numTypes];
|
||||||
|
|
||||||
e = spawnFighter(type, x, y, side);
|
e = spawnFighter(type, x, y, side);
|
||||||
|
|
||||||
if (scatter > 1)
|
if (scatter > 1)
|
||||||
{
|
{
|
||||||
e->x += (rand() % scatter) - (rand() % scatter);
|
e->x += (rand() % scatter) - (rand() % scatter);
|
||||||
e->y += (rand() % scatter) - (rand() % scatter);
|
e->y += (rand() % scatter) - (rand() % scatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->active = active;
|
e->active = active;
|
||||||
|
|
||||||
if (flags != -1)
|
if (flags != -1)
|
||||||
{
|
{
|
||||||
if (addFlags)
|
if (addFlags)
|
||||||
|
@ -461,11 +425,11 @@ static void loadFighters(cJSON *node)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e->flags = flags;
|
e->flags = flags;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiFlags != -1)
|
if (aiFlags != -1)
|
||||||
{
|
{
|
||||||
if (addAIFlags)
|
if (addAIFlags)
|
||||||
|
@ -475,29 +439,29 @@ static void loadFighters(cJSON *node)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e->aiFlags = aiFlags;
|
e->aiFlags = aiFlags;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "AI Flags for '%s' (%s) replaced", e->name, e->defName);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "AI Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupName)
|
if (groupName)
|
||||||
{
|
{
|
||||||
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
|
||||||
for (i = 0 ; i < numTypes ; i++)
|
for (i = 0 ; i < numTypes ; i++)
|
||||||
{
|
{
|
||||||
free(types[i]);
|
free(types[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(types);
|
free(types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,11 +475,11 @@ static void loadCapitalShips(cJSON *node)
|
||||||
int i, numTypes, addFlags;
|
int i, numTypes, addFlags;
|
||||||
long flags;
|
long flags;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
name = NULL;
|
name = NULL;
|
||||||
|
@ -524,66 +488,46 @@ static void loadCapitalShips(cJSON *node)
|
||||||
active = 1;
|
active = 1;
|
||||||
number = 1;
|
number = 1;
|
||||||
flags = -1;
|
flags = -1;
|
||||||
|
|
||||||
types = toTypeArray(cJSON_GetObjectItem(node, "types")->valuestring, &numTypes);
|
types = toTypeArray(cJSON_GetObjectItem(node, "types")->valuestring, &numTypes);
|
||||||
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
side = lookup(cJSON_GetObjectItem(node, "side")->valuestring);
|
||||||
x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
||||||
y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
||||||
|
name = cJSON_GetObjectItem(node, "name", NULL);
|
||||||
if (cJSON_GetObjectItem(node, "name"))
|
groupName = getJSONValueStr(node, "groupName", NULL);
|
||||||
{
|
number = getJSONValueStr(node, "number", 0);
|
||||||
name = cJSON_GetObjectItem(node, "name")->valuestring;
|
scatter = getJSONValueStr(node, "scatter", 0);
|
||||||
}
|
active = getJSONValue(node, "active", 0);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "groupName"))
|
|
||||||
{
|
|
||||||
groupName = cJSON_GetObjectItem(node, "groupName")->valuestring;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "number"))
|
|
||||||
{
|
|
||||||
number = cJSON_GetObjectItem(node, "number")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "scatter"))
|
|
||||||
{
|
|
||||||
scatter = cJSON_GetObjectItem(node, "scatter")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
|
||||||
{
|
|
||||||
active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "flags"))
|
if (cJSON_GetObjectItem(node, "flags"))
|
||||||
{
|
{
|
||||||
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < number ; i++)
|
for (i = 0 ; i < number ; i++)
|
||||||
{
|
{
|
||||||
type = types[rand() % numTypes];
|
type = types[rand() % numTypes];
|
||||||
|
|
||||||
e = spawnCapitalShip(type, x, y, side);
|
e = spawnCapitalShip(type, x, y, side);
|
||||||
|
|
||||||
if (scatter > 1)
|
if (scatter > 1)
|
||||||
{
|
{
|
||||||
e->x += (rand() % scatter) - (rand() % scatter);
|
e->x += (rand() % scatter) - (rand() % scatter);
|
||||||
e->y += (rand() % scatter) - (rand() % scatter);
|
e->y += (rand() % scatter) - (rand() % scatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->active = active;
|
e->active = active;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupName)
|
if (groupName)
|
||||||
{
|
{
|
||||||
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags != -1)
|
if (flags != -1)
|
||||||
{
|
{
|
||||||
if (addFlags)
|
if (addFlags)
|
||||||
|
@ -593,21 +537,21 @@ static void loadCapitalShips(cJSON *node)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e->flags = flags;
|
e->flags = flags;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCapitalShipComponentProperties(e);
|
updateCapitalShipComponentProperties(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
|
||||||
for (i = 0 ; i < numTypes ; i++)
|
for (i = 0 ; i < numTypes ; i++)
|
||||||
{
|
{
|
||||||
free(types[i]);
|
free(types[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(types);
|
free(types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,11 +563,11 @@ static void loadEntities(cJSON *node)
|
||||||
char *name, *groupName;
|
char *name, *groupName;
|
||||||
int i, type, scatter, number, active;
|
int i, type, scatter, number, active;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
e = NULL;
|
e = NULL;
|
||||||
|
@ -635,32 +579,17 @@ static void loadEntities(cJSON *node)
|
||||||
number = 1;
|
number = 1;
|
||||||
active = 1;
|
active = 1;
|
||||||
scatter = 1;
|
scatter = 1;
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "name"))
|
name = getJSONValueStr(node, "name", NULL);
|
||||||
{
|
|
||||||
name = cJSON_GetObjectItem(node, "name")->valuestring;
|
groupName = getJSONValueStr(node, "groupName", NULL);
|
||||||
}
|
|
||||||
|
number = getJSONValue(node, "number", 0);
|
||||||
if (cJSON_GetObjectItem(node, "groupName"))
|
|
||||||
{
|
active = getJSONValue(node, "active", 0);
|
||||||
groupName = cJSON_GetObjectItem(node, "groupName")->valuestring;
|
|
||||||
}
|
scatter = getJSONValue(node, "scatter", 0);
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "number"))
|
|
||||||
{
|
|
||||||
number = cJSON_GetObjectItem(node, "number")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
|
||||||
{
|
|
||||||
active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "scatter"))
|
|
||||||
{
|
|
||||||
scatter = cJSON_GetObjectItem(node, "scatter")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < number ; i++)
|
for (i = 0 ; i < number ; i++)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -668,41 +597,41 @@ static void loadEntities(cJSON *node)
|
||||||
case ET_WAYPOINT:
|
case ET_WAYPOINT:
|
||||||
e = spawnWaypoint();
|
e = spawnWaypoint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ET_EXTRACTION_POINT:
|
case ET_EXTRACTION_POINT:
|
||||||
e = spawnExtractionPoint();
|
e = spawnExtractionPoint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Error: Unhandled entity type: %s\n", cJSON_GetObjectItem(node, "type")->valuestring);
|
printf("Error: Unhandled entity type: %s\n", cJSON_GetObjectItem(node, "type")->valuestring);
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupName)
|
if (groupName)
|
||||||
{
|
{
|
||||||
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->x = x;
|
e->x = x;
|
||||||
e->y = y;
|
e->y = y;
|
||||||
|
|
||||||
if (scatter > 1)
|
if (scatter > 1)
|
||||||
{
|
{
|
||||||
e->x += (rand() % scatter) - (rand() % scatter);
|
e->x += (rand() % scatter) - (rand() % scatter);
|
||||||
e->y += (rand() % scatter) - (rand() % scatter);
|
e->y += (rand() % scatter) - (rand() % scatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->active = active;
|
e->active = active;
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,14 +644,14 @@ static void loadItems(cJSON *node)
|
||||||
int i, scatter, number, active, addFlags;
|
int i, scatter, number, active, addFlags;
|
||||||
long flags;
|
long flags;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
flags = -1;
|
flags = -1;
|
||||||
scatter = 1;
|
scatter = 1;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
type = cJSON_GetObjectItem(node, "type")->valuestring;
|
type = cJSON_GetObjectItem(node, "type")->valuestring;
|
||||||
|
@ -732,51 +661,36 @@ static void loadItems(cJSON *node)
|
||||||
groupName = NULL;
|
groupName = NULL;
|
||||||
number = 1;
|
number = 1;
|
||||||
active = 1;
|
active = 1;
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "name"))
|
name = getJSONValueStr(node, "name", NULL);
|
||||||
{
|
|
||||||
name = cJSON_GetObjectItem(node, "name")->valuestring;
|
groupName = getJSONValueStr(node, "groupName", NULL);
|
||||||
}
|
|
||||||
|
number = getJSONValue(node, "number", 0);
|
||||||
if (cJSON_GetObjectItem(node, "groupName"))
|
|
||||||
{
|
scatter = getJSONValue(node, "scatter", 0);
|
||||||
groupName = cJSON_GetObjectItem(node, "groupName")->valuestring;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "number"))
|
|
||||||
{
|
|
||||||
number = cJSON_GetObjectItem(node, "number")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "scatter"))
|
|
||||||
{
|
|
||||||
scatter = cJSON_GetObjectItem(node, "scatter")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "flags"))
|
if (cJSON_GetObjectItem(node, "flags"))
|
||||||
{
|
{
|
||||||
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
active = getJSONValue(node, "active", 0);
|
||||||
{
|
|
||||||
active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < number ; i++)
|
for (i = 0 ; i < number ; i++)
|
||||||
{
|
{
|
||||||
e = spawnItem(type);
|
e = spawnItem(type);
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupName)
|
if (groupName)
|
||||||
{
|
{
|
||||||
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags != -1)
|
if (flags != -1)
|
||||||
{
|
{
|
||||||
if (addFlags)
|
if (addFlags)
|
||||||
|
@ -786,24 +700,24 @@ static void loadItems(cJSON *node)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e->flags = flags;
|
e->flags = flags;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e->x = x;
|
e->x = x;
|
||||||
e->y = y;
|
e->y = y;
|
||||||
e->active = active;
|
e->active = active;
|
||||||
|
|
||||||
if (scatter > 1)
|
if (scatter > 1)
|
||||||
{
|
{
|
||||||
e->x += (rand() % scatter) - (rand() % scatter);
|
e->x += (rand() % scatter) - (rand() % scatter);
|
||||||
e->y += (rand() % scatter) - (rand() % scatter);
|
e->y += (rand() % scatter) - (rand() % scatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,35 +727,32 @@ static void loadLocations(cJSON *node)
|
||||||
{
|
{
|
||||||
int active;
|
int active;
|
||||||
Location *l;
|
Location *l;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
active = 1;
|
active = 1;
|
||||||
|
|
||||||
l = malloc(sizeof(Location));
|
l = malloc(sizeof(Location));
|
||||||
memset(l, 0, sizeof(Location));
|
memset(l, 0, sizeof(Location));
|
||||||
battle.locationTail->next = l;
|
battle.locationTail->next = l;
|
||||||
battle.locationTail = l;
|
battle.locationTail = l;
|
||||||
|
|
||||||
STRNCPY(l->name, cJSON_GetObjectItem(node, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(l->name, cJSON_GetObjectItem(node, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
l->x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
l->x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH;
|
||||||
l->y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
l->y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT;
|
||||||
|
|
||||||
l->size = cJSON_GetObjectItem(node, "size")->valueint;
|
l->size = cJSON_GetObjectItem(node, "size")->valueint;
|
||||||
|
|
||||||
if (cJSON_GetObjectItem(node, "active"))
|
active = getJSONValue(node, "active", 0);
|
||||||
{
|
|
||||||
active = cJSON_GetObjectItem(node, "active")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
l->x += (SCREEN_WIDTH / 2);
|
l->x += (SCREEN_WIDTH / 2);
|
||||||
l->y += (SCREEN_HEIGHT / 2);
|
l->y += (SCREEN_HEIGHT / 2);
|
||||||
l->active = active;
|
l->active = active;
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,9 +762,9 @@ static char **toTypeArray(char *types, int *numTypes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char **typeArray, *type;
|
char **typeArray, *type;
|
||||||
|
|
||||||
*numTypes = 1;
|
*numTypes = 1;
|
||||||
|
|
||||||
for (i = 0 ; i < strlen(types) ; i++)
|
for (i = 0 ; i < strlen(types) ; i++)
|
||||||
{
|
{
|
||||||
if (types[i] == ';')
|
if (types[i] == ';')
|
||||||
|
@ -863,19 +774,19 @@ static char **toTypeArray(char *types, int *numTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
typeArray = malloc(*numTypes * sizeof(char*));
|
typeArray = malloc(*numTypes * sizeof(char*));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
type = strtok(types, ";");
|
type = strtok(types, ";");
|
||||||
while (type)
|
while (type)
|
||||||
{
|
{
|
||||||
typeArray[i] = malloc(strlen(type) + 1);
|
typeArray[i] = malloc(strlen(type) + 1);
|
||||||
strcpy(typeArray[i], type);
|
strcpy(typeArray[i], type);
|
||||||
|
|
||||||
type = strtok(NULL, ";");
|
type = strtok(NULL, ";");
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeArray;
|
return typeArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,11 +795,11 @@ static void loadEpicData(cJSON *node)
|
||||||
Entity *e;
|
Entity *e;
|
||||||
int numFighters[SIDE_MAX];
|
int numFighters[SIDE_MAX];
|
||||||
memset(numFighters, 0, sizeof(int) * SIDE_MAX);
|
memset(numFighters, 0, sizeof(int) * SIDE_MAX);
|
||||||
|
|
||||||
battle.isEpic = 1;
|
battle.isEpic = 1;
|
||||||
|
|
||||||
battle.epicFighterLimit = cJSON_GetObjectItem(node, "fighterLimit")->valueint;
|
battle.epicFighterLimit = cJSON_GetObjectItem(node, "fighterLimit")->valueint;
|
||||||
|
|
||||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||||
{
|
{
|
||||||
if (e->active && e->type == ET_FIGHTER && numFighters[e->side]++ >= battle.epicFighterLimit)
|
if (e->active && e->type == ET_FIGHTER && numFighters[e->side]++ >= battle.epicFighterLimit)
|
||||||
|
@ -902,7 +813,7 @@ Mission *getMission(char *filename)
|
||||||
{
|
{
|
||||||
StarSystem *starSystem;
|
StarSystem *starSystem;
|
||||||
Mission *mission;
|
Mission *mission;
|
||||||
|
|
||||||
/* First, search the star systems */
|
/* First, search the star systems */
|
||||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||||
{
|
{
|
||||||
|
@ -914,7 +825,7 @@ Mission *getMission(char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now search the challenges */
|
/* now search the challenges */
|
||||||
for (mission = game.challengeMissionHead.next ; mission != NULL ; mission = mission->next)
|
for (mission = game.challengeMissionHead.next ; mission != NULL ; mission = mission->next)
|
||||||
{
|
{
|
||||||
|
@ -923,16 +834,16 @@ Mission *getMission(char *filename)
|
||||||
return mission;
|
return mission;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "No such mission '%s'", filename);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "No such mission '%s'", filename);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateAllMissions(void)
|
void updateAllMissions(void)
|
||||||
{
|
{
|
||||||
updateStarSystemMissions();
|
updateStarSystemMissions();
|
||||||
|
|
||||||
updateChallengeMissions();
|
updateChallengeMissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,6 +865,6 @@ static unsigned long hashcode(const char *str)
|
||||||
|
|
||||||
c = *str++;
|
c = *str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return abs(hash);
|
return abs(hash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ extern void updateChallengeMissions(void);
|
||||||
extern char *getBackgroundTextureName(int n);
|
extern char *getBackgroundTextureName(int n);
|
||||||
extern char *getPlanetTextureName(int n);
|
extern char *getPlanetTextureName(int n);
|
||||||
extern char *getMusicFilename(int n);
|
extern char *getMusicFilename(int n);
|
||||||
|
extern int getJSONValue(cJSON *node, char *name, int defValue);
|
||||||
|
extern char *getJSONValueStr(cJSON *node, char *name, char *defValue);
|
||||||
|
|
||||||
extern Battle battle;
|
extern Battle battle;
|
||||||
extern Entity *player;
|
extern Entity *player;
|
||||||
|
|
|
@ -28,19 +28,19 @@ void initStarSystems(void)
|
||||||
cJSON *root, *node;
|
cJSON *root, *node;
|
||||||
char *text;
|
char *text;
|
||||||
StarSystem *starSystem, *tail;
|
StarSystem *starSystem, *tail;
|
||||||
|
|
||||||
tail = &game.starSystemHead;
|
tail = &game.starSystemHead;
|
||||||
|
|
||||||
text = readFile(getFileLocation("data/galaxy/starSystems.json"));
|
text = readFile(getFileLocation("data/galaxy/starSystems.json"));
|
||||||
root = cJSON_Parse(text);
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
for (node = cJSON_GetObjectItem(root, "starSystems")->child ; node != NULL ; node = node->next)
|
for (node = cJSON_GetObjectItem(root, "starSystems")->child ; node != NULL ; node = node->next)
|
||||||
{
|
{
|
||||||
starSystem = loadStarSystem(node);
|
starSystem = loadStarSystem(node);
|
||||||
tail->next = starSystem;
|
tail->next = starSystem;
|
||||||
tail = starSystem;
|
tail = starSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
@ -48,32 +48,28 @@ void initStarSystems(void)
|
||||||
static StarSystem *loadStarSystem(cJSON *starSystemJSON)
|
static StarSystem *loadStarSystem(cJSON *starSystemJSON)
|
||||||
{
|
{
|
||||||
StarSystem *starSystem;
|
StarSystem *starSystem;
|
||||||
|
|
||||||
starSystem = malloc(sizeof(StarSystem));
|
starSystem = malloc(sizeof(StarSystem));
|
||||||
memset(starSystem, 0, sizeof(StarSystem));
|
memset(starSystem, 0, sizeof(StarSystem));
|
||||||
|
|
||||||
STRNCPY(starSystem->name, cJSON_GetObjectItem(starSystemJSON, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(starSystem->name, cJSON_GetObjectItem(starSystemJSON, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
starSystem->side = lookup(cJSON_GetObjectItem(starSystemJSON, "side")->valuestring);
|
starSystem->side = lookup(cJSON_GetObjectItem(starSystemJSON, "side")->valuestring);
|
||||||
starSystem->x = cJSON_GetObjectItem(starSystemJSON, "x")->valueint;
|
starSystem->x = cJSON_GetObjectItem(starSystemJSON, "x")->valueint;
|
||||||
starSystem->y = cJSON_GetObjectItem(starSystemJSON, "y")->valueint;
|
starSystem->y = cJSON_GetObjectItem(starSystemJSON, "y")->valueint;
|
||||||
|
starSystem->fallsToPandorans = getJSONValue(starSystemJSON, "fallsToPandorans", 0);
|
||||||
if (cJSON_GetObjectItem(starSystemJSON, "fallsToPandorans"))
|
|
||||||
{
|
|
||||||
starSystem->fallsToPandorans = cJSON_GetObjectItem(starSystemJSON, "fallsToPandorans")->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(starSystem->name, "Sol") == 0)
|
if (strcmp(starSystem->name, "Sol") == 0)
|
||||||
{
|
{
|
||||||
starSystem->isSol = 1;
|
starSystem->isSol = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
starSystem->missionHead.completed = 1;
|
starSystem->missionHead.completed = 1;
|
||||||
|
|
||||||
loadMissions(starSystem);
|
loadMissions(starSystem);
|
||||||
|
|
||||||
starSystem->x *= 3;
|
starSystem->x *= 3;
|
||||||
starSystem->y *= 3;
|
starSystem->y *= 3;
|
||||||
|
|
||||||
return starSystem;
|
return starSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,38 +80,38 @@ static void loadMissions(StarSystem *starSystem)
|
||||||
char path[MAX_FILENAME_LENGTH];
|
char path[MAX_FILENAME_LENGTH];
|
||||||
char **filenames;
|
char **filenames;
|
||||||
Mission *mission, *tail;
|
Mission *mission, *tail;
|
||||||
|
|
||||||
tail = &starSystem->missionHead;
|
tail = &starSystem->missionHead;
|
||||||
|
|
||||||
STRNCPY(name, starSystem->name, MAX_NAME_LENGTH);
|
STRNCPY(name, starSystem->name, MAX_NAME_LENGTH);
|
||||||
|
|
||||||
for (i = 0 ; name[i] ; i++)
|
for (i = 0 ; name[i] ; i++)
|
||||||
{
|
{
|
||||||
name[i] = tolower(name[i]);
|
name[i] = tolower(name[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(path, "data/missions/%s", name);
|
sprintf(path, "data/missions/%s", name);
|
||||||
|
|
||||||
filenames = getFileList(getFileLocation(path), &count);
|
filenames = getFileList(getFileLocation(path), &count);
|
||||||
|
|
||||||
for (i = 0 ; i < count ; i++)
|
for (i = 0 ; i < count ; i++)
|
||||||
{
|
{
|
||||||
sprintf(path, "data/missions/%s/%s", name, filenames[i]);
|
sprintf(path, "data/missions/%s/%s", name, filenames[i]);
|
||||||
|
|
||||||
mission = loadMissionMeta(path);
|
mission = loadMissionMeta(path);
|
||||||
tail->next = mission;
|
tail->next = mission;
|
||||||
tail = mission;
|
tail = mission;
|
||||||
|
|
||||||
free(filenames[i]);
|
free(filenames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filenames);
|
free(filenames);
|
||||||
}
|
}
|
||||||
|
|
||||||
StarSystem *getStarSystem(char *name)
|
StarSystem *getStarSystem(char *name)
|
||||||
{
|
{
|
||||||
StarSystem *starSystem;
|
StarSystem *starSystem;
|
||||||
|
|
||||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||||
{
|
{
|
||||||
if (strcmp(starSystem->name, name) == 0)
|
if (strcmp(starSystem->name, name) == 0)
|
||||||
|
@ -123,7 +119,7 @@ StarSystem *getStarSystem(char *name)
|
||||||
return starSystem;
|
return starSystem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,51 +127,51 @@ void updateStarSystemMissions(void)
|
||||||
{
|
{
|
||||||
StarSystem *starSystem;
|
StarSystem *starSystem;
|
||||||
Mission *mission, *prev;
|
Mission *mission, *prev;
|
||||||
|
|
||||||
game.completedMissions = game.totalMissions = game.availableMissions = 0;
|
game.completedMissions = game.totalMissions = game.availableMissions = 0;
|
||||||
|
|
||||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||||
{
|
{
|
||||||
starSystem->completedMissions = starSystem->availableMissions = starSystem->totalMissions = 0;
|
starSystem->completedMissions = starSystem->availableMissions = starSystem->totalMissions = 0;
|
||||||
|
|
||||||
for (mission = starSystem->missionHead.next ; mission != NULL ; mission = mission->next)
|
for (mission = starSystem->missionHead.next ; mission != NULL ; mission = mission->next)
|
||||||
{
|
{
|
||||||
starSystem->totalMissions++;
|
starSystem->totalMissions++;
|
||||||
|
|
||||||
if (mission->completed)
|
if (mission->completed)
|
||||||
{
|
{
|
||||||
starSystem->completedMissions++;
|
starSystem->completedMissions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(starSystem->name, "Sol") != 0)
|
if (strcmp(starSystem->name, "Sol") != 0)
|
||||||
{
|
{
|
||||||
game.totalMissions += starSystem->totalMissions;
|
game.totalMissions += starSystem->totalMissions;
|
||||||
game.completedMissions += starSystem->completedMissions;
|
game.completedMissions += starSystem->completedMissions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||||
{
|
{
|
||||||
prev = &starSystem->missionHead;
|
prev = &starSystem->missionHead;
|
||||||
|
|
||||||
for (mission = starSystem->missionHead.next ; mission != NULL ; mission = mission->next)
|
for (mission = starSystem->missionHead.next ; mission != NULL ; mission = mission->next)
|
||||||
{
|
{
|
||||||
mission->available = strcmp(starSystem->name, "Sol") == 0 || isMissionAvailable(mission, prev);
|
mission->available = strcmp(starSystem->name, "Sol") == 0 || isMissionAvailable(mission, prev);
|
||||||
|
|
||||||
if (mission->available)
|
if (mission->available)
|
||||||
{
|
{
|
||||||
starSystem->availableMissions++;
|
starSystem->availableMissions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = mission;
|
prev = mission;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(starSystem->name, "Sol") != 0)
|
if (strcmp(starSystem->name, "Sol") != 0)
|
||||||
{
|
{
|
||||||
game.availableMissions += starSystem->availableMissions;
|
game.availableMissions += starSystem->availableMissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(starSystem->description, "[ %s ] [ Missions %d / %d ]", starSystem->name, starSystem->completedMissions, starSystem->availableMissions);
|
sprintf(starSystem->description, "[ %s ] [ Missions %d / %d ]", starSystem->name, starSystem->completedMissions, starSystem->availableMissions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,18 +180,18 @@ void destroyStarSystems(void)
|
||||||
{
|
{
|
||||||
StarSystem *starSystem;
|
StarSystem *starSystem;
|
||||||
Mission *mission;
|
Mission *mission;
|
||||||
|
|
||||||
while (game.starSystemHead.next)
|
while (game.starSystemHead.next)
|
||||||
{
|
{
|
||||||
starSystem = game.starSystemHead.next;
|
starSystem = game.starSystemHead.next;
|
||||||
|
|
||||||
while (starSystem->missionHead.next)
|
while (starSystem->missionHead.next)
|
||||||
{
|
{
|
||||||
mission = starSystem->missionHead.next;
|
mission = starSystem->missionHead.next;
|
||||||
starSystem->missionHead.next = mission->next;
|
starSystem->missionHead.next = mission->next;
|
||||||
free(mission);
|
free(mission);
|
||||||
}
|
}
|
||||||
|
|
||||||
game.starSystemHead.next = starSystem->next;
|
game.starSystemHead.next = starSystem->next;
|
||||||
free(starSystem);
|
free(starSystem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,5 +28,6 @@ extern int isMissionAvailable(Mission *mission, Mission *prev);
|
||||||
extern char *getFileLocation(char *filename);
|
extern char *getFileLocation(char *filename);
|
||||||
extern char **getFileList(char *dir, int *count);
|
extern char **getFileList(char *dir, int *count);
|
||||||
extern Mission *loadMissionMeta(char *filename);
|
extern Mission *loadMissionMeta(char *filename);
|
||||||
|
extern int getJSONValue(cJSON *node, char *name, int defValue);
|
||||||
|
|
||||||
extern Game game;
|
extern Game game;
|
||||||
|
|
|
@ -49,10 +49,10 @@ float getAngle(int x1, int y1, int x2, int y2)
|
||||||
int getDistance(int x1, int y1, int x2, int y2)
|
int getDistance(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
x = x2 - x1;
|
x = x2 - x1;
|
||||||
y = y2 - y1;
|
y = y2 - y1;
|
||||||
|
|
||||||
return sqrt(x * x + y *y);
|
return sqrt(x * x + y *y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,14 +76,14 @@ void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy)
|
||||||
char *timeToString(long millis, int showHours)
|
char *timeToString(long millis, int showHours)
|
||||||
{
|
{
|
||||||
static char TIME[MAX_NAME_LENGTH];
|
static char TIME[MAX_NAME_LENGTH];
|
||||||
|
|
||||||
int hours, minutes, seconds;
|
int hours, minutes, seconds;
|
||||||
|
|
||||||
seconds = millis / FPS;
|
seconds = millis / FPS;
|
||||||
minutes = (seconds / 60) % 60;
|
minutes = (seconds / 60) % 60;
|
||||||
hours = seconds / (60 * 60);
|
hours = seconds / (60 * 60);
|
||||||
seconds %= 60;
|
seconds %= 60;
|
||||||
|
|
||||||
if (showHours)
|
if (showHours)
|
||||||
{
|
{
|
||||||
sprintf(TIME, "%dh:%02dm:%02ds", hours, minutes, seconds);
|
sprintf(TIME, "%dh:%02dm:%02ds", hours, minutes, seconds);
|
||||||
|
@ -92,6 +92,33 @@ char *timeToString(long millis, int showHours)
|
||||||
{
|
{
|
||||||
sprintf(TIME, "%dm %02ds", minutes, seconds);
|
sprintf(TIME, "%dm %02ds", minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TIME;
|
return TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *getJSONValueStr(cJSON *node, char *name, char *defValue)
|
||||||
|
{
|
||||||
|
cJSON *child;
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
child = cJSON_GetObjectItem(node, name);
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
return child->valuestring;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getJSONValue(cJSON *node, char *name, int defValue)
|
||||||
|
{
|
||||||
|
char *result = getJSONValueStr(node, name, defValue);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return aoti(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue