Trim all whitespace.
This commit is contained in:
parent
98274ffa34
commit
3329d1375a
346
src/battle/ai.c
346
src/battle/ai.c
File diff suppressed because it is too large
Load Diff
|
@ -57,7 +57,7 @@ void initBattle(void)
|
|||
app.delegate.logic = &logic;
|
||||
app.delegate.draw = &draw;
|
||||
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
||||
|
||||
|
||||
battle.hasThreats = 1;
|
||||
|
||||
initQuadtree(&battle.quadtree);
|
||||
|
@ -96,7 +96,7 @@ void initBattle(void)
|
|||
getWidget("quit", "battleLost")->action = quitBattle;
|
||||
|
||||
selectWidget("ok", "startBattle");
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 1);
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,9 @@ static void logic(void)
|
|||
doPlayerSelect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
app.doTrophyAlerts = (battle.status != MS_IN_PROGRESS && battle.missionFinishedTimer <= -FPS * 2);
|
||||
|
||||
|
||||
if (battle.campaignFinished)
|
||||
{
|
||||
endCampaign();
|
||||
|
@ -163,9 +163,9 @@ static void doBattle(void)
|
|||
doDebris();
|
||||
|
||||
doPlayer();
|
||||
|
||||
|
||||
checkSuspicionLevel();
|
||||
|
||||
|
||||
doTorelliFireStorm();
|
||||
|
||||
if (player->alive == ALIVE_ALIVE)
|
||||
|
@ -175,7 +175,7 @@ static void doBattle(void)
|
|||
doLocations();
|
||||
|
||||
doMessageBox();
|
||||
|
||||
|
||||
if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE)
|
||||
{
|
||||
doScript();
|
||||
|
@ -186,7 +186,7 @@ static void doBattle(void)
|
|||
if (battle.stats[STAT_TIME]++ % FPS == 0)
|
||||
{
|
||||
runScriptFunction("TIME %d", battle.stats[STAT_TIME] / FPS);
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.timeLimit && game.currentMission->challengeData.timeLimit - battle.stats[STAT_TIME] < 11 * FPS)
|
||||
{
|
||||
playSound(SND_TIME_WARNING);
|
||||
|
@ -198,11 +198,11 @@ static void doBattle(void)
|
|||
if (battle.status != MS_IN_PROGRESS)
|
||||
{
|
||||
battle.missionFinishedTimer--;
|
||||
|
||||
|
||||
if (battle.unwinnable && battle.missionFinishedTimer <= -FPS * 6)
|
||||
{
|
||||
battle.status = MS_COMPLETE;
|
||||
|
||||
|
||||
postBattle();
|
||||
|
||||
destroyBattle();
|
||||
|
@ -221,11 +221,11 @@ static void draw(void)
|
|||
}
|
||||
|
||||
drawBackground(battle.background);
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
blitScaled(battle.planetTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight, 0);
|
||||
|
||||
|
||||
if (battle.destroyTorelli)
|
||||
{
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
|
@ -273,14 +273,14 @@ static void draw(void)
|
|||
static void drawMenu(void)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
if (app.modalDialog.type == MD_NONE)
|
||||
{
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 400;
|
||||
|
@ -294,7 +294,7 @@ static void drawMenu(void)
|
|||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
drawWidgets("inBattle");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
}
|
||||
|
@ -331,9 +331,9 @@ static void handleKeyboard(void)
|
|||
if (battle.status == MS_IN_PROGRESS && app.keyboard[SDL_SCANCODE_TAB])
|
||||
{
|
||||
battle.status = MS_PAUSED;
|
||||
|
||||
|
||||
selectWidget("ok", "startBattle");
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 0);
|
||||
}
|
||||
}
|
||||
|
@ -341,14 +341,14 @@ static void handleKeyboard(void)
|
|||
static void start(void)
|
||||
{
|
||||
battle.status = MS_IN_PROGRESS;
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 1);
|
||||
}
|
||||
|
||||
static void resume(void)
|
||||
{
|
||||
show = SHOW_BATTLE;
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 1);
|
||||
|
||||
clearInput();
|
||||
|
@ -397,7 +397,7 @@ static void restart(void)
|
|||
static void retry(void)
|
||||
{
|
||||
app.modalDialog.type = MD_NONE;
|
||||
|
||||
|
||||
postBattle();
|
||||
|
||||
destroyBattle();
|
||||
|
@ -415,7 +415,7 @@ static void optQuitBattle(void)
|
|||
static void quitBattle(void)
|
||||
{
|
||||
app.modalDialog.type = MD_NONE;
|
||||
|
||||
|
||||
postBattle();
|
||||
|
||||
destroyBattle();
|
||||
|
@ -441,13 +441,13 @@ static void postBattle(void)
|
|||
game.stats[i] += battle.stats[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
game.stats[STAT_EPIC_KILL_STREAK] = MAX(game.stats[STAT_EPIC_KILL_STREAK], battle.stats[STAT_EPIC_KILL_STREAK]);
|
||||
|
||||
updateAccuracyStats(game.stats);
|
||||
|
||||
|
||||
game.currentMission->completed = (game.currentMission->completed || battle.status == MS_COMPLETE || !battle.numObjectivesTotal);
|
||||
|
||||
|
||||
app.saveGame = 1;
|
||||
}
|
||||
|
||||
|
@ -456,11 +456,11 @@ static void checkSuspicionLevel(void)
|
|||
if (battle.hasSuspicionLevel && battle.suspicionLevel >= MAX_SUSPICION_LEVEL)
|
||||
{
|
||||
cancelScript();
|
||||
|
||||
|
||||
resetMessageBox();
|
||||
|
||||
|
||||
runScriptFunction("MAX_SUSPICION_LEVEL");
|
||||
|
||||
|
||||
battle.hasSuspicionLevel = 0;
|
||||
}
|
||||
}
|
||||
|
@ -476,11 +476,11 @@ static void doTorelliFireStorm(void)
|
|||
static void endCampaign(void)
|
||||
{
|
||||
awardTrophy("CAMPAIGN_COMPLETE");
|
||||
|
||||
|
||||
postBattle();
|
||||
|
||||
destroyBattle();
|
||||
|
||||
|
||||
initCredits();
|
||||
}
|
||||
|
||||
|
@ -567,7 +567,7 @@ void destroyBattle(void)
|
|||
destroyBullets();
|
||||
|
||||
destroyEffects();
|
||||
|
||||
|
||||
memset(&battle, 0, sizeof(Battle));
|
||||
battle.bulletTail = &battle.bulletHead;
|
||||
battle.debrisTail = &battle.debrisHead;
|
||||
|
|
|
@ -179,7 +179,7 @@ static void checkCollisions(Bullet *b)
|
|||
{
|
||||
battle.stats[STAT_ROCKETS_HIT]++;
|
||||
}
|
||||
|
||||
|
||||
if (battle.hasSuspicionLevel)
|
||||
{
|
||||
if (e->aiFlags & (AIF_AVOIDS_COMBAT|AIF_DEFENSIVE))
|
||||
|
@ -192,14 +192,14 @@ static void checkCollisions(Bullet *b)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (e->flags & EF_IMMORTAL)
|
||||
{
|
||||
b->damage = 0;
|
||||
}
|
||||
|
||||
|
||||
damageFighter(e, b->damage, b->flags);
|
||||
|
||||
|
||||
doBulletHitEffect(b);
|
||||
|
||||
b->life = 0;
|
||||
|
@ -215,13 +215,13 @@ static void checkCollisions(Bullet *b)
|
|||
battle.stats[STAT_MISSILES_STRUCK]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* missile was targetting player, but hit something else */
|
||||
if (b->type == BT_MISSILE && b->target == player && e != player)
|
||||
{
|
||||
battle.stats[STAT_MISSILES_EVADED]++;
|
||||
}
|
||||
|
||||
|
||||
if (b->type == BT_MISSILE && b->target != e)
|
||||
{
|
||||
if (e == player)
|
||||
|
@ -233,23 +233,23 @@ static void checkCollisions(Bullet *b)
|
|||
awardTrophy("BODYGUARD");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* assuming that health <= 0 will always mean killed */
|
||||
if (e->health <= 0)
|
||||
{
|
||||
e->killedBy = b->owner;
|
||||
|
||||
|
||||
if (e == player)
|
||||
{
|
||||
battle.lastKilledPlayer = b->owner;
|
||||
}
|
||||
|
||||
|
||||
if (battle.isEpic && b->owner == player && e == battle.lastKilledPlayer)
|
||||
{
|
||||
awardTrophy("REVENGE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (b->owner == player && b->type == BT_MISSILE)
|
||||
{
|
||||
battle.stats[STAT_MISSILES_HIT]++;
|
||||
|
@ -268,19 +268,19 @@ void doBulletHitEffect(Bullet *b)
|
|||
case BT_PARTICLE:
|
||||
addBulletHitEffect(b->x, b->y, 255, 0, 255);
|
||||
break;
|
||||
|
||||
|
||||
case BT_PLASMA:
|
||||
addBulletHitEffect(b->x, b->y, 0, 255, 0);
|
||||
break;
|
||||
|
||||
|
||||
case BT_LASER:
|
||||
addBulletHitEffect(b->x, b->y, 255, 0, 0);
|
||||
break;
|
||||
|
||||
|
||||
case BT_MAG:
|
||||
addBulletHitEffect(b->x, b->y, 196, 196, 255);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
addBulletHitEffect(b->x, b->y, 255, 255, 255);
|
||||
break;
|
||||
|
@ -291,7 +291,7 @@ void drawBullets(void)
|
|||
{
|
||||
int i;
|
||||
Bullet *b;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
for (i = 0, b = bulletsToDraw[i] ; b != NULL ; b = bulletsToDraw[++i])
|
||||
|
@ -303,7 +303,7 @@ void drawBullets(void)
|
|||
static void faceTarget(Bullet *b)
|
||||
{
|
||||
int dir, wantedAngle, dist;
|
||||
|
||||
|
||||
wantedAngle = (int)getAngle(b->x, b->y, b->target->x, b->target->y) % 360;
|
||||
|
||||
if (abs(wantedAngle - b->angle) > TURN_THRESHOLD)
|
||||
|
@ -311,23 +311,23 @@ static void faceTarget(Bullet *b)
|
|||
dir = (wantedAngle - b->angle + 360) % 360 > 180 ? -1 : 1;
|
||||
|
||||
b->angle += dir * TURN_SPEED;
|
||||
|
||||
|
||||
dist = getDistance(b->x, b->y, b->target->x, b->target->y);
|
||||
|
||||
|
||||
if (dist < 250)
|
||||
{
|
||||
dist = 250 - dist;
|
||||
|
||||
|
||||
while (dist > 0)
|
||||
{
|
||||
b->angle += dir;
|
||||
|
||||
|
||||
dist -= 50;
|
||||
}
|
||||
}
|
||||
|
||||
b->angle = mod(b->angle, 360);
|
||||
|
||||
|
||||
b->dx *= 0.5;
|
||||
b->dy *= 0.5;
|
||||
}
|
||||
|
@ -378,29 +378,29 @@ static void selectNewTarget(Bullet *b)
|
|||
{
|
||||
int i;
|
||||
Entity *e, **candidates;
|
||||
|
||||
|
||||
if (app.gameplay.missileReTarget)
|
||||
{
|
||||
b->target = NULL;
|
||||
|
||||
|
||||
candidates = getAllEntsInRadius(b->x, b->y, SCREEN_HEIGHT, NULL);
|
||||
|
||||
|
||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||
{
|
||||
if (e->type == ET_FIGHTER && e->side != b->owner->side && e->health > 0)
|
||||
{
|
||||
b->target = e;
|
||||
|
||||
|
||||
if (b->target == player)
|
||||
{
|
||||
playSound(SND_INCOMING);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* no target, just explode */
|
||||
b->life = 0;
|
||||
addMissileExplosion(b);
|
||||
|
@ -438,7 +438,7 @@ void fireGuns(Entity *owner)
|
|||
int i;
|
||||
float x, y;
|
||||
float c, s;
|
||||
|
||||
|
||||
b = NULL;
|
||||
|
||||
for (i = 0 ; i < MAX_FIGHTER_GUNS ; i++)
|
||||
|
@ -492,7 +492,7 @@ void fireMissile(Entity *owner)
|
|||
Bullet *b;
|
||||
|
||||
b = createBullet(BT_MISSILE, owner->x, owner->y, owner);
|
||||
|
||||
|
||||
b->dx *= 0.5;
|
||||
b->dy *= 0.5;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void doCapitalShip(void)
|
|||
if (self->alive == ALIVE_ALIVE)
|
||||
{
|
||||
handleDisabled();
|
||||
|
||||
|
||||
if (self->health <= 0)
|
||||
{
|
||||
self->health = 0;
|
||||
|
@ -111,7 +111,7 @@ void doCapitalShip(void)
|
|||
|
||||
runScriptFunction("CAPITAL_SHIPS_DESTROYED %d", battle.stats[STAT_CAPITAL_SHIPS_DESTROYED]);
|
||||
}
|
||||
|
||||
|
||||
runScriptFunction(self->name);
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ static int steer(void)
|
|||
static void gunThink(void)
|
||||
{
|
||||
doAI();
|
||||
|
||||
|
||||
handleDisabled();
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ static void componentDie(void)
|
|||
if (self->owner->health > 0)
|
||||
{
|
||||
runScriptFunction("CAP_HEALTH %s %d", self->owner->name, self->owner->health);
|
||||
|
||||
|
||||
if (self->side != SIDE_PANDORAN && self->side == player->side)
|
||||
{
|
||||
issueDamageMessage(self->owner);
|
||||
|
@ -270,12 +270,12 @@ static void componentDie(void)
|
|||
static void gunDie(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
addSmallExplosion();
|
||||
playBattleSound(SND_EXPLOSION_1 + rand() % 4, self->x, self->y);
|
||||
addDebris(self->x, self->y, 3 + rand() % 4);
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e != self && e->health > 0 && e->owner == self->owner && e->type == ET_COMPONENT_GUN)
|
||||
|
@ -283,14 +283,14 @@ static void gunDie(void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
runScriptFunction("CAP_GUNS_DESTROYED %s", self->owner->name);
|
||||
|
||||
|
||||
if (self->side != SIDE_PANDORAN && self->side == player->side)
|
||||
{
|
||||
issueGunsDestroyedMessage(self->owner);
|
||||
}
|
||||
|
||||
|
||||
if (--self->owner->systemPower == 1)
|
||||
{
|
||||
disable();
|
||||
|
@ -300,7 +300,7 @@ static void gunDie(void)
|
|||
static void engineThink(void)
|
||||
{
|
||||
handleDisabled();
|
||||
|
||||
|
||||
addLargeEngineEffect();
|
||||
}
|
||||
|
||||
|
@ -329,13 +329,13 @@ static void engineDie(void)
|
|||
self->owner->dx = self->owner->dy = 0;
|
||||
|
||||
runScriptFunction("CAP_ENGINES_DESTROYED %s", self->owner->name);
|
||||
|
||||
|
||||
if (self->side != SIDE_PANDORAN && self->side == player->side)
|
||||
{
|
||||
issueEnginesDestroyedMessage(self->owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (--self->owner->systemPower == 1)
|
||||
{
|
||||
disable();
|
||||
|
@ -347,11 +347,11 @@ static void die(void)
|
|||
Entity *e;
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
|
||||
|
||||
playBattleSound(SND_CAP_DEATH, self->x, self->y);
|
||||
|
||||
addLargeExplosion();
|
||||
|
||||
|
||||
addDebris(self->x, self->y, 12);
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -364,7 +364,7 @@ static void die(void)
|
|||
|
||||
updateObjective(self->name, TT_DESTROY);
|
||||
updateObjective(self->groupName, TT_DESTROY);
|
||||
|
||||
|
||||
updateCondition(self->name, TT_DESTROY);
|
||||
updateCondition(self->groupName, TT_DESTROY);
|
||||
}
|
||||
|
@ -384,9 +384,9 @@ static void handleDisabled(void)
|
|||
static void disable(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
runScriptFunction("CAP_DISABLED %s", self->owner->name);
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->owner == self->owner || e == self->owner)
|
||||
|
@ -395,7 +395,7 @@ static void disable(void)
|
|||
e->flags |= EF_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateObjective(self->owner->name, TT_DISABLE);
|
||||
updateObjective(self->owner->groupName, TT_DISABLE);
|
||||
}
|
||||
|
@ -631,7 +631,7 @@ static void loadEngines(Entity *parent, cJSON *engines)
|
|||
void updateCapitalShipComponentProperties(Entity *parent, long flags)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
if (flags != -1)
|
||||
{
|
||||
flags &= ~EF_AI_LEADER;
|
||||
|
@ -645,7 +645,7 @@ void updateCapitalShipComponentProperties(Entity *parent, long flags)
|
|||
{
|
||||
e->flags |= flags;
|
||||
}
|
||||
|
||||
|
||||
switch (e->type)
|
||||
{
|
||||
case ET_COMPONENT_ENGINE:
|
||||
|
@ -743,9 +743,9 @@ void loadCapitalShips(cJSON *node)
|
|||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateCapitalShipComponentProperties(e, flags);
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "%s (%d / %d)", e->name, e->health, e->maxHealth);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,9 +48,9 @@ void doEffects(void)
|
|||
int i, onScreen;
|
||||
Effect *e;
|
||||
Effect *prev = &battle.effectHead;
|
||||
|
||||
|
||||
i = 0;
|
||||
|
||||
|
||||
memset(effectsToDraw, 0, sizeof(Effect*) * drawCapacity);
|
||||
|
||||
for (e = battle.effectHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -79,22 +79,22 @@ void doEffects(void)
|
|||
else
|
||||
{
|
||||
onScreen = 0;
|
||||
|
||||
|
||||
switch (e->type)
|
||||
{
|
||||
case EFFECT_LINE:
|
||||
onScreen = pointOnScreen(e->x - battle.camera.x, e->y - battle.camera.y) || pointOnScreen(e->x + (e->dx * 3) - battle.camera.x, e->y + (e->dy * 3) - battle.camera.y);
|
||||
break;
|
||||
|
||||
|
||||
case EFFECT_POINT:
|
||||
onScreen = pointOnScreen(e->x - battle.camera.x, e->y - battle.camera.y);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
onScreen = isOnBattleScreen(e->x, e->y, e->size, e->size);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (onScreen)
|
||||
{
|
||||
effectsToDraw[i++] = e;
|
||||
|
@ -124,7 +124,7 @@ static void resizeDrawList(void)
|
|||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Resizing effect draw capacity: %d -> %d", drawCapacity, n);
|
||||
|
||||
effectsToDraw = resize(effectsToDraw, sizeof(Effect*) * drawCapacity, sizeof(Effect*) * n);
|
||||
|
||||
|
||||
drawCapacity = n;
|
||||
}
|
||||
|
||||
|
@ -169,20 +169,20 @@ void drawEffects(void)
|
|||
blitScaled(e->texture, app.winWidth / 2 - (e->size / 2), app.winHeight / 2 - (e->size / 2), e->size, e->size, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (e->texture != NULL)
|
||||
{
|
||||
SDL_SetTextureBlendMode(e->texture->texture, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
void drawShieldHitEffect(Entity *e)
|
||||
{
|
||||
int size = MAX(e->w, e->h) + 32;
|
||||
|
||||
|
||||
SDL_SetTextureBlendMode(shieldHitTexture->texture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureAlphaMod(shieldHitTexture->texture, e->shieldHit);
|
||||
blitScaled(shieldHitTexture, e->x - battle.camera.x, e->y - battle.camera.y, size, size, 1);
|
||||
|
@ -192,7 +192,7 @@ void addBulletHitEffect(int x, int y, int r, int g, int b)
|
|||
{
|
||||
Effect *e;
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
e = malloc(sizeof(Effect));
|
||||
|
@ -205,7 +205,7 @@ void addBulletHitEffect(int x, int y, int r, int g, int b)
|
|||
e->size = 16;
|
||||
e->x = x;
|
||||
e->y = y;
|
||||
|
||||
|
||||
e->dx = (rand() % 25) - (rand() % 25);
|
||||
e->dx *= 0.01;
|
||||
e->dy = (rand() % 25) - (rand() % 25);
|
||||
|
@ -406,7 +406,7 @@ void addLargeExplosion(void)
|
|||
e->x -= e->size / 2;
|
||||
e->y -= e->size / 2;
|
||||
}
|
||||
|
||||
|
||||
e = malloc(sizeof(Effect));
|
||||
|
||||
memset(e, 0, sizeof(Effect));
|
||||
|
@ -603,7 +603,7 @@ void addShieldSplinterEffect(Entity *ent)
|
|||
e->dy = rand() % 64 - rand() % 64;
|
||||
e->dy *= 0.1;
|
||||
e->a = 255;
|
||||
|
||||
|
||||
e->health = e->a;
|
||||
|
||||
setRandomShieldHue(e);
|
||||
|
|
|
@ -84,7 +84,7 @@ void doEntities(void)
|
|||
e->health = e->maxHealth;
|
||||
e->shield = e->maxShield;
|
||||
}
|
||||
|
||||
|
||||
if (e->active)
|
||||
{
|
||||
self = e;
|
||||
|
@ -149,19 +149,19 @@ void doEntities(void)
|
|||
e->action();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
doRope(e);
|
||||
|
||||
|
||||
restrictToBattleArea(e);
|
||||
|
||||
|
||||
if (!e->speed)
|
||||
{
|
||||
e->dx = e->dy = 0;
|
||||
}
|
||||
|
||||
|
||||
e->x += e->dx;
|
||||
e->y += e->dy;
|
||||
|
||||
|
||||
addToQuadtree(e, &battle.quadtree);
|
||||
}
|
||||
else
|
||||
|
@ -175,7 +175,7 @@ void doEntities(void)
|
|||
{
|
||||
battle.missionTarget = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (e->killedBy == player && battle.hasSuspicionLevel)
|
||||
{
|
||||
if (e->aiFlags & (AIF_AVOIDS_COMBAT|AIF_DEFENSIVE))
|
||||
|
@ -196,12 +196,12 @@ void doEntities(void)
|
|||
cutRope(e);
|
||||
|
||||
prev->next = e->next;
|
||||
|
||||
|
||||
e->next = NULL;
|
||||
|
||||
|
||||
deadTail->next = e;
|
||||
deadTail = e;
|
||||
|
||||
|
||||
/* actually just creates another fighter in this one's place */
|
||||
if (e->type == ET_FIGHTER && battle.isEpic && e->side != player->side && battle.unlimitedEnemies)
|
||||
{
|
||||
|
@ -230,13 +230,13 @@ void doEntities(void)
|
|||
if (e->health > 0 && e->active)
|
||||
{
|
||||
numActiveEnemies++;
|
||||
|
||||
|
||||
if (e->spawned)
|
||||
{
|
||||
numSpawnedEnemies++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(e->flags & EF_DISABLED) || battle.isEpic)
|
||||
{
|
||||
battle.hasThreats = 1;
|
||||
|
@ -249,7 +249,7 @@ void doEntities(void)
|
|||
|
||||
battle.numAllies = (battle.isEpic) ? numAllies : numActiveAllies;
|
||||
battle.numEnemies = (battle.isEpic) ? numEnemies : numActiveEnemies;
|
||||
|
||||
|
||||
if (battle.status == MS_IN_PROGRESS && battle.stats[STAT_TIME] % (FPS * 30) == 0)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "numEnemies=%d, numActiveEnemies=%d, hasThreats=%d", numEnemies, numActiveEnemies, battle.hasThreats);
|
||||
|
@ -261,7 +261,7 @@ void doEntities(void)
|
|||
{
|
||||
activateEpicFighters(SIDE_ALLIES);
|
||||
}
|
||||
|
||||
|
||||
numActiveEnemies -= numSpawnedEnemies;
|
||||
|
||||
if (numActiveEnemies < battle.epicFighterLimit)
|
||||
|
@ -357,7 +357,7 @@ static void alignComponents(void)
|
|||
if (isComponent(e))
|
||||
{
|
||||
removeFromQuadtree(e, &battle.quadtree);
|
||||
|
||||
|
||||
s = sin(TO_RAIDANS(e->owner->angle));
|
||||
c = cos(TO_RAIDANS(e->owner->angle));
|
||||
|
||||
|
@ -389,12 +389,12 @@ void drawEntities(void)
|
|||
{
|
||||
int i;
|
||||
Entity *e, **candidates;
|
||||
|
||||
|
||||
candidates = getAllEntsWithin(battle.camera.x, battle.camera.y, app.winWidth, app.winHeight, NULL);
|
||||
|
||||
|
||||
/* counting entities to draw */
|
||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) {};
|
||||
|
||||
|
||||
qsort(candidates, i, sizeof(Entity*), drawComparator);
|
||||
|
||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||
|
@ -409,11 +409,11 @@ void drawEntities(void)
|
|||
{
|
||||
drawEntity(e);
|
||||
}
|
||||
|
||||
|
||||
drawHealthBar(e);
|
||||
|
||||
|
||||
drawTargetRects(e);
|
||||
|
||||
|
||||
drawRope(e);
|
||||
}
|
||||
}
|
||||
|
@ -448,14 +448,14 @@ static void drawEntity(Entity *e)
|
|||
static void drawHealthBar(Entity *e)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
if (app.gameplay.healthBars && !(e->flags & EF_NO_HEALTH_BAR) && e->health > 0)
|
||||
{
|
||||
r.x = e->x - (e->w / 2) - battle.camera.x;
|
||||
r.y = e->y - e->h - battle.camera.y;
|
||||
r.w = 32;
|
||||
r.h = 1;
|
||||
|
||||
|
||||
if (e->side == player->side || e->flags & EF_FRIENDLY_HEALTH_BAR)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 128, 0, 255);
|
||||
|
@ -464,11 +464,11 @@ static void drawHealthBar(Entity *e)
|
|||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 128, 0, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
|
||||
|
||||
r.w = 32 * (e->health * 1.0f / e->maxHealth);
|
||||
|
||||
|
||||
if (e->side == player->side || e->flags & EF_FRIENDLY_HEALTH_BAR)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 255, 0, 255);
|
||||
|
@ -477,7 +477,7 @@ static void drawHealthBar(Entity *e)
|
|||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +509,7 @@ static void drawTargetRects(Entity *e)
|
|||
SDL_SetRenderDrawColor(app.renderer, 0, 255, 0, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
}
|
||||
|
||||
|
||||
if (e == battle.messageSpeaker && e != player && battle.stats[STAT_TIME] % 40 < 20)
|
||||
{
|
||||
r.x = e->x - (size / 2) - battle.camera.x;
|
||||
|
@ -564,9 +564,9 @@ void activateEntityGroups(char *groupNames)
|
|||
if (strcmp(e->groupName, groupName) == 0)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Activated %s (%s)", e->name, groupName);
|
||||
|
||||
|
||||
e->active = 1;
|
||||
|
||||
|
||||
if (e->type == ET_CAPITAL_SHIP)
|
||||
{
|
||||
updateCapitalShipComponentProperties(e, 0);
|
||||
|
@ -600,23 +600,23 @@ static void notifyNewArrivals(void)
|
|||
static void activateEpicFighters(int side)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (!e->active && e->type == ET_FIGHTER && !(e->flags & EF_NO_EPIC) && ((side == SIDE_ALLIES && e->side == SIDE_ALLIES) || (side != SIDE_ALLIES && e->side != SIDE_ALLIES)))
|
||||
{
|
||||
e->active = 1;
|
||||
|
||||
|
||||
/* don't spring into existence in front of the player */
|
||||
if (isOnBattleScreen(e->x, e->y, e->w, e->h))
|
||||
{
|
||||
e->x = player->x;
|
||||
e->y = player->y;
|
||||
|
||||
|
||||
e->x += (rand() % 2) ? -app.winWidth : app.winWidth;
|
||||
e->y += (rand() % 2) ? -app.winHeight : app.winHeight;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ void countNumEnemies(void)
|
|||
void addAllToQuadtree(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->active)
|
||||
|
@ -661,14 +661,14 @@ static int drawComparator(const void *a, const void *b)
|
|||
void killEntity(char *name)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (strcmp(e->name, name) == 0)
|
||||
{
|
||||
e->health = 0;
|
||||
e->deathType = DT_INSTANT;
|
||||
|
||||
|
||||
/* prevent objectives and conditions from firing */
|
||||
strcpy(e->name, "");
|
||||
strcpy(e->groupName, "");
|
||||
|
@ -680,15 +680,15 @@ void updateEntitySide(char *sideStr, char *name)
|
|||
{
|
||||
Entity *e;
|
||||
int side;
|
||||
|
||||
|
||||
side = lookup(sideStr);
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (strcmp(e->name, name) == 0)
|
||||
{
|
||||
e->side = side;
|
||||
|
||||
|
||||
if (e->side != player->side)
|
||||
{
|
||||
e->flags |= EF_MISSION_TARGET;
|
||||
|
@ -700,7 +700,7 @@ void updateEntitySide(char *sideStr, char *name)
|
|||
void awardPandoranCraftTrophy(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
for (e = deadHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->killedBy == player && e->side == SIDE_PANDORAN)
|
||||
|
|
|
@ -97,7 +97,7 @@ Entity *spawnFighter(char *name, int x, int y, int side)
|
|||
|
||||
e->action = doAI;
|
||||
e->die = die;
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.isDeathMatch)
|
||||
{
|
||||
e->side = SDL_GetTicks();
|
||||
|
@ -193,14 +193,14 @@ static void randomizeDartGuns(Entity *dart)
|
|||
void resetFighter(Entity *fighter)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
e = spawnFighter(fighter->defName, fighter->x, fighter->y, fighter->side);
|
||||
|
||||
|
||||
e->x += (rand() % 7500) - (rand() % 7500);
|
||||
e->y += (rand() % 7500) - (rand() % 7500);
|
||||
|
||||
|
||||
e->active = 0;
|
||||
|
||||
|
||||
if (rand() % 4)
|
||||
{
|
||||
e->aiFlags |= AIF_TARGET_FOCUS;
|
||||
|
@ -251,7 +251,7 @@ void doFighter(void)
|
|||
|
||||
self->flags |= EF_DISABLED;
|
||||
self->flags |= EF_SECONDARY_TARGET;
|
||||
|
||||
|
||||
if (self->aiFlags & AIF_SURRENDERING)
|
||||
{
|
||||
self->aiFlags |= AIF_SURRENDERED;
|
||||
|
@ -262,7 +262,7 @@ void doFighter(void)
|
|||
|
||||
updateObjective(self->name, TT_DISABLE);
|
||||
updateObjective(self->groupName, TT_DISABLE);
|
||||
|
||||
|
||||
if (self->side != player->side)
|
||||
{
|
||||
runScriptFunction("ENEMIES_DISABLED %d", battle.stats[STAT_ENEMIES_DISABLED]);
|
||||
|
@ -279,12 +279,12 @@ void doFighter(void)
|
|||
self->action = doAI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (self->aiFlags & AIF_SUSPICIOUS)
|
||||
{
|
||||
checkSuspicionLevel();
|
||||
}
|
||||
|
||||
|
||||
if (self->aiFlags & AIF_ZAK_SUSPICIOUS)
|
||||
{
|
||||
checkZackariaSuspicionLevel();
|
||||
|
@ -296,7 +296,7 @@ void doFighter(void)
|
|||
if (self == player && !game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
updateObjective("Player", TT_ESCAPED);
|
||||
|
||||
|
||||
completeMission();
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ void doFighter(void)
|
|||
{
|
||||
addHudMessage(colors.red, _("Civilian has been killed"));
|
||||
}
|
||||
|
||||
|
||||
runScriptFunction("CIVILIANS_KILLED %d", battle.stats[STAT_CIVILIANS_KILLED]);
|
||||
}
|
||||
else
|
||||
|
@ -360,10 +360,10 @@ void doFighter(void)
|
|||
runScriptFunction("ALLIES_KILLED %d", battle.stats[STAT_ALLIES_KILLED]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateObjective(self->name, TT_DESTROY);
|
||||
updateObjective(self->groupName, TT_DESTROY);
|
||||
|
||||
|
||||
if (battle.isEpic && self->killedBy == player)
|
||||
{
|
||||
updateObjective("EPIC_PLAYER_KILLS", TT_DESTROY);
|
||||
|
@ -373,7 +373,7 @@ void doFighter(void)
|
|||
|
||||
updateCondition(self->name, TT_DESTROY);
|
||||
updateCondition(self->groupName, TT_DESTROY);
|
||||
|
||||
|
||||
/* don't fire if the opposing side is responsible */
|
||||
if (self->aiFlags & AIF_SURRENDERED && self->killedBy->side == player->side)
|
||||
{
|
||||
|
@ -461,21 +461,21 @@ void damageFighter(Entity *e, int amount, long flags)
|
|||
|
||||
e->aiDamageTimer = FPS;
|
||||
e->aiDamagePerSec += amount;
|
||||
|
||||
|
||||
if (flags & BF_SYSTEM_DAMAGE)
|
||||
{
|
||||
if (e->shield > 0)
|
||||
{
|
||||
amount /= 2;
|
||||
|
||||
|
||||
e->shield -= amount;
|
||||
|
||||
|
||||
if (e->shield < 0)
|
||||
{
|
||||
amount = -e->shield;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (amount >= 0)
|
||||
{
|
||||
e->systemPower = MAX(0, e->systemPower - amount);
|
||||
|
@ -487,7 +487,7 @@ void damageFighter(Entity *e, int amount, long flags)
|
|||
e->shield = e->maxShield = 0;
|
||||
e->action = NULL;
|
||||
}
|
||||
|
||||
|
||||
playBattleSound(SND_MAG_HIT, e->x, e->y);
|
||||
}
|
||||
}
|
||||
|
@ -509,13 +509,13 @@ void damageFighter(Entity *e, int amount, long flags)
|
|||
if (e->shield > 0)
|
||||
{
|
||||
e->shield -= amount;
|
||||
|
||||
|
||||
if (e->shield <= 0)
|
||||
{
|
||||
e->armourHit = 255;
|
||||
e->health += e->shield;
|
||||
e->shield = 0;
|
||||
|
||||
|
||||
playBattleSound(SND_ARMOUR_HIT, e->x, e->y);
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ void damageFighter(Entity *e, int amount, long flags)
|
|||
|
||||
playBattleSound(SND_SHIELD_HIT, e->x, e->y);
|
||||
}
|
||||
|
||||
|
||||
/* don't allow the shield to recharge immediately after taking a hit */
|
||||
e->shieldRecharge = e->shieldRechargeRate;
|
||||
|
||||
|
@ -596,22 +596,22 @@ static void die(void)
|
|||
self->action = simpleDie;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (self->killedBy == player && (!(self->flags & EF_NO_KILL_INC)))
|
||||
{
|
||||
battle.stats[STAT_ENEMIES_KILLED_PLAYER]++;
|
||||
|
||||
|
||||
if (self->flags & EF_COMMON_FIGHTER)
|
||||
{
|
||||
incFighterStat(self->defName);
|
||||
}
|
||||
|
||||
|
||||
if (battle.isEpic && player->flags & EF_COMMON_FIGHTER)
|
||||
{
|
||||
battle.stats[STAT_EPIC_KILL_STREAK]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (self->flags & EF_DROPS_ITEMS)
|
||||
{
|
||||
addRandomItem(self->x, self->y);
|
||||
|
@ -688,14 +688,14 @@ void retreatEnemies(void)
|
|||
if (e->type == ET_FIGHTER && e->side != player->side)
|
||||
{
|
||||
e->flags |= EF_RETREATING;
|
||||
|
||||
|
||||
e->aiFlags |= AIF_AVOIDS_COMBAT;
|
||||
e->aiFlags |= AIF_UNLIMITED_RANGE;
|
||||
e->aiFlags &= ~AIF_MOVES_TO_LEADER;
|
||||
e->aiFlags &= ~AIF_WANDERS;
|
||||
|
||||
|
||||
e->aiActionTime = MIN(e->aiActionTime, FPS);
|
||||
|
||||
|
||||
if (!game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
e->aiFlags |= AIF_GOAL_JUMPGATE;
|
||||
|
@ -720,9 +720,9 @@ void retreatAllies(void)
|
|||
e->aiFlags &= ~AIF_MOVES_TO_PLAYER;
|
||||
e->aiFlags &= ~AIF_MOVES_TO_LEADER;
|
||||
e->aiFlags &= ~AIF_WANDERS;
|
||||
|
||||
|
||||
e->aiActionTime = MIN(e->aiActionTime, FPS);
|
||||
|
||||
|
||||
if (!game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
e->aiFlags |= AIF_GOAL_JUMPGATE;
|
||||
|
@ -751,7 +751,7 @@ Entity **getDBFighters(int *num)
|
|||
{
|
||||
Entity *e, **dbFighters;
|
||||
int i;
|
||||
|
||||
|
||||
i = *num = 0;
|
||||
|
||||
for (e = defHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -761,19 +761,19 @@ Entity **getDBFighters(int *num)
|
|||
*num = *num + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dbFighters = malloc(sizeof(Entity*) * *num);
|
||||
|
||||
|
||||
for (e = defHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->description != NULL)
|
||||
{
|
||||
dbFighters[i] = e;
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dbFighters;
|
||||
}
|
||||
|
||||
|
@ -839,7 +839,7 @@ static void loadFighterDef(char *filename)
|
|||
e->reloadTime = getJSONValue(root, "reloadTime", 0);
|
||||
e->shieldRechargeRate = getJSONValue(root, "shieldRechargeRate", 0);
|
||||
e->texture = getAtlasImage(cJSON_GetObjectItem(root, "texture")->valuestring);
|
||||
|
||||
|
||||
if (strlen(cJSON_GetObjectItem(root, "description")->valuestring) > 0)
|
||||
{
|
||||
len = strlen(_(cJSON_GetObjectItem(root, "description")->valuestring)) + 1;
|
||||
|
@ -890,7 +890,7 @@ static void loadFighterDef(char *filename)
|
|||
{
|
||||
e->deathType = lookup(cJSON_GetObjectItem(root, "deathType")->valuestring);
|
||||
}
|
||||
|
||||
|
||||
if (e->flags & EF_COMMON_FIGHTER)
|
||||
{
|
||||
addFighterStat(e->name);
|
||||
|
@ -913,33 +913,33 @@ static void loadFighterDef(char *filename)
|
|||
static void addFighterStat(char *key)
|
||||
{
|
||||
Tuple *t, *tail;
|
||||
|
||||
|
||||
tail = &game.fighterStatHead;
|
||||
|
||||
|
||||
for (t = game.fighterStatHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
if (strcmp(t->key, key) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tail = t;
|
||||
}
|
||||
|
||||
|
||||
t = malloc(sizeof(Tuple));
|
||||
memset(t, 0, sizeof(Tuple));
|
||||
tail->next = t;
|
||||
|
||||
|
||||
STRNCPY(t->key, key, MAX_NAME_LENGTH);
|
||||
t->value = 0;
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Added '%s' to fighter stats", key);
|
||||
}
|
||||
|
||||
static void incFighterStat(char *key)
|
||||
{
|
||||
Tuple *t;
|
||||
|
||||
|
||||
for (t = game.fighterStatHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
if (strcmp(t->key, key) == 0)
|
||||
|
@ -962,7 +962,7 @@ void loadFighters(cJSON *node)
|
|||
if (node)
|
||||
{
|
||||
id = 0;
|
||||
|
||||
|
||||
node = node->child;
|
||||
|
||||
while (node)
|
||||
|
@ -1018,7 +1018,7 @@ void loadFighters(cJSON *node)
|
|||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName);
|
||||
}
|
||||
|
||||
|
||||
if (e->flags & EF_DISABLED)
|
||||
{
|
||||
e->speed = 0;
|
||||
|
@ -1042,10 +1042,10 @@ void loadFighters(cJSON *node)
|
|||
if (name)
|
||||
{
|
||||
STRNCPY(e->name, name, MAX_NAME_LENGTH);
|
||||
|
||||
|
||||
/* update 'name #?' to 'name #1', etc. */
|
||||
strpos = strstr(e->name, "#?");
|
||||
|
||||
|
||||
if (strpos)
|
||||
{
|
||||
*(++strpos) = ('0' + ++id);
|
||||
|
@ -1078,12 +1078,12 @@ void destroyFighterDefs(void)
|
|||
{
|
||||
e = defHead.next;
|
||||
defHead.next = e->next;
|
||||
|
||||
|
||||
if (e->description)
|
||||
{
|
||||
free(e->description);
|
||||
}
|
||||
|
||||
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
@ -1091,7 +1091,7 @@ void destroyFighterDefs(void)
|
|||
void destroyFighterStats(void)
|
||||
{
|
||||
Tuple *t;
|
||||
|
||||
|
||||
while (game.fighterStatHead.next)
|
||||
{
|
||||
t = game.fighterStatHead.next;
|
||||
|
|
236
src/battle/hud.c
236
src/battle/hud.c
|
@ -68,7 +68,7 @@ void initHud(void)
|
|||
{
|
||||
memset(&hudMessageHead, 0, sizeof(HudMessage));
|
||||
hudMessageTail = &hudMessageHead;
|
||||
|
||||
|
||||
gunName[BT_NONE] = "";
|
||||
gunName[BT_PARTICLE] = _("Particle Cannon");
|
||||
gunName[BT_PLASMA] = _("Plasma Cannon");
|
||||
|
@ -76,7 +76,7 @@ void initHud(void)
|
|||
gunName[BT_MAG] = _("Mag Cannon");
|
||||
gunName[BT_ROCKET] = _("Rockets");
|
||||
gunName[BT_MISSILE] = _("Missiles");
|
||||
|
||||
|
||||
MISSILES_TEXT = _("Missiles (%d)");
|
||||
TARGET_TEXT = _("Target: %.2fkm");
|
||||
NONE_TEXT = _("(None)");
|
||||
|
@ -90,7 +90,7 @@ void initHud(void)
|
|||
SUSPICION_TEXT = _("Suspicion");
|
||||
REMAINING_PILOTS_TEXT = _("Remaining Pilots: %d");
|
||||
WARNING_TEXT = _("WARNING: INCOMING MISSILE!");
|
||||
|
||||
|
||||
targetPointer = getAtlasImage("gfx/hud/targetPointer.png");
|
||||
targetCircle = getAtlasImage("gfx/hud/targetCircle.png");
|
||||
smallFighter = getAtlasImage("gfx/hud/smallFighter.png");
|
||||
|
@ -108,31 +108,31 @@ void initHud(void)
|
|||
void doHud(void)
|
||||
{
|
||||
HudMessage *hudMessage, *prev;
|
||||
|
||||
|
||||
numMessages = 0;
|
||||
|
||||
|
||||
prev = &hudMessageHead;
|
||||
|
||||
|
||||
for (hudMessage = hudMessageHead.next ; hudMessage != NULL ; hudMessage = hudMessage->next)
|
||||
{
|
||||
hudMessage->life--;
|
||||
|
||||
|
||||
numMessages++;
|
||||
|
||||
|
||||
if (hudMessage->life <= 0)
|
||||
{
|
||||
if (hudMessage == hudMessageTail)
|
||||
{
|
||||
hudMessageTail = prev;
|
||||
}
|
||||
|
||||
|
||||
prev->next = hudMessage->next;
|
||||
free(hudMessage);
|
||||
hudMessage = prev;
|
||||
|
||||
|
||||
numMessages--;
|
||||
}
|
||||
|
||||
|
||||
prev = hudMessage;
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ void doHud(void)
|
|||
void addHudMessage(SDL_Color c, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
||||
HudMessage *hudMessage = malloc(sizeof(HudMessage));
|
||||
memset(hudMessage, 0, sizeof(HudMessage));
|
||||
hudMessageTail->next = hudMessage;
|
||||
|
@ -149,18 +149,18 @@ void addHudMessage(SDL_Color c, char *format, ...)
|
|||
va_start(args, format);
|
||||
vsprintf(hudMessageTail->message, format, args);
|
||||
va_end(args);
|
||||
|
||||
|
||||
hudMessage->color = c;
|
||||
hudMessage->life = FPS * 5;
|
||||
|
||||
|
||||
numMessages++;
|
||||
|
||||
|
||||
while (numMessages > MAX_HUD_MESSAGES)
|
||||
{
|
||||
hudMessage = hudMessageHead.next;
|
||||
hudMessageHead.next = hudMessage->next;
|
||||
free(hudMessage);
|
||||
|
||||
|
||||
numMessages--;
|
||||
}
|
||||
}
|
||||
|
@ -170,30 +170,30 @@ void drawHud(void)
|
|||
if (player->alive == ALIVE_ALIVE)
|
||||
{
|
||||
drawHealthBars();
|
||||
|
||||
|
||||
drawAbilityBars();
|
||||
|
||||
|
||||
drawPlayerTargeter();
|
||||
|
||||
|
||||
drawWeaponInfo();
|
||||
|
||||
|
||||
drawNumFighters();
|
||||
|
||||
|
||||
drawObjectives();
|
||||
|
||||
|
||||
drawDistancesInfo();
|
||||
|
||||
|
||||
drawRadar();
|
||||
|
||||
|
||||
drawRadarRangeWarning();
|
||||
|
||||
|
||||
drawMissileWarning();
|
||||
|
||||
|
||||
drawSuspicionLevel();
|
||||
}
|
||||
|
||||
|
||||
drawHudMessages();
|
||||
|
||||
|
||||
if (battle.playerSelect)
|
||||
{
|
||||
drawPlayerSelect();
|
||||
|
@ -204,11 +204,11 @@ static void drawHealthBars(void)
|
|||
{
|
||||
float p;
|
||||
int r, g, b;
|
||||
|
||||
|
||||
r = g = b = 0;
|
||||
p = player->health;
|
||||
p /= player->maxHealth;
|
||||
|
||||
|
||||
if (p <= 0.25)
|
||||
{
|
||||
r = 255;
|
||||
|
@ -222,12 +222,12 @@ static void drawHealthBars(void)
|
|||
{
|
||||
g = 200;
|
||||
}
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blit(armour, 6, 9, 0);
|
||||
drawHealthShieldBar(player->health, player->maxHealth, 30, 10, r, g, b, 1);
|
||||
|
||||
|
||||
blit(shield, 6, 29, 0);
|
||||
drawHealthShieldBar(player->shield, player->maxShield, 30, 30, 0, 200, 255, 0);
|
||||
}
|
||||
|
@ -236,38 +236,38 @@ static void drawHealthShieldBar(int current, int max, int x, int y, int r, int g
|
|||
{
|
||||
SDL_Rect rect;
|
||||
float percent = 0;
|
||||
|
||||
|
||||
if (max > 0)
|
||||
{
|
||||
percent = current;
|
||||
percent /= max;
|
||||
|
||||
|
||||
if (flashLow && percent <= 0.25 && battle.stats[STAT_TIME] % FPS < 30)
|
||||
{
|
||||
percent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.w = 250;
|
||||
rect.h = 12;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, r / 2, g / 2, b / 2, 255);
|
||||
SDL_RenderFillRect(app.renderer, &rect);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 255, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &rect);
|
||||
|
||||
|
||||
if (current > 0)
|
||||
{
|
||||
rect.x += 2;
|
||||
rect.y += 2;
|
||||
rect.w -= 4;
|
||||
rect.h -= 4;
|
||||
|
||||
|
||||
rect.w *= percent;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, r, g, b, 255);
|
||||
SDL_RenderFillRect(app.renderer, &rect);
|
||||
}
|
||||
|
@ -276,10 +276,10 @@ static void drawHealthShieldBar(int current, int max, int x, int y, int r, int g
|
|||
static void drawAbilityBars(void)
|
||||
{
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blit(boost, 6, 49, 0);
|
||||
drawBoostECMBar(battle.boostTimer, BOOST_RECHARGE_TIME, 30, 50, 128, 128, 255);
|
||||
|
||||
|
||||
blit(ecm, 155, 49, 0);
|
||||
drawBoostECMBar(battle.ecmTimer, ECM_RECHARGE_TIME, 175, 50, 255, 128, 0);
|
||||
}
|
||||
|
@ -287,35 +287,35 @@ static void drawAbilityBars(void)
|
|||
static void drawBoostECMBar(int current, int max, int x, int y, int r, int g, int b)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
|
||||
|
||||
float percent = current;
|
||||
percent /= max;
|
||||
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.w = 105;
|
||||
rect.h = 12;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(app.renderer, &rect);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 255, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &rect);
|
||||
|
||||
|
||||
rect.x += 2;
|
||||
rect.y += 2;
|
||||
rect.w -= 4;
|
||||
rect.h -= 4;
|
||||
|
||||
|
||||
rect.w *= percent;
|
||||
|
||||
|
||||
if (current < max)
|
||||
{
|
||||
r /= 2;
|
||||
g /= 2;
|
||||
b /= 2;
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, r, g, b, 255);
|
||||
SDL_RenderFillRect(app.renderer, &rect);
|
||||
}
|
||||
|
@ -323,15 +323,15 @@ static void drawBoostECMBar(int current, int max, int x, int y, int r, int g, in
|
|||
static void drawWeaponInfo(void)
|
||||
{
|
||||
int i, y;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
if (!player->combinedGuns)
|
||||
{
|
||||
if (battle.numPlayerGuns)
|
||||
{
|
||||
y = 70;
|
||||
|
||||
|
||||
for (i = 0 ; i < BT_MAX ; i++)
|
||||
{
|
||||
if (playerHasGun(i))
|
||||
|
@ -339,14 +339,14 @@ static void drawWeaponInfo(void)
|
|||
if (player->selectedGunType == i)
|
||||
{
|
||||
drawText(30, y, 14, TA_LEFT, colors.green, "%s", gunName[i]);
|
||||
|
||||
|
||||
blit(nextGun, 8, y + 5, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawText(30, y, 14, TA_LEFT, colors.darkGrey, "%s", gunName[i]);
|
||||
}
|
||||
|
||||
|
||||
y += 20;
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ static void drawWeaponInfo(void)
|
|||
{
|
||||
drawText(30, 70, 14, TA_LEFT, colors.white, COMBINED_TEXT);
|
||||
}
|
||||
|
||||
|
||||
drawText(280, 70, 14, TA_RIGHT, colors.white, MISSILES_TEXT, player->missiles);
|
||||
}
|
||||
|
||||
|
@ -368,7 +368,7 @@ static void drawPlayerTargeter(void)
|
|||
{
|
||||
float angle;
|
||||
int x, y;
|
||||
|
||||
|
||||
if (player->target || battle.missionTarget || jumpgateEnabled() || battle.messageSpeaker)
|
||||
{
|
||||
if (player->target)
|
||||
|
@ -387,63 +387,63 @@ static void drawPlayerTargeter(void)
|
|||
{
|
||||
setAtlasColor(255, 255, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
blit(targetCircle, player->x - battle.camera.x, player->y - battle.camera.y, 1);
|
||||
}
|
||||
|
||||
|
||||
if (player->target)
|
||||
{
|
||||
angle = getAngle(player->x, player->y, player->target->x, player->target->y);
|
||||
x = player->x;
|
||||
y = player->y;
|
||||
|
||||
|
||||
x += sin(TO_RAIDANS(angle)) * 45;
|
||||
y += -cos(TO_RAIDANS(angle)) * 45;
|
||||
|
||||
|
||||
setAtlasColor(255, 0, 0, 255);
|
||||
|
||||
|
||||
blitRotated(targetPointer, x - battle.camera.x, y - battle.camera.y, angle);
|
||||
}
|
||||
|
||||
|
||||
if (battle.missionTarget)
|
||||
{
|
||||
angle = getAngle(player->x, player->y, battle.missionTarget->x, battle.missionTarget->y);
|
||||
x = player->x;
|
||||
y = player->y;
|
||||
|
||||
|
||||
x += sin(TO_RAIDANS(angle)) * 45;
|
||||
y += -cos(TO_RAIDANS(angle)) * 45;
|
||||
|
||||
|
||||
setAtlasColor(0, 255, 0, 255);
|
||||
|
||||
|
||||
blitRotated(targetPointer, x - battle.camera.x, y - battle.camera.y, angle);
|
||||
}
|
||||
|
||||
|
||||
if (jumpgateEnabled())
|
||||
{
|
||||
angle = getAngle(player->x, player->y, battle.jumpgate->x, battle.jumpgate->y);
|
||||
x = player->x;
|
||||
y = player->y;
|
||||
|
||||
|
||||
x += sin(TO_RAIDANS(angle)) * 45;
|
||||
y += -cos(TO_RAIDANS(angle)) * 45;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 0, 255);
|
||||
|
||||
|
||||
blitRotated(targetPointer, x - battle.camera.x, y - battle.camera.y, angle);
|
||||
}
|
||||
|
||||
|
||||
if (battle.messageSpeaker && battle.messageSpeaker != player)
|
||||
{
|
||||
angle = getAngle(player->x, player->y, battle.messageSpeaker->x, battle.messageSpeaker->y);
|
||||
x = player->x;
|
||||
y = player->y;
|
||||
|
||||
|
||||
x += sin(TO_RAIDANS(angle)) * 45;
|
||||
y += -cos(TO_RAIDANS(angle)) * 45;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blitRotated(targetPointer, x - battle.camera.x, y - battle.camera.y, angle);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ static void drawNumFighters(void)
|
|||
setAtlasColor(150, 200, 255, 255);
|
||||
blit(smallFighter, (app.winWidth / 2) - 185, 15, 0);
|
||||
drawText((app.winWidth / 2) - 160, 11, 14, TA_LEFT, colors.white, battle.numAllies < 1000 ? "(%d)" : "(999+)", battle.numAllies);
|
||||
|
||||
|
||||
/* Enemies */
|
||||
setAtlasColor(255, 100, 100, 255);
|
||||
blit(smallFighter, (app.winWidth / 2) + 170, 15, 0);
|
||||
|
@ -464,14 +464,14 @@ static void drawNumFighters(void)
|
|||
static void drawObjectives(void)
|
||||
{
|
||||
int timeRemaining;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
if (!game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
blit(objectives, (app.winWidth / 2) - 50, 14, 0);
|
||||
drawText(app.winWidth / 2, 10, 16, TA_CENTER, colors.white, "%d / %d", battle.numObjectivesComplete, (battle.numObjectivesTotal + battle.numConditions));
|
||||
|
||||
|
||||
if (battle.isEpic && battle.epicLives > 0)
|
||||
{
|
||||
drawText(app.winWidth / 2, 35, 14, TA_CENTER, colors.white, REMAINING_PILOTS_TEXT, battle.epicLives - 1);
|
||||
|
@ -482,7 +482,7 @@ static void drawObjectives(void)
|
|||
if (game.currentMission->challengeData.timeLimit)
|
||||
{
|
||||
timeRemaining = game.currentMission->challengeData.timeLimit - battle.stats[STAT_TIME];
|
||||
|
||||
|
||||
blit(clockIcon, (app.winWidth / 2) - 50, 14, 0);
|
||||
drawText(app.winWidth / 2, 10, 16, TA_CENTER, (timeRemaining < 11 * FPS) ? colors.red : colors.white, timeToString(timeRemaining, 0));
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ static void drawObjectives(void)
|
|||
drawText(app.winWidth / 2, 10, 16, TA_CENTER, colors.white, timeToString(battle.stats[STAT_TIME], 0));
|
||||
blit(clockIcon, (app.winWidth / 2) - 50, 14, 0);
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.killLimit)
|
||||
{
|
||||
drawText(app.winWidth / 2, 35, 14, TA_CENTER, colors.white, "%d / %d", battle.stats[STAT_ENEMIES_KILLED_PLAYER] + battle.stats[STAT_ENEMIES_DISABLED], game.currentMission->challengeData.killLimit);
|
||||
|
@ -530,14 +530,14 @@ static void drawObjectives(void)
|
|||
static float distanceToKM(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
float distance;
|
||||
|
||||
|
||||
distance = getDistance(x1, y1, x2, y2);
|
||||
|
||||
|
||||
/* 2px = 1m approx */
|
||||
distance /= 2;
|
||||
distance = (int)distance;
|
||||
distance /= 1000;
|
||||
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
|
@ -545,9 +545,9 @@ static void drawDistancesInfo(void)
|
|||
{
|
||||
int y;
|
||||
float distance;
|
||||
|
||||
|
||||
y = 11;
|
||||
|
||||
|
||||
if (player->target)
|
||||
{
|
||||
if (player->target->flags & EF_AI_LEADER && player->target->speed > 0)
|
||||
|
@ -558,40 +558,40 @@ static void drawDistancesInfo(void)
|
|||
{
|
||||
drawText(app.winWidth - 15, y, 18, TA_RIGHT, colors.red, player->target->name);
|
||||
}
|
||||
|
||||
|
||||
y += 30;
|
||||
|
||||
|
||||
distance = distanceToKM(player->x, player->y, player->target->x, player->target->y);
|
||||
|
||||
|
||||
drawText(app.winWidth - 15, y, 14, TA_RIGHT, colors.red, TARGET_DIST_TEXT, distance);
|
||||
|
||||
|
||||
y += 25;
|
||||
}
|
||||
|
||||
|
||||
if (battle.missionTarget)
|
||||
{
|
||||
distance = distanceToKM(player->x, player->y, battle.missionTarget->x, battle.missionTarget->y);
|
||||
|
||||
|
||||
drawText(app.winWidth - 15, y, 14, TA_RIGHT, colors.green, OBJECTIVE_DIST_TEXT, distance);
|
||||
|
||||
|
||||
y += 25;
|
||||
}
|
||||
|
||||
|
||||
if (jumpgateEnabled())
|
||||
{
|
||||
distance = distanceToKM(player->x, player->y, battle.jumpgate->x, battle.jumpgate->y);
|
||||
|
||||
|
||||
drawText(app.winWidth - 15, y, 14, TA_RIGHT, colors.yellow, JUMPGATE_DIST_TEXT, distance);
|
||||
|
||||
|
||||
y += 25;
|
||||
}
|
||||
|
||||
|
||||
if (battle.messageSpeaker)
|
||||
{
|
||||
distance = distanceToKM(player->x, player->y, battle.messageSpeaker->x, battle.messageSpeaker->y);
|
||||
|
||||
|
||||
drawText(app.winWidth - 15, y, 14, TA_RIGHT, colors.white, "%s: %.2fkm", battle.messageSpeaker->name, distance);
|
||||
|
||||
|
||||
y += 25;
|
||||
}
|
||||
}
|
||||
|
@ -600,11 +600,11 @@ static void drawHudMessages(void)
|
|||
{
|
||||
HudMessage *hudMessage;
|
||||
int y = app.winHeight - 25;
|
||||
|
||||
|
||||
for (hudMessage = hudMessageHead.next ; hudMessage != NULL ; hudMessage = hudMessage->next)
|
||||
{
|
||||
drawText(10, y, 14, TA_LEFT, hudMessage->color, hudMessage->message);
|
||||
|
||||
|
||||
y -= 25;
|
||||
}
|
||||
}
|
||||
|
@ -615,20 +615,20 @@ static void drawPlayerSelect(void)
|
|||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
setAtlasColor(0, 200, 255, 255);
|
||||
|
||||
|
||||
blit(targetCircle, player->x - battle.camera.x, player->y - battle.camera.y, 1);
|
||||
|
||||
|
||||
drawText(app.winWidth / 2, 500, 28, TA_CENTER, colors.white, NEW_FIGHTER_TEXT);
|
||||
|
||||
|
||||
if (player->health > 0)
|
||||
{
|
||||
drawText(app.winWidth / 2, 540, 20, TA_CENTER, colors.white, "%s (%d%% / %d%%)", player->defName, getPercent(player->health, player->maxHealth), getPercent(player->shield, player->maxShield));
|
||||
}
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blit(arrowLeft, (app.winWidth / 2) - 200, 520, 1);
|
||||
blit(arrowRight, (app.winWidth / 2) + 200, 520, 1);
|
||||
}
|
||||
|
@ -636,33 +636,33 @@ static void drawPlayerSelect(void)
|
|||
static void drawSuspicionLevel(void)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
if (battle.hasSuspicionLevel && !battle.incomingMissile)
|
||||
{
|
||||
battle.suspicionLevel = MIN(battle.suspicionLevel, MAX_SUSPICION_LEVEL);
|
||||
|
||||
|
||||
drawText((app.winWidth / 2) - 150, app.winHeight - 60, 18, TA_RIGHT, colors.white, SUSPICION_TEXT);
|
||||
|
||||
|
||||
r.x = (app.winWidth / 2) - 140;
|
||||
r.y = app.winHeight - 58;
|
||||
r.w = 400;
|
||||
r.h = 20;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 192, 192, 192, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
|
||||
r.x += 2;
|
||||
r.y += 2;
|
||||
r.w -= 4;
|
||||
r.h -= 4;
|
||||
|
||||
|
||||
r.w = MAX((r.w / MAX_SUSPICION_LEVEL) * battle.suspicionLevel, 0);
|
||||
|
||||
|
||||
if (battle.suspicionLevel < (MAX_SUSPICION_LEVEL * 0.5))
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 255, 255);
|
||||
|
@ -675,9 +675,9 @@ static void drawSuspicionLevel(void)
|
|||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
|
||||
|
||||
drawText(r.x + r.w + 7, app.winHeight - 57, 12, TA_LEFT, colors.white, "%d%%", (battle.suspicionLevel > 0) ? getPercent(battle.suspicionLevel, MAX_SUSPICION_LEVEL) : 0);
|
||||
}
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ static void drawMissileWarning(void)
|
|||
void resetHud(void)
|
||||
{
|
||||
HudMessage *hudMessage;
|
||||
|
||||
|
||||
while (hudMessageHead.next)
|
||||
{
|
||||
hudMessage = hudMessageHead.next;
|
||||
|
|
|
@ -50,7 +50,7 @@ void loadItemDefs(void)
|
|||
e->texture = getAtlasImage(cJSON_GetObjectItem(node, "texture")->valuestring);
|
||||
e->health = e->maxHealth = FPS;
|
||||
e->flags = EF_NO_HEALTH_BAR;
|
||||
|
||||
|
||||
e->w = e->texture->rect.w;
|
||||
e->h = e->texture->rect.h;
|
||||
|
||||
|
@ -65,7 +65,7 @@ void loadItemDefs(void)
|
|||
Entity *spawnItem(char *name)
|
||||
{
|
||||
Entity *e, *def, *item;
|
||||
|
||||
|
||||
def = NULL;
|
||||
|
||||
item = spawnEntity();
|
||||
|
@ -86,9 +86,9 @@ Entity *spawnItem(char *name)
|
|||
}
|
||||
|
||||
memcpy(item, def, sizeof(Entity));
|
||||
|
||||
|
||||
item->next = NULL;
|
||||
|
||||
|
||||
item->action = action;
|
||||
|
||||
return item;
|
||||
|
@ -97,7 +97,7 @@ Entity *spawnItem(char *name)
|
|||
void addRandomItem(int x, int y)
|
||||
{
|
||||
Entity *item;
|
||||
|
||||
|
||||
item = spawnItem("RANDOM");
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
|
|
|
@ -33,13 +33,13 @@ static float portalAngle;
|
|||
Entity *spawnJumpgate(int side, long flags)
|
||||
{
|
||||
Entity *jumpgate;
|
||||
|
||||
|
||||
if (battle.jumpgate)
|
||||
{
|
||||
printf("ERROR: Only one jumpgate is allowed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
jumpgate = spawnEntity();
|
||||
jumpgate->type = ET_JUMPGATE;
|
||||
jumpgate->health = jumpgate->maxHealth = 1;
|
||||
|
@ -48,20 +48,20 @@ Entity *spawnJumpgate(int side, long flags)
|
|||
jumpgate->draw = draw;
|
||||
jumpgate->side = side;
|
||||
jumpgate->flags = EF_NO_MT_BOX+EF_IMMORTAL+EF_AI_IGNORE+EF_NON_SOLID+EF_NO_HEALTH_BAR;
|
||||
|
||||
|
||||
if (flags != -1 && flags & EF_DISABLED)
|
||||
{
|
||||
jumpgate->flags |= EF_DISABLED;
|
||||
}
|
||||
|
||||
|
||||
addNodes(jumpgate, flags);
|
||||
|
||||
portal = getAtlasImage("gfx/entities/portal.png");
|
||||
portalAngle = 0;
|
||||
|
||||
|
||||
jumpgate->w = jumpgate->texture->rect.w;
|
||||
jumpgate->h = jumpgate->texture->rect.h;
|
||||
|
||||
|
||||
battle.jumpgate = jumpgate;
|
||||
|
||||
return jumpgate;
|
||||
|
@ -72,9 +72,9 @@ static void addNodes(Entity *jumpgate, long flags)
|
|||
Entity *node;
|
||||
AtlasImage *nodeTexture;
|
||||
int i;
|
||||
|
||||
|
||||
nodeTexture = getAtlasImage("gfx/entities/jumpgateNode.png");
|
||||
|
||||
|
||||
for (i = 0 ; i < 360 ; i += 36)
|
||||
{
|
||||
node = spawnEntity();
|
||||
|
@ -90,20 +90,20 @@ static void addNodes(Entity *jumpgate, long flags)
|
|||
node->die = nodeDie;
|
||||
node->w = node->texture->rect.w;
|
||||
node->h = node->texture->rect.h;
|
||||
|
||||
|
||||
if (jumpgate->side == SIDE_NONE)
|
||||
{
|
||||
node->flags |= EF_NO_HEALTH_BAR;
|
||||
}
|
||||
|
||||
|
||||
if (flags != -1)
|
||||
{
|
||||
node->flags = flags;
|
||||
}
|
||||
|
||||
|
||||
jumpgate->maxHealth++;
|
||||
}
|
||||
|
||||
|
||||
jumpgate->health = jumpgate->maxHealth;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ static void nodeDie(void)
|
|||
if (--battle.jumpgate->health == 1)
|
||||
{
|
||||
battle.jumpgate->flags |= EF_DISABLED;
|
||||
|
||||
|
||||
updateObjective("Jumpgate", TT_DESTROY);
|
||||
updateCondition("Jumpgate", TT_DESTROY);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ int jumpgateEnabled(void)
|
|||
void activateJumpgate(int activate)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
if (battle.jumpgate && battle.jumpgate->health > 1)
|
||||
{
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -158,19 +158,19 @@ static void think(void)
|
|||
self->thinkTime = 4;
|
||||
|
||||
self->angle += 0.1;
|
||||
|
||||
|
||||
if (self->angle >= 360)
|
||||
{
|
||||
self->angle -= 360;
|
||||
}
|
||||
|
||||
|
||||
if (jumpgateEnabled())
|
||||
{
|
||||
handleFleeingEntities();
|
||||
}
|
||||
|
||||
|
||||
portalAngle += 2;
|
||||
|
||||
|
||||
if (portalAngle >= 360)
|
||||
{
|
||||
portalAngle -= 360;
|
||||
|
|
|
@ -23,20 +23,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
void doLocations(void)
|
||||
{
|
||||
Location *l, *prev;
|
||||
|
||||
|
||||
prev = &battle.locationHead;
|
||||
|
||||
|
||||
for (l = battle.locationHead.next ; l != NULL ; l = l->next)
|
||||
{
|
||||
if (l->active && getDistance(player->x, player->y, l->x, l->y) <= l->size)
|
||||
{
|
||||
runScriptFunction(l->name);
|
||||
|
||||
|
||||
prev->next = l->next;
|
||||
free(l);
|
||||
l = prev;
|
||||
}
|
||||
|
||||
|
||||
prev = l;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void doLocations(void)
|
|||
void drawLocations(void)
|
||||
{
|
||||
Location *l;
|
||||
|
||||
|
||||
for (l = battle.locationHead.next ; l != NULL ; l = l->next)
|
||||
{
|
||||
if (l->active)
|
||||
|
@ -58,9 +58,9 @@ void activateLocations(char *locations)
|
|||
{
|
||||
char *token;
|
||||
Location *l;
|
||||
|
||||
|
||||
token = strtok(locations, ";");
|
||||
|
||||
|
||||
while (token)
|
||||
{
|
||||
for (l = battle.locationHead.next ; l != NULL ; l = l->next)
|
||||
|
@ -70,7 +70,7 @@ void activateLocations(char *locations)
|
|||
l->active = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
token = strtok(NULL, ";");
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void createChristabelLocation(void)
|
|||
{
|
||||
Location *l;
|
||||
Entity *e;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (strcmp(e->name, "Christabel") == 0)
|
||||
|
@ -100,7 +100,7 @@ void createChristabelLocation(void)
|
|||
|
||||
l->x -= l->size / 2;
|
||||
l->y -= l->size / 2;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ void loadLocations(cJSON *node)
|
|||
|
||||
l->x += (SCREEN_WIDTH / 2);
|
||||
l->y += (SCREEN_HEIGHT / 2);
|
||||
|
||||
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ void initMessageBox(void)
|
|||
{
|
||||
memset(&head, 0, sizeof(MessageBox));
|
||||
tail = &head;
|
||||
|
||||
|
||||
lastWingmate = NULL;
|
||||
}
|
||||
|
||||
|
@ -40,22 +40,22 @@ void addMessageBox(char *title, char *body, int type)
|
|||
MessageBox *msg;
|
||||
int isFirst;
|
||||
float time;
|
||||
|
||||
|
||||
isFirst = (tail == &head);
|
||||
|
||||
|
||||
msg = malloc(sizeof(MessageBox));
|
||||
memset(msg, 0, sizeof(MessageBox));
|
||||
tail->next = msg;
|
||||
tail = msg;
|
||||
|
||||
|
||||
time = 0.075 * strlen(body);
|
||||
time = MIN(MAX(time, 3), 7);
|
||||
|
||||
|
||||
STRNCPY(msg->title, title, MAX_NAME_LENGTH);
|
||||
STRNCPY(msg->body, body, MAX_DESCRIPTION_LENGTH);
|
||||
msg->time = time * FPS;
|
||||
msg->type = type;
|
||||
|
||||
|
||||
if (isFirst)
|
||||
{
|
||||
nextMessage();
|
||||
|
@ -65,9 +65,9 @@ void addMessageBox(char *title, char *body, int type)
|
|||
void doMessageBox(void)
|
||||
{
|
||||
MessageBox *msg;
|
||||
|
||||
|
||||
msg = head.next;
|
||||
|
||||
|
||||
if (msg)
|
||||
{
|
||||
if (--msg->time <= -(FPS / 4))
|
||||
|
@ -76,13 +76,13 @@ void doMessageBox(void)
|
|||
{
|
||||
tail = &head;
|
||||
}
|
||||
|
||||
|
||||
head.next = msg->next;
|
||||
free(msg);
|
||||
msg = &head;
|
||||
|
||||
|
||||
battle.messageSpeaker = NULL;
|
||||
|
||||
|
||||
if (head.next)
|
||||
{
|
||||
nextMessage();
|
||||
|
@ -94,7 +94,7 @@ void doMessageBox(void)
|
|||
static void calculateMessageBoxHeight(MessageBox *msg)
|
||||
{
|
||||
app.textWidth = MSG_BOX_TEXT_WIDTH;
|
||||
|
||||
|
||||
if (msg->type == MB_PANDORAN)
|
||||
{
|
||||
useFont("khosrau");
|
||||
|
@ -103,11 +103,11 @@ static void calculateMessageBoxHeight(MessageBox *msg)
|
|||
{
|
||||
useFont("roboto");
|
||||
}
|
||||
|
||||
|
||||
msg->height = getWrappedTextHeight(msg->body, 18);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
useFont("roboto");
|
||||
}
|
||||
|
||||
|
@ -120,21 +120,21 @@ void drawMessageBox(void)
|
|||
{
|
||||
MessageBox *msg = head.next;
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
if (msg && msg->time > 0)
|
||||
{
|
||||
if (!msg->height)
|
||||
{
|
||||
calculateMessageBoxHeight(msg);
|
||||
}
|
||||
|
||||
|
||||
r.y = 50;
|
||||
r.w = 650;
|
||||
r.h = msg->height + 40;
|
||||
r.x = (app.winWidth - r.w) / 2;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
|
||||
if (msg->type == MB_IMPORTANT)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 64);
|
||||
|
@ -144,15 +144,15 @@ void drawMessageBox(void)
|
|||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
}
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 128);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
drawText(r.x + 10, r.y + 5, 18, TA_LEFT, colors.cyan, msg->title);
|
||||
|
||||
|
||||
app.textWidth = MSG_BOX_TEXT_WIDTH;
|
||||
|
||||
|
||||
if (msg->type == MB_PANDORAN)
|
||||
{
|
||||
useFont("khosrau");
|
||||
|
@ -161,12 +161,12 @@ void drawMessageBox(void)
|
|||
{
|
||||
useFont("roboto");
|
||||
}
|
||||
|
||||
|
||||
drawText(r.x + 10, r.y + 30, 18, TA_LEFT, (msg->type != MB_IMPORTANT) ? colors.white : colors.red, msg->body);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
}
|
||||
|
||||
|
||||
useFont("roboto");
|
||||
}
|
||||
|
||||
|
@ -174,13 +174,13 @@ static void nextMessage(void)
|
|||
{
|
||||
Entity *e, *wingmate;
|
||||
int isWingmate;
|
||||
|
||||
|
||||
wingmate = NULL;
|
||||
|
||||
|
||||
isWingmate = strcmp(head.next->title, "Wingmate") == 0;
|
||||
|
||||
|
||||
playSound(SND_RADIO);
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->active && e != player)
|
||||
|
@ -190,11 +190,11 @@ static void nextMessage(void)
|
|||
battle.messageSpeaker = lastWingmate = e;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (isWingmate && e->side == player->side && e->type == ET_FIGHTER && e->speed > 0)
|
||||
{
|
||||
wingmate = e;
|
||||
|
||||
|
||||
if (rand() % 2 && e != lastWingmate)
|
||||
{
|
||||
battle.messageSpeaker = lastWingmate = e;
|
||||
|
@ -203,20 +203,20 @@ static void nextMessage(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
battle.messageSpeaker = wingmate;
|
||||
}
|
||||
|
||||
void resetMessageBox(void)
|
||||
{
|
||||
MessageBox *messageBox;
|
||||
|
||||
|
||||
while (head.next)
|
||||
{
|
||||
messageBox = head.next;
|
||||
head.next = messageBox->next;
|
||||
free(messageBox);
|
||||
}
|
||||
|
||||
|
||||
tail = &head;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static AtlasImage *shadowMine = NULL;
|
|||
Entity *spawnMine(int type)
|
||||
{
|
||||
Entity *mine = spawnEntity();
|
||||
|
||||
|
||||
if (!mineWarning)
|
||||
{
|
||||
shadowMine = getAtlasImage("gfx/entities/shadowMine.png");
|
||||
|
@ -50,14 +50,14 @@ Entity *spawnMine(int type)
|
|||
mine->action = think;
|
||||
mine->die = die;
|
||||
mine->flags = EF_TAKES_DAMAGE+EF_NO_PLAYER_TARGET+EF_SHORT_RADAR_RANGE+EF_NON_SOLID+EF_NO_HEALTH_BAR;
|
||||
|
||||
|
||||
if (type == ET_SHADOW_MINE)
|
||||
{
|
||||
mine->flags &= ~EF_NO_PLAYER_TARGET;
|
||||
mine->speed = 100 + rand() % 100;
|
||||
mine->speed *= 0.01;
|
||||
}
|
||||
|
||||
|
||||
mine->w = mine->texture->rect.w;
|
||||
mine->h = mine->texture->rect.h;
|
||||
|
||||
|
@ -67,17 +67,17 @@ Entity *spawnMine(int type)
|
|||
static void think(void)
|
||||
{
|
||||
self->texture = (self->type == ET_MINE) ? mineNormal : shadowMine;
|
||||
|
||||
|
||||
self->angle += 0.1;
|
||||
|
||||
|
||||
if (self->angle >= 360)
|
||||
{
|
||||
self->angle -= 360;
|
||||
}
|
||||
|
||||
|
||||
self->dx *= 0.99;
|
||||
self->dy *= 0.99;
|
||||
|
||||
|
||||
if (self->type == ET_MINE)
|
||||
{
|
||||
lookForFighters();
|
||||
|
@ -86,11 +86,11 @@ static void think(void)
|
|||
{
|
||||
lookForPlayer();
|
||||
}
|
||||
|
||||
|
||||
if (self->systemPower < SYSTEM_POWER && battle.stats[STAT_TIME] % 8 < 4)
|
||||
{
|
||||
playBattleSound(SND_MINE_WARNING, self->x, self->y);
|
||||
|
||||
|
||||
self->texture = mineWarning;
|
||||
}
|
||||
}
|
||||
|
@ -107,16 +107,16 @@ static void lookForFighters(void)
|
|||
if (e->side != self->side && e->health > 0 && e->type == ET_FIGHTER && getDistance(self->x, self->y, e->x, e->y) <= TRIGGER_RANGE)
|
||||
{
|
||||
self->systemPower--;
|
||||
|
||||
|
||||
if (self->systemPower <= 0)
|
||||
{
|
||||
self->health = 0;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self->systemPower = SYSTEM_POWER;
|
||||
}
|
||||
|
||||
|
@ -124,11 +124,11 @@ static void lookForPlayer(void)
|
|||
{
|
||||
float dx, dy, norm;
|
||||
int distance;
|
||||
|
||||
|
||||
if (player->alive == ALIVE_ALIVE)
|
||||
{
|
||||
distance = getDistance(self->x, self->y, player->x, player->y);
|
||||
|
||||
|
||||
if (distance < SCREEN_WIDTH * 2)
|
||||
{
|
||||
dx = player->x - self->x;
|
||||
|
@ -140,37 +140,37 @@ static void lookForPlayer(void)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dx = rand() % 1000;
|
||||
dx -= rand() % 1000;
|
||||
|
||||
|
||||
dy = rand() % 1000;
|
||||
dy -= rand() % 1000;
|
||||
|
||||
|
||||
self->aiActionTime = FPS * (5 + (rand() % 15));
|
||||
}
|
||||
|
||||
|
||||
norm = sqrt(dx * dx + dy * dy);
|
||||
|
||||
|
||||
dx /= norm;
|
||||
dy /= norm;
|
||||
|
||||
|
||||
self->dx = dx * self->speed;
|
||||
self->dy = dy * self->speed;
|
||||
|
||||
|
||||
if (distance <= TRIGGER_RANGE)
|
||||
{
|
||||
self->systemPower--;
|
||||
|
||||
|
||||
if (self->systemPower <= 0)
|
||||
{
|
||||
self->health = 0;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self->systemPower = SYSTEM_POWER;
|
||||
}
|
||||
|
||||
|
@ -180,17 +180,17 @@ static void die(void)
|
|||
{
|
||||
battle.stats[STAT_MINES_DESTROYED]++;
|
||||
}
|
||||
|
||||
|
||||
addMineExplosion();
|
||||
|
||||
|
||||
doSplashDamage();
|
||||
|
||||
|
||||
playBattleSound(SND_EXPLOSION_5, self->x, self->y);
|
||||
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
|
||||
|
||||
updateObjective(self->name, TT_DESTROY);
|
||||
|
||||
|
||||
runScriptFunction("MINES_DESTROYED %d", battle.stats[STAT_MINES_DESTROYED]);
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ static void doSplashDamage(void)
|
|||
float damage, percent;
|
||||
|
||||
candidates = getAllEntsInRadius(self->x, self->y, DAMAGE_RANGE, self);
|
||||
|
||||
|
||||
kills = 0;
|
||||
|
||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||
|
@ -209,20 +209,20 @@ static void doSplashDamage(void)
|
|||
if (e->health > 0 && (e->type == ET_FIGHTER || e->type == ET_MINE) && !(e->flags & EF_IMMORTAL))
|
||||
{
|
||||
dist = getDistance(self->x, self->y, e->x, e->y);
|
||||
|
||||
|
||||
if (dist <= DAMAGE_RANGE)
|
||||
{
|
||||
percent = dist;
|
||||
percent /= DAMAGE_RANGE;
|
||||
percent = 1 - percent;
|
||||
|
||||
|
||||
damage = DAMAGE_RANGE;
|
||||
damage *= percent;
|
||||
|
||||
|
||||
if (e->type == ET_FIGHTER)
|
||||
{
|
||||
damageFighter(e, damage, 0);
|
||||
|
||||
|
||||
if (self->killedBy == player && e != player && e->health <= 0)
|
||||
{
|
||||
kills++;
|
||||
|
@ -232,14 +232,14 @@ static void doSplashDamage(void)
|
|||
{
|
||||
e->dx = e->x - self->x;
|
||||
e->dy = e->y - self->y;
|
||||
|
||||
|
||||
e->dx *= 0.01;
|
||||
e->dy *= 0.01;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (kills >= 2)
|
||||
{
|
||||
awardTrophy("2_BIRDS");
|
||||
|
|
|
@ -37,16 +37,16 @@ static char *TIME_LIMIT_TEXT;
|
|||
void initMissionInfo(void)
|
||||
{
|
||||
int isChallenge = game.currentMission->challengeData.isChallenge;
|
||||
|
||||
|
||||
objectiveStatus[OS_INCOMPLETE] = _("Incomplete");
|
||||
objectiveStatus[OS_COMPLETE] = _("Complete");
|
||||
objectiveStatus[OS_FAILED] = _("Failed");
|
||||
objectiveStatus[OS_CONDITION] = _("Condition");
|
||||
|
||||
|
||||
OBJECTIVES_TEXT = _("OBJECTIVES");
|
||||
NONE_TEXT = _("(none)");
|
||||
TIME_LIMIT_TEXT = _("Time Limit: %s");
|
||||
|
||||
|
||||
missionStartTexture = !isChallenge ? getAtlasImage("gfx/battle/missionStart.png") : getAtlasImage("gfx/battle/challengeStart.png");
|
||||
missionInProgressTexture = !isChallenge ? getAtlasImage("gfx/battle/missionInProgress.png") : getAtlasImage("gfx/battle/challengeInProgress.png");
|
||||
missionCompleteTexture = !isChallenge ? getAtlasImage("gfx/battle/missionComplete.png") : getAtlasImage("gfx/battle/challengeComplete.png");
|
||||
|
@ -57,19 +57,19 @@ void initMissionInfo(void)
|
|||
void drawMissionInfo(void)
|
||||
{
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
switch (battle.status)
|
||||
{
|
||||
case MS_START:
|
||||
drawMissionSummary(missionStartTexture);
|
||||
drawWidgets("startBattle");
|
||||
break;
|
||||
|
||||
|
||||
case MS_PAUSED:
|
||||
drawMissionSummary(missionInProgressTexture);
|
||||
drawWidgets("startBattle");
|
||||
break;
|
||||
|
||||
|
||||
case MS_COMPLETE:
|
||||
case MS_FAILED:
|
||||
if (!battle.unwinnable)
|
||||
|
@ -77,7 +77,7 @@ void drawMissionInfo(void)
|
|||
if (battle.missionFinishedTimer <= -FPS)
|
||||
{
|
||||
drawMissionSummary(battle.status == MS_COMPLETE ? missionCompleteTexture : missionFailedTexture);
|
||||
|
||||
|
||||
if (battle.missionFinishedTimer <= -(FPS * 2))
|
||||
{
|
||||
drawWidgets(battle.status == MS_COMPLETE ? "battleWon" : "battleLost");
|
||||
|
@ -85,12 +85,12 @@ void drawMissionInfo(void)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MS_TIME_UP:
|
||||
if (battle.missionFinishedTimer <= -FPS)
|
||||
{
|
||||
drawMissionSummary(timeUpTexture);
|
||||
|
||||
|
||||
if (battle.missionFinishedTimer <= -(FPS * 2))
|
||||
{
|
||||
drawWidgets("battleWon");
|
||||
|
@ -98,7 +98,7 @@ void drawMissionInfo(void)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -108,11 +108,11 @@ static void drawMissionSummary(AtlasImage *header)
|
|||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
|
||||
blit(header, UI_WIDTH / 2, 150, 1);
|
||||
|
||||
|
||||
if (!game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
drawObjectives();
|
||||
|
@ -128,50 +128,50 @@ static void drawObjectives(void)
|
|||
Objective *o;
|
||||
SDL_Color color;
|
||||
int y = 215;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, y, 28, TA_CENTER, colors.white, OBJECTIVES_TEXT);
|
||||
|
||||
|
||||
y += 10;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->active)
|
||||
{
|
||||
y += 50;
|
||||
|
||||
|
||||
switch (o->status)
|
||||
{
|
||||
case OS_INCOMPLETE:
|
||||
color = colors.white;
|
||||
break;
|
||||
|
||||
|
||||
case OS_COMPLETE:
|
||||
color = colors.green;
|
||||
break;
|
||||
|
||||
|
||||
case OS_FAILED:
|
||||
color = colors.red;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2 - 100, y, 22, TA_RIGHT, colors.white, o->description);
|
||||
|
||||
|
||||
if (o->targetValue > 1 && !o->hideNumbers)
|
||||
{
|
||||
drawText(UI_WIDTH / 2, y, 22, TA_CENTER, colors.white, "%d / %d", o->currentValue, o->targetValue);
|
||||
}
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2 + 100, y, 22, TA_LEFT, color, objectiveStatus[o->status]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!battle.objectiveHead.next)
|
||||
{
|
||||
y += 50;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, y, 22, TA_CENTER, colors.white, NONE_TEXT);
|
||||
}
|
||||
|
||||
|
||||
y += 75;
|
||||
}
|
||||
|
||||
|
@ -182,43 +182,43 @@ static void drawChallenges(void)
|
|||
char *challengeStatus;
|
||||
SDL_Color color;
|
||||
int y = 215;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, y, 24, TA_CENTER, colors.white, game.currentMission->description);
|
||||
|
||||
|
||||
if (battle.status == MS_START && game.currentMission->challengeData.timeLimit)
|
||||
{
|
||||
y+= 50;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, y, 20, TA_CENTER, colors.white, TIME_LIMIT_TEXT, timeToString(game.currentMission->challengeData.timeLimit, 0));
|
||||
}
|
||||
|
||||
|
||||
y += 25;
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_CHALLENGES ; i++)
|
||||
{
|
||||
c = game.currentMission->challengeData.challenges[i];
|
||||
|
||||
|
||||
if (c)
|
||||
{
|
||||
y += 50;
|
||||
|
||||
|
||||
color = colors.white;
|
||||
|
||||
|
||||
challengeStatus = _("Incomplete");
|
||||
|
||||
|
||||
if (c->passed)
|
||||
{
|
||||
color = colors.green;
|
||||
|
||||
|
||||
challengeStatus = _("Complete");
|
||||
}
|
||||
else if (battle.status == MS_COMPLETE ||battle.status == MS_FAILED)
|
||||
{
|
||||
color = colors.red;
|
||||
|
||||
|
||||
challengeStatus = _("Failed");
|
||||
}
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2 - 50, y, 22, TA_RIGHT, colors.white, "%s", getChallengeDescription(c));
|
||||
drawText(UI_WIDTH / 2 + 50, y, 22, TA_LEFT, color, challengeStatus);
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ void doObjectives(void)
|
|||
int objectiveFailed;
|
||||
int hasHidden;
|
||||
Objective *o;
|
||||
|
||||
|
||||
battle.numObjectivesComplete = battle.numObjectivesTotal = battle.numConditions = 0;
|
||||
objectiveFailed = 0;
|
||||
hasHidden = 0;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->active)
|
||||
|
@ -44,17 +44,17 @@ void doObjectives(void)
|
|||
{
|
||||
battle.numConditions++;
|
||||
}
|
||||
|
||||
|
||||
if (o->isEliminateAll && o->status != OS_COMPLETE && !battle.hasThreats)
|
||||
{
|
||||
addHudMessage(colors.green, _("%s - Objective Complete!"), o->description);
|
||||
|
||||
|
||||
o->currentValue = o->targetValue;
|
||||
|
||||
|
||||
o->status = OS_COMPLETE;
|
||||
|
||||
|
||||
runScriptFunction("OBJECTIVES_COMPLETE %d", battle.numObjectivesComplete + 1);
|
||||
|
||||
|
||||
playSound(SND_OBJECTIVE_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void doObjectives(void)
|
|||
{
|
||||
hasHidden = 1;
|
||||
}
|
||||
|
||||
|
||||
if (o->currentValue == o->targetValue)
|
||||
{
|
||||
switch (o->status)
|
||||
|
@ -70,14 +70,14 @@ void doObjectives(void)
|
|||
case OS_COMPLETE:
|
||||
battle.numObjectivesComplete++;
|
||||
break;
|
||||
|
||||
|
||||
case OS_FAILED:
|
||||
objectiveFailed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (battle.status == MS_IN_PROGRESS)
|
||||
{
|
||||
if (!hasHidden && battle.numObjectivesTotal > 0 && battle.numObjectivesComplete == battle.numObjectivesTotal)
|
||||
|
@ -85,16 +85,16 @@ void doObjectives(void)
|
|||
if (fireObjectivesComplete)
|
||||
{
|
||||
fireObjectivesComplete = 0;
|
||||
|
||||
|
||||
runScriptFunction("ALL_OBJECTIVES_COMPLETE");
|
||||
}
|
||||
|
||||
|
||||
if (!battle.manualComplete)
|
||||
{
|
||||
completeMission();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (objectiveFailed)
|
||||
{
|
||||
failMission();
|
||||
|
@ -106,13 +106,13 @@ void updateObjective(char *name, int type)
|
|||
{
|
||||
Objective *o;
|
||||
int completed, hasHidden;
|
||||
|
||||
|
||||
if (strlen(name))
|
||||
{
|
||||
completed = battle.numObjectivesComplete;
|
||||
|
||||
|
||||
hasHidden = 0;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->active && o->status != OS_COMPLETE)
|
||||
|
@ -120,7 +120,7 @@ void updateObjective(char *name, int type)
|
|||
if (!o->isEliminateAll && !o->isCondition && o->targetType == type && o->currentValue < o->targetValue && strcmp(o->targetName, name) == 0)
|
||||
{
|
||||
o->currentValue++;
|
||||
|
||||
|
||||
if (!o->hideNumbers)
|
||||
{
|
||||
if (o->targetValue - o->currentValue <= 10)
|
||||
|
@ -132,32 +132,32 @@ void updateObjective(char *name, int type)
|
|||
addHudMessage(colors.cyan, "%s - %d / %d", o->description, o->currentValue, o->targetValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (o->currentValue == o->targetValue)
|
||||
{
|
||||
addHudMessage(colors.green, _("%s - Objective Complete!"), o->description);
|
||||
|
||||
|
||||
runScriptFunction(o->description);
|
||||
|
||||
|
||||
o->status = OS_COMPLETE;
|
||||
|
||||
|
||||
runScriptFunction("OBJECTIVES_COMPLETE %d", ++completed);
|
||||
|
||||
|
||||
playSound(SND_OBJECTIVE_COMPLETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!o->active)
|
||||
{
|
||||
hasHidden = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (completed == battle.numObjectivesTotal && !hasHidden && fireObjectivesComplete)
|
||||
{
|
||||
fireObjectivesComplete = 0;
|
||||
|
||||
|
||||
runScriptFunction("ALL_OBJECTIVES_COMPLETE");
|
||||
}
|
||||
}
|
||||
|
@ -166,20 +166,20 @@ void updateObjective(char *name, int type)
|
|||
void adjustObjectiveTargetValue(char *name, int type, int amount)
|
||||
{
|
||||
Objective *o;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->active && !o->isCondition && o->targetType == type && o->currentValue < o->targetValue && strcmp(o->targetName, name) == 0)
|
||||
{
|
||||
o->targetValue += amount;
|
||||
o->currentValue = MIN(o->currentValue, o->targetValue);
|
||||
|
||||
|
||||
if (o->currentValue >= o->targetValue && o->targetValue > 0)
|
||||
{
|
||||
o->status = OS_COMPLETE;
|
||||
|
||||
|
||||
addHudMessage(colors.green, _("%s - Objective Complete!"), o->description);
|
||||
|
||||
|
||||
playSound(SND_OBJECTIVE_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ void adjustObjectiveTargetValue(char *name, int type, int amount)
|
|||
void updateCondition(char *name, int type)
|
||||
{
|
||||
Objective *o;
|
||||
|
||||
|
||||
if (strlen(name))
|
||||
{
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
|
@ -197,7 +197,7 @@ void updateCondition(char *name, int type)
|
|||
if (o->active && o->isCondition && o->targetType == type && o->currentValue < o->targetValue && strcmp(o->targetName, name) == 0)
|
||||
{
|
||||
o->currentValue++;
|
||||
|
||||
|
||||
if (o->currentValue == o->targetValue)
|
||||
{
|
||||
o->status = OS_FAILED;
|
||||
|
@ -216,7 +216,7 @@ void updateCondition(char *name, int type)
|
|||
void completeAllObjectives(void)
|
||||
{
|
||||
Objective *o;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
o->status = OS_COMPLETE;
|
||||
|
@ -226,13 +226,13 @@ void completeAllObjectives(void)
|
|||
void completeConditions(void)
|
||||
{
|
||||
Objective *o;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->isCondition)
|
||||
{
|
||||
o->currentValue = o->targetValue;
|
||||
|
||||
|
||||
o->status = OS_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ void completeConditions(void)
|
|||
void failIncompleteObjectives(void)
|
||||
{
|
||||
Objective *o;
|
||||
|
||||
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->status != OS_COMPLETE)
|
||||
|
@ -257,11 +257,11 @@ void activateObjectives(char *objectives)
|
|||
char *token;
|
||||
Objective *o;
|
||||
int activated;
|
||||
|
||||
|
||||
activated = 0;
|
||||
|
||||
|
||||
token = strtok(objectives, ";");
|
||||
|
||||
|
||||
while (token)
|
||||
{
|
||||
for (o = battle.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
|
@ -269,24 +269,24 @@ void activateObjectives(char *objectives)
|
|||
if (strcmp(token, o->id) == 0)
|
||||
{
|
||||
addHudMessage(colors.cyan, _("New Objective : %s"), o->description);
|
||||
|
||||
|
||||
o->active = 1;
|
||||
|
||||
|
||||
/* prevent race condition */
|
||||
doObjectives();
|
||||
|
||||
|
||||
if (o->isEliminateAll)
|
||||
{
|
||||
updateObjective(o->targetName, o->targetType);
|
||||
}
|
||||
|
||||
|
||||
activated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
token = strtok(NULL, ";");
|
||||
}
|
||||
|
||||
|
||||
if (activated)
|
||||
{
|
||||
playSound(SND_NEW_OBJECTIVE);
|
||||
|
@ -326,7 +326,7 @@ void loadObjectives(cJSON *node)
|
|||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fireObjectivesComplete = 1;
|
||||
}
|
||||
|
||||
|
@ -334,12 +334,12 @@ void addEpicLivesObjective(void)
|
|||
{
|
||||
Objective *o;
|
||||
char id[MAX_DESCRIPTION_LENGTH];
|
||||
|
||||
|
||||
o = malloc(sizeof(Objective));
|
||||
memset(o, 0, sizeof(Objective));
|
||||
battle.objectiveTail->next = o;
|
||||
battle.objectiveTail = o;
|
||||
|
||||
|
||||
sprintf(id, _("Do not lose more than %d pilots"), battle.epicLives);
|
||||
|
||||
STRNCPY(o->id, id, MAX_DESCRIPTION_LENGTH);
|
||||
|
@ -355,12 +355,12 @@ void addEpicKillsObjective(void)
|
|||
{
|
||||
Objective *o;
|
||||
char id[MAX_DESCRIPTION_LENGTH];
|
||||
|
||||
|
||||
o = malloc(sizeof(Objective));
|
||||
memset(o, 0, sizeof(Objective));
|
||||
battle.objectiveTail->next = o;
|
||||
battle.objectiveTail = o;
|
||||
|
||||
|
||||
sprintf(id, _("Destroy at least %d enemy fighters"), battle.epicKills);
|
||||
|
||||
STRNCPY(o->id, id, MAX_DESCRIPTION_LENGTH);
|
||||
|
|
|
@ -81,30 +81,30 @@ void initPlayer(void)
|
|||
{
|
||||
player->selectedGunType = 0;
|
||||
}
|
||||
|
||||
|
||||
setPilotName();
|
||||
|
||||
player->action = NULL;
|
||||
|
||||
battle.boostTimer = BOOST_RECHARGE_TIME;
|
||||
battle.ecmTimer = ECM_RECHARGE_TIME;
|
||||
|
||||
|
||||
player->flags |= EF_NO_HEALTH_BAR;
|
||||
player->flags &= ~EF_IMMORTAL;
|
||||
|
||||
|
||||
player->target = NULL;
|
||||
|
||||
|
||||
game.stats[STAT_EPIC_KILL_STREAK] = MAX(game.stats[STAT_EPIC_KILL_STREAK], battle.stats[STAT_EPIC_KILL_STREAK]);
|
||||
|
||||
|
||||
battle.stats[STAT_EPIC_KILL_STREAK] = 0;
|
||||
}
|
||||
|
||||
static void setPilotName(void)
|
||||
{
|
||||
int i, pos;
|
||||
|
||||
|
||||
pos = -1;
|
||||
|
||||
|
||||
for (i = 0 ; i < strlen(game.currentMission->pilot) ; i++)
|
||||
{
|
||||
if (game.currentMission->pilot[i] == ' ')
|
||||
|
@ -112,34 +112,34 @@ static void setPilotName(void)
|
|||
pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memset(player->name, '\0', MAX_NAME_LENGTH);
|
||||
|
||||
|
||||
if (pos != -1)
|
||||
{
|
||||
memcpy(player->name, game.currentMission->pilot + pos + 1, strlen(game.currentMission->pilot) - pos - 1);
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Pilot name = '%s'", player->name);
|
||||
}
|
||||
|
||||
void doPlayer(void)
|
||||
{
|
||||
self = player;
|
||||
|
||||
|
||||
rechargeBoostECM();
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.isChallenge)
|
||||
{
|
||||
applyRestrictions();
|
||||
}
|
||||
|
||||
|
||||
if (player->alive == ALIVE_ALIVE && player->systemPower > 0)
|
||||
{
|
||||
handleKeyboard();
|
||||
|
||||
handleMouse();
|
||||
|
||||
|
||||
handleSuspicionLevel();
|
||||
|
||||
if (!player->target || player->target->health <= 0 || player->target->systemPower <= 0 || targetOutOfRange())
|
||||
|
@ -157,22 +157,22 @@ void doPlayer(void)
|
|||
if (!game.currentMission->challengeData.allowPlayerDeath)
|
||||
{
|
||||
updateDeathStats();
|
||||
|
||||
|
||||
failMission();
|
||||
}
|
||||
}
|
||||
else if (!battle.isEpic)
|
||||
{
|
||||
updateDeathStats();
|
||||
|
||||
|
||||
failMission();
|
||||
}
|
||||
else if (player->health == -FPS)
|
||||
{
|
||||
updateDeathStats();
|
||||
|
||||
|
||||
updateCondition("PLAYER", TT_DESTROY);
|
||||
|
||||
|
||||
if (battle.status == MS_IN_PROGRESS)
|
||||
{
|
||||
initPlayerSelect();
|
||||
|
@ -189,7 +189,7 @@ void doPlayer(void)
|
|||
{
|
||||
player->missiles = 999;
|
||||
}
|
||||
|
||||
|
||||
/* really only used in challenge mode */
|
||||
if (player->systemPower <= 0 && battle.status == MS_IN_PROGRESS)
|
||||
{
|
||||
|
@ -209,7 +209,7 @@ void doPlayer(void)
|
|||
static void updateDeathStats(void)
|
||||
{
|
||||
battle.stats[STAT_PLAYER_KILLED]++;
|
||||
|
||||
|
||||
/* the player is known as "Player", so we need to check the craft they were assigned to */
|
||||
if (strcmp(game.currentMission->craft, "ATAF") == 0)
|
||||
{
|
||||
|
@ -220,14 +220,14 @@ static void updateDeathStats(void)
|
|||
static void rechargeBoostECM(void)
|
||||
{
|
||||
int boostTimer, ecmTimer;
|
||||
|
||||
|
||||
boostTimer = battle.boostTimer;
|
||||
battle.boostTimer = MIN(battle.boostTimer + 1, BOOST_RECHARGE_TIME);
|
||||
if (boostTimer < BOOST_RECHARGE_TIME && battle.boostTimer == BOOST_RECHARGE_TIME)
|
||||
{
|
||||
playSound(SND_RECHARGED);
|
||||
}
|
||||
|
||||
|
||||
ecmTimer = battle.ecmTimer;
|
||||
battle.ecmTimer = MIN(battle.ecmTimer + 1, ECM_RECHARGE_TIME);
|
||||
if (ecmTimer < ECM_RECHARGE_TIME && battle.ecmTimer == ECM_RECHARGE_TIME)
|
||||
|
@ -247,17 +247,17 @@ static void applyRestrictions(void)
|
|||
{
|
||||
player->missiles = 0;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.noBoost)
|
||||
{
|
||||
battle.boostTimer = 0;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.noECM)
|
||||
{
|
||||
battle.ecmTimer = 0;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.noGuns)
|
||||
{
|
||||
player->reload = 1;
|
||||
|
@ -342,7 +342,7 @@ static void handleKeyboard(void)
|
|||
static void handleMouse(void)
|
||||
{
|
||||
faceMouse();
|
||||
|
||||
|
||||
if (battle.status == MS_IN_PROGRESS)
|
||||
{
|
||||
if (isControl(CONTROL_FIRE) && !player->reload && player->guns[0].type)
|
||||
|
@ -355,13 +355,13 @@ static void handleMouse(void)
|
|||
{
|
||||
fireRocket(player);
|
||||
}
|
||||
|
||||
|
||||
if (battle.hasSuspicionLevel && !battle.numEnemies && !battle.suspicionCoolOff)
|
||||
{
|
||||
battle.suspicionLevel += (MAX_SUSPICION_LEVEL * 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_ACCELERATE))
|
||||
{
|
||||
if (battle.boostTimer > BOOST_FINISHED_TIME || game.currentMission->challengeData.noBoost)
|
||||
|
@ -369,25 +369,25 @@ static void handleMouse(void)
|
|||
applyFighterThrust();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_MISSILE))
|
||||
{
|
||||
preFireMissile();
|
||||
|
||||
|
||||
app.mouse.button[SDL_BUTTON_MIDDLE] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_GUNS))
|
||||
{
|
||||
switchGuns();
|
||||
|
||||
|
||||
app.mouse.button[SDL_BUTTON_X1] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_RADAR))
|
||||
{
|
||||
cycleRadarZoom();
|
||||
|
||||
|
||||
app.mouse.button[SDL_BUTTON_X2] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -425,14 +425,14 @@ static void preFireMissile(void)
|
|||
else
|
||||
{
|
||||
playSound(SND_GUI_DENIED);
|
||||
|
||||
|
||||
addHudMessage(colors.white, _("Target not in range"));
|
||||
}
|
||||
}
|
||||
else if (!player->missiles)
|
||||
{
|
||||
addHudMessage(colors.white, _("Out of missiles"));
|
||||
|
||||
|
||||
playSound(SND_NO_MISSILES);
|
||||
}
|
||||
}
|
||||
|
@ -440,11 +440,11 @@ static void preFireMissile(void)
|
|||
static void initPlayerSelect(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
memset(&availablePlayerUnits, 0, sizeof(Entity*) * MAX_SELECTABLE_PLAYERS);
|
||||
|
||||
selectedPlayerIndex = 0;
|
||||
|
||||
|
||||
if (battle.epicLives == 0 || (battle.epicLives > 0 && --battle.epicLives > 0))
|
||||
{
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -465,7 +465,7 @@ static void initPlayerSelect(void)
|
|||
else
|
||||
{
|
||||
battle.isEpic = 0;
|
||||
|
||||
|
||||
if (battle.epicKills > 0 && battle.stats[STAT_ENEMIES_KILLED_PLAYER] < battle.epicKills)
|
||||
{
|
||||
battle.unwinnable = 0;
|
||||
|
@ -480,23 +480,23 @@ void doPlayerSelect(void)
|
|||
if (isControl(CONTROL_PREV_FIGHTER))
|
||||
{
|
||||
selectNewPlayer(-1);
|
||||
|
||||
|
||||
clearControl(CONTROL_PREV_FIGHTER);
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_NEXT_FIGHTER))
|
||||
{
|
||||
selectNewPlayer(1);
|
||||
|
||||
|
||||
clearControl(CONTROL_NEXT_FIGHTER);
|
||||
}
|
||||
|
||||
|
||||
if (player->health > 0 && isAcceptControl())
|
||||
{
|
||||
battle.playerSelect = 0;
|
||||
|
||||
|
||||
initPlayer();
|
||||
|
||||
|
||||
resetAcceptControls();
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ void doPlayerSelect(void)
|
|||
static void selectNewPlayer(int dir)
|
||||
{
|
||||
player = NULL;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
selectedPlayerIndex += dir;
|
||||
|
@ -554,7 +554,7 @@ static void activateECM(void)
|
|||
addECMEffect(player);
|
||||
|
||||
battle.stats[STAT_ECM]++;
|
||||
|
||||
|
||||
if (battle.hasSuspicionLevel && !battle.numEnemies && !battle.suspicionCoolOff)
|
||||
{
|
||||
battle.suspicionLevel += (MAX_SUSPICION_LEVEL * 0.25);
|
||||
|
@ -594,18 +594,18 @@ static void selectTarget(void)
|
|||
i = 0;
|
||||
near = NULL;
|
||||
memset(targets, 0, sizeof(Entity*) * MAX_SELECTABLE_TARGETS);
|
||||
|
||||
|
||||
if (player->target && (!player->target->health || !player->target->systemPower))
|
||||
{
|
||||
player->target = NULL;
|
||||
}
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->active && e != player && (e->flags & EF_TAKES_DAMAGE) && (!(e->flags & EF_NO_PLAYER_TARGET)) && e->side != player->side && e->alive == ALIVE_ALIVE && e->systemPower > 0 && i < MAX_SELECTABLE_TARGETS)
|
||||
{
|
||||
dist = getDistance(player->x, player->y, e->x, e->y);
|
||||
|
||||
|
||||
if (dist < closest)
|
||||
{
|
||||
near = e;
|
||||
|
@ -693,13 +693,13 @@ static int isPriorityMissionTarget(Entity *e, int dist, int closest)
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* battle.missionTarget is not secondary, e is */
|
||||
if ((battle.missionTarget->flags & EF_SECONDARY_TARGET) < (e->flags & EF_SECONDARY_TARGET))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* normal distance check */
|
||||
return dist < closest;
|
||||
}
|
||||
|
@ -707,9 +707,9 @@ static int isPriorityMissionTarget(Entity *e, int dist, int closest)
|
|||
void setInitialPlayerAngle(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
selectMissionTarget();
|
||||
|
||||
|
||||
if (battle.missionTarget)
|
||||
{
|
||||
player->angle = getAngle(player->x, player->y, battle.missionTarget->x, battle.missionTarget->y);
|
||||
|
@ -717,7 +717,7 @@ void setInitialPlayerAngle(void)
|
|||
else
|
||||
{
|
||||
selectTarget();
|
||||
|
||||
|
||||
if (player->target)
|
||||
{
|
||||
player->angle = getAngle(player->x, player->y, player->target->x, player->target->y);
|
||||
|
@ -730,7 +730,7 @@ void setInitialPlayerAngle(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->side == player->side)
|
||||
|
@ -743,7 +743,7 @@ void setInitialPlayerAngle(void)
|
|||
static void cycleRadarZoom(void)
|
||||
{
|
||||
battle.radarRange = (battle.radarRange + 1) % 3;
|
||||
|
||||
|
||||
playSound(SND_ZOOM);
|
||||
}
|
||||
|
||||
|
@ -780,12 +780,12 @@ void loadPlayer(cJSON *node)
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
if (cJSON_GetObjectItem(node, "flags"))
|
||||
{
|
||||
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
||||
}
|
||||
|
||||
|
||||
if (flags != -1)
|
||||
{
|
||||
if (addFlags)
|
||||
|
|
|
@ -36,7 +36,7 @@ void initQuadtree(Quadtree *root)
|
|||
{
|
||||
Quadtree *node;
|
||||
int i, w, h;
|
||||
|
||||
|
||||
/* entire battlefield */
|
||||
if (root->depth == 0)
|
||||
{
|
||||
|
@ -45,16 +45,16 @@ void initQuadtree(Quadtree *root)
|
|||
root->capacity = QT_INITIAL_CAPACITY;
|
||||
root->ents = malloc(sizeof(Entity*) * root->capacity);
|
||||
memset(root->ents, 0, sizeof(Entity*) * root->capacity);
|
||||
|
||||
|
||||
cIndex = 0;
|
||||
cCapacity = QT_INITIAL_CAPACITY;
|
||||
candidates = malloc(sizeof(Entity*) * cCapacity);
|
||||
memset(candidates, 0, sizeof(Entity*) * cCapacity);
|
||||
}
|
||||
|
||||
|
||||
w = root->w / 2;
|
||||
h = root->h / 2;
|
||||
|
||||
|
||||
if (root->depth + 1 < QT_MAX_DEPTH)
|
||||
{
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
|
@ -62,12 +62,12 @@ void initQuadtree(Quadtree *root)
|
|||
node = malloc(sizeof(Quadtree));
|
||||
memset(node, 0, sizeof(Quadtree));
|
||||
root->node[i] = node;
|
||||
|
||||
|
||||
node->depth = root->depth + 1;
|
||||
node->capacity = QT_INITIAL_CAPACITY;
|
||||
node->ents = malloc(sizeof(Entity*) * node->capacity);
|
||||
memset(node->ents, 0, sizeof(Entity*) * node->capacity);
|
||||
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
node->x = root->x;
|
||||
|
@ -96,7 +96,7 @@ void initQuadtree(Quadtree *root)
|
|||
node->w = w;
|
||||
node->h = h;
|
||||
}
|
||||
|
||||
|
||||
initQuadtree(node);
|
||||
}
|
||||
}
|
||||
|
@ -105,36 +105,36 @@ void initQuadtree(Quadtree *root)
|
|||
void addToQuadtree(Entity *e, Quadtree *root)
|
||||
{
|
||||
int index;
|
||||
|
||||
|
||||
root->addedTo = 1;
|
||||
|
||||
|
||||
if (root->node[0])
|
||||
{
|
||||
index = getIndex(root, e->x - (e->w / 2), e->y - (e->h / 2), e->w, e->h);
|
||||
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
addToQuadtree(e, root->node[index]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (root->numEnts == root->capacity)
|
||||
{
|
||||
resizeQTEntCapacity(root);
|
||||
}
|
||||
|
||||
|
||||
root->ents[root->numEnts++] = e;
|
||||
}
|
||||
|
||||
static void resizeQTEntCapacity(Quadtree *root)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
n = root->capacity + QT_INITIAL_CAPACITY;
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Resizing QT node: %d -> %d", root->capacity, n);
|
||||
|
||||
|
||||
root->ents = resize(root->ents, sizeof(Entity*) * root->capacity, sizeof(Entity*) * n);
|
||||
root->capacity = n;
|
||||
}
|
||||
|
@ -177,26 +177,26 @@ static int getIndex(Quadtree *root, int x, int y, int w, int h)
|
|||
void removeFromQuadtree(Entity *e, Quadtree *root)
|
||||
{
|
||||
int index;
|
||||
|
||||
|
||||
if (root->addedTo)
|
||||
{
|
||||
if (root->node[0])
|
||||
{
|
||||
index = getIndex(root, e->x - (e->w / 2), e->y - (e->h / 2), e->w, e->h);
|
||||
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
removeFromQuadtree(e, root->node[index]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeEntity(e, root);
|
||||
|
||||
|
||||
if (root->numEnts == 0)
|
||||
{
|
||||
root->addedTo = 0;
|
||||
|
||||
|
||||
if (root->node[0])
|
||||
{
|
||||
root->addedTo = root->node[0]->addedTo || root->node[1]->addedTo || root->node[2]->addedTo || root->node[3]->addedTo;
|
||||
|
@ -208,9 +208,9 @@ void removeFromQuadtree(Entity *e, Quadtree *root)
|
|||
static void removeEntity(Entity *e, Quadtree *root)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
|
||||
n = root->numEnts;
|
||||
|
||||
|
||||
for (i = 0 ; i < root->capacity ; i++)
|
||||
{
|
||||
if (root->ents[i] == e)
|
||||
|
@ -219,7 +219,7 @@ static void removeEntity(Entity *e, Quadtree *root)
|
|||
root->numEnts--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qsort(root->ents, n, sizeof(Entity*), candidatesComparator);
|
||||
}
|
||||
|
||||
|
@ -227,9 +227,9 @@ Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore)
|
|||
{
|
||||
cIndex = 0;
|
||||
memset(candidates, 0, sizeof(Entity*) * cCapacity);
|
||||
|
||||
|
||||
getAllEntsWithinNode(x, y, w, h, ignore, &battle.quadtree);
|
||||
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
|
@ -241,13 +241,13 @@ Entity **getAllEntsInRadius(int x, int y, int radius, Entity *ignore)
|
|||
static void getAllEntsWithinNode(int x, int y, int w, int h, Entity *ignore, Quadtree *root)
|
||||
{
|
||||
int index, i;
|
||||
|
||||
|
||||
if (root->addedTo)
|
||||
{
|
||||
if (root->node[0])
|
||||
{
|
||||
index = getIndex(root, x, y, w, h);
|
||||
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
getAllEntsWithinNode(x, y, w, h, ignore, root->node[index]);
|
||||
|
@ -260,11 +260,11 @@ static void getAllEntsWithinNode(int x, int y, int w, int h, Entity *ignore, Qua
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < root->numEnts ; i++)
|
||||
{
|
||||
candidates[cIndex++] = root->ents[i];
|
||||
|
||||
|
||||
if (cIndex == cCapacity)
|
||||
{
|
||||
resizeCandidates();
|
||||
|
@ -276,11 +276,11 @@ static void getAllEntsWithinNode(int x, int y, int w, int h, Entity *ignore, Qua
|
|||
static void resizeCandidates(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
n = cCapacity + QT_INITIAL_CAPACITY;
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Resizing candidates: %d -> %d", cCapacity, n);
|
||||
|
||||
|
||||
candidates = resize(candidates, sizeof(Entity*) * cCapacity, sizeof(Entity*) * n);
|
||||
cCapacity = n;
|
||||
}
|
||||
|
@ -288,11 +288,11 @@ static void resizeCandidates(void)
|
|||
void destroyQuadtree(void)
|
||||
{
|
||||
destroyQuadtreeNode(&battle.quadtree);
|
||||
|
||||
|
||||
if (candidates)
|
||||
{
|
||||
free(candidates);
|
||||
|
||||
|
||||
candidates = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -300,19 +300,19 @@ void destroyQuadtree(void)
|
|||
static void destroyQuadtreeNode(Quadtree *root)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
free(root->ents);
|
||||
|
||||
|
||||
root->ents = NULL;
|
||||
|
||||
|
||||
if (root->node[0])
|
||||
{
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
destroyQuadtreeNode(root->node[i]);
|
||||
|
||||
|
||||
free(root->node[i]);
|
||||
|
||||
|
||||
root->node[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ static int candidatesComparator(const void *a, const void *b)
|
|||
{
|
||||
Entity *e1 = *((Entity**)a);
|
||||
Entity *e2 = *((Entity**)b);
|
||||
|
||||
|
||||
if (!e1)
|
||||
{
|
||||
return 1;
|
||||
|
|
|
@ -29,10 +29,10 @@ void initRadar(void)
|
|||
{
|
||||
radarTexture = getAtlasImage("gfx/hud/radar.png");
|
||||
radarWarningTexture = getAtlasImage("gfx/hud/radarWarning.png");
|
||||
|
||||
|
||||
/* medium range by default */
|
||||
battle.radarRange = 1;
|
||||
|
||||
|
||||
CAUTION_TEXT = _("Caution: Leaving battle area - turn around.");
|
||||
}
|
||||
|
||||
|
@ -41,34 +41,34 @@ void drawRadar(void)
|
|||
SDL_Rect r;
|
||||
Entity *e;
|
||||
int dist, inRange, blink;
|
||||
|
||||
|
||||
blit(radarTexture, app.winWidth - 85, app.winHeight - 85, 1);
|
||||
|
||||
|
||||
drawText(app.winWidth - 160, app.winHeight - 30, 14, TA_RIGHT, colors.white, "%dx", battle.radarRange + 1);
|
||||
|
||||
|
||||
r.w = r.h = 3;
|
||||
|
||||
|
||||
blink = battle.stats[STAT_TIME] % 60 < 30;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
dist = getDistance(e->x, e->y, player->x, player->y);
|
||||
|
||||
|
||||
if (e->active)
|
||||
{
|
||||
inRange = (!(e->flags & EF_SHORT_RADAR_RANGE)) ? (dist / radarRanges[battle.radarRange]) < 70 : dist < 500;
|
||||
|
||||
|
||||
if (inRange)
|
||||
{
|
||||
r.x = app.winWidth - 85;
|
||||
r.y = app.winHeight - 85;
|
||||
|
||||
|
||||
r.x -= (player->x - e->x) / radarRanges[battle.radarRange];
|
||||
r.y -= (player->y - e->y) / radarRanges[battle.radarRange];
|
||||
|
||||
|
||||
r.x--;
|
||||
r.y--;
|
||||
|
||||
|
||||
if (e->side == SIDE_NONE)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 255, 255);
|
||||
|
@ -81,25 +81,25 @@ void drawRadar(void)
|
|||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
if (e->type == ET_MINE || e->type == ET_SHADOW_MINE || e->type == ET_JUMPGATE || (e->owner && e->owner->type == ET_JUMPGATE))
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
|
||||
if (blink)
|
||||
{
|
||||
if (e == player->target || e == battle.missionTarget)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 255, 255, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
if (e->flags & EF_DISABLED)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 192, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
}
|
||||
}
|
||||
|
@ -109,39 +109,39 @@ void drawRadar(void)
|
|||
void drawRadarRangeWarning(void)
|
||||
{
|
||||
int x, y, leaving;
|
||||
|
||||
|
||||
x = (int)player->x / (app.winWidth / 2);
|
||||
y = (int)player->y / (app.winHeight / 2);
|
||||
leaving = 0;
|
||||
|
||||
|
||||
if (x <= 2 && player->dx < 0)
|
||||
{
|
||||
blitRotated(radarWarningTexture, app.winWidth - 85, app.winHeight - 85, 270);
|
||||
|
||||
|
||||
leaving = 1;
|
||||
}
|
||||
|
||||
|
||||
if (y <= 3 && player->dy < 0)
|
||||
{
|
||||
blitRotated(radarWarningTexture, app.winWidth - 85, app.winHeight - 85, 0);
|
||||
|
||||
|
||||
leaving = 1;
|
||||
}
|
||||
|
||||
|
||||
if (x >= BATTLE_AREA_CELLS - 2 && player->dx > 0)
|
||||
{
|
||||
blitRotated(radarWarningTexture, app.winWidth - 85, app.winHeight - 85, 90);
|
||||
|
||||
|
||||
leaving = 1;
|
||||
}
|
||||
|
||||
|
||||
if (y >= BATTLE_AREA_CELLS - 3 && player->dy > 0)
|
||||
{
|
||||
blitRotated(radarWarningTexture, app.winWidth - 85, app.winHeight - 85, 180);
|
||||
|
||||
|
||||
leaving = 1;
|
||||
}
|
||||
|
||||
|
||||
if (leaving && battle.stats[STAT_TIME] % FPS < 40)
|
||||
{
|
||||
drawText(app.winWidth / 2, app.winHeight - 30, 14, TA_CENTER, colors.white, CAUTION_TEXT);
|
||||
|
|
|
@ -24,35 +24,35 @@ void attachRope(void)
|
|||
{
|
||||
int i, distance;
|
||||
Entity *e, **candidates;
|
||||
|
||||
|
||||
if ((self->flags & EF_HAS_ROPE) && self->towing == NULL)
|
||||
{
|
||||
candidates = getAllEntsInRadius(self->x, self->y, self->separationRadius, self);
|
||||
|
||||
|
||||
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
|
||||
{
|
||||
if (!e->owner && e->type == ET_FIGHTER && (e->flags & EF_DISABLED) && (e->flags & EF_ROPED_ATTACHED) == 0 && e->alive == ALIVE_ALIVE)
|
||||
{
|
||||
distance = getDistance(e->x, e->y, self->x, self->y);
|
||||
|
||||
|
||||
if (distance > 0 && distance <= self->separationRadius)
|
||||
{
|
||||
self->towing = e;
|
||||
self->aiFlags |= AIF_GOAL_JUMPGATE;
|
||||
|
||||
|
||||
e->owner = self;
|
||||
e->speed = 1;
|
||||
e->flags |= EF_RETREATING;
|
||||
e->flags |= EF_ROPED_ATTACHED;
|
||||
|
||||
|
||||
runScriptFunction("TOWING %s", e->name);
|
||||
|
||||
|
||||
if (self == player)
|
||||
{
|
||||
battle.stats[STAT_NUM_TOWED]++;
|
||||
addHudMessage(colors.white, _("Tow rope attached"));
|
||||
}
|
||||
|
||||
|
||||
playBattleSound(SND_TOW_ROPE, e->x, e->y);
|
||||
}
|
||||
}
|
||||
|
@ -64,23 +64,23 @@ void doRope(Entity *owner)
|
|||
{
|
||||
float dx, dy, angle, force;
|
||||
int distance;
|
||||
|
||||
|
||||
if (owner->towing)
|
||||
{
|
||||
distance = getDistance(owner->towing->x, owner->towing->y, owner->x, owner->y);
|
||||
|
||||
|
||||
if (distance > ROPE_DISTANCE)
|
||||
{
|
||||
angle = getAngle(owner->x, owner->y, owner->towing->x, owner->towing->y);
|
||||
|
||||
|
||||
dx = sin(TO_RAIDANS(angle));
|
||||
dy = -cos(TO_RAIDANS(angle));
|
||||
force = (distance - ROPE_DISTANCE) * 0.02;
|
||||
|
||||
|
||||
owner->towing->dx -= (dx * force);
|
||||
owner->towing->dy -= (dy * force);
|
||||
}
|
||||
|
||||
|
||||
owner->towing->dx *= 0.985;
|
||||
owner->towing->dy *= 0.985;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ void drawRope(Entity *e)
|
|||
if (e->towing)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
|
||||
|
||||
|
||||
SDL_RenderDrawLine(app.renderer, e->x - battle.camera.x, e->y - battle.camera.y, e->towing->x - battle.camera.x, e->towing->y - battle.camera.y);
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ void cutRope(Entity *e)
|
|||
e->owner->towing = NULL;
|
||||
e->owner->aiFlags &= ~AIF_GOAL_JUMPGATE;
|
||||
}
|
||||
|
||||
|
||||
/* tug is dead - reset thing being tugged */
|
||||
if (e->towing)
|
||||
{
|
||||
|
|
|
@ -31,16 +31,16 @@ static int runScript;
|
|||
void initScript(cJSON *root)
|
||||
{
|
||||
cJSON *function;
|
||||
|
||||
|
||||
memset(&head, 0, sizeof(ScriptRunner));
|
||||
tail = &head;
|
||||
|
||||
|
||||
rootJSON = root;
|
||||
|
||||
|
||||
runScript = 0;
|
||||
|
||||
scriptJSON = cJSON_GetObjectItem(root, "script");
|
||||
|
||||
|
||||
if (scriptJSON)
|
||||
{
|
||||
function = scriptJSON->child;
|
||||
|
@ -48,10 +48,10 @@ void initScript(cJSON *root)
|
|||
while (function)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Found script function: '%s'", cJSON_GetObjectItem(function, "function")->valuestring);
|
||||
|
||||
|
||||
function = function->next;
|
||||
}
|
||||
|
||||
|
||||
runScript = 1;
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ void runScriptFunction(const char *format, ...)
|
|||
tail = scriptRunner;
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Running script '%s'", funcNameBuffer);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -284,25 +284,25 @@ static void executeNextLine(ScriptRunner *runner)
|
|||
void cancelScript(void)
|
||||
{
|
||||
ScriptRunner *runner;
|
||||
|
||||
|
||||
while (head.next)
|
||||
{
|
||||
runner = head.next;
|
||||
head.next = runner->next;
|
||||
free(runner);
|
||||
}
|
||||
|
||||
|
||||
tail = &head;
|
||||
}
|
||||
|
||||
void destroyScript(void)
|
||||
{
|
||||
ScriptRunner *scriptRunner;
|
||||
|
||||
|
||||
if (rootJSON)
|
||||
{
|
||||
cJSON_Delete(rootJSON);
|
||||
|
||||
|
||||
rootJSON = NULL;
|
||||
}
|
||||
|
||||
|
@ -314,6 +314,6 @@ void destroyScript(void)
|
|||
}
|
||||
|
||||
tail = &head;
|
||||
|
||||
|
||||
scriptJSON = NULL;
|
||||
}
|
||||
|
|
|
@ -27,27 +27,27 @@ void doSpawners(void)
|
|||
char *type;
|
||||
int i, num, addFlags, addAIFlags;
|
||||
long flags, aiFlags;
|
||||
|
||||
|
||||
for (s = battle.spawnerHead.next ; s != NULL ; s = s->next)
|
||||
{
|
||||
if (s->active && --s->time <= 0)
|
||||
{
|
||||
aiFlags = flags = -1;
|
||||
|
||||
|
||||
num = s->step;
|
||||
|
||||
|
||||
if (s->total != -1)
|
||||
{
|
||||
num = MIN(s->step, s->total);
|
||||
|
||||
|
||||
s->total -= num;
|
||||
}
|
||||
|
||||
|
||||
if (s->side != SIDE_ALLIES)
|
||||
{
|
||||
battle.numInitialEnemies += num;
|
||||
}
|
||||
|
||||
|
||||
if (strlen(s->flags))
|
||||
{
|
||||
flags = flagsToLong(s->flags, &addFlags);
|
||||
|
@ -57,15 +57,15 @@ void doSpawners(void)
|
|||
{
|
||||
aiFlags = flagsToLong(s->aiFlags, &addAIFlags);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < num ; i++)
|
||||
{
|
||||
type = s->types[rand() % s->numTypes];
|
||||
|
||||
|
||||
e = spawnFighter(type, 0, 0, s->side);
|
||||
|
||||
|
||||
e->spawned = 1;
|
||||
|
||||
|
||||
if (s->offscreen)
|
||||
{
|
||||
e->x = player->x;
|
||||
|
@ -76,10 +76,10 @@ void doSpawners(void)
|
|||
e->x = rand() % 2 ? 0 : BATTLE_AREA_WIDTH;
|
||||
e->y = rand() % 2 ? 0 : BATTLE_AREA_HEIGHT;
|
||||
}
|
||||
|
||||
|
||||
e->x += (rand() % 2) ? -SCREEN_WIDTH * 3 : SCREEN_WIDTH * 3;
|
||||
e->y += (rand() % 2) ? -SCREEN_HEIGHT * 3 : SCREEN_HEIGHT * 3;
|
||||
|
||||
|
||||
if (flags != -1)
|
||||
{
|
||||
if (addFlags)
|
||||
|
@ -91,7 +91,7 @@ void doSpawners(void)
|
|||
e->flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (aiFlags != -1)
|
||||
{
|
||||
if (addAIFlags)
|
||||
|
@ -104,7 +104,7 @@ void doSpawners(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s->time = s->interval;
|
||||
}
|
||||
}
|
||||
|
@ -127,12 +127,12 @@ void activateTrespasserSpawner(void)
|
|||
{
|
||||
Spawner *s;
|
||||
char types[MAX_DESCRIPTION_LENGTH];
|
||||
|
||||
|
||||
s = malloc(sizeof(Spawner));
|
||||
memset(s, 0, sizeof(Spawner));
|
||||
battle.spawnerTail->next = s;
|
||||
battle.spawnerTail = s;
|
||||
|
||||
|
||||
STRNCPY(types, "Jackal;Mantis;Sphinx;Scarab", MAX_DESCRIPTION_LENGTH);
|
||||
|
||||
s->types = toTypeArray(types, &s->numTypes);
|
||||
|
|
|
@ -25,15 +25,15 @@ static Star stars[MAX_STARS];
|
|||
void initStars(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
memset(stars, 0, sizeof(Star) * MAX_STARS);
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_STARS ; i++)
|
||||
{
|
||||
stars[i].x = rand() % app.winWidth;
|
||||
stars[i].y = rand() % app.winHeight;
|
||||
stars[i].speed = 5 + rand() % 35;
|
||||
|
||||
|
||||
stars[i].speed *= 0.1;
|
||||
}
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ void initStars(void)
|
|||
void doStars(float dx, float dy)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_STARS ; i++)
|
||||
{
|
||||
stars[i].x -= (dx * stars[i].speed);
|
||||
stars[i].y -= (dy * stars[i].speed);
|
||||
|
||||
|
||||
stars[i].x = mod(stars[i].x, app.winWidth - 1);
|
||||
stars[i].y = mod(stars[i].y, app.winHeight - 1);
|
||||
}
|
||||
|
@ -56,15 +56,15 @@ void drawStars(void)
|
|||
{
|
||||
int i;
|
||||
int c;
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_STARS ; i++)
|
||||
{
|
||||
c = 64 * stars[i].speed;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, c, c, c, 255);
|
||||
|
||||
|
||||
SDL_RenderDrawPoint(app.renderer, stars[i].x, stars[i].y);
|
||||
|
||||
|
||||
if (c >= 240)
|
||||
{
|
||||
SDL_RenderDrawPoint(app.renderer, stars[i].x + 1, stars[i].y + 1);
|
||||
|
|
|
@ -37,7 +37,7 @@ void resetWaypoints(void)
|
|||
Entity *spawnWaypoint(void)
|
||||
{
|
||||
Entity *waypoint = spawnEntity();
|
||||
|
||||
|
||||
sprintf(waypoint->name, "Waypoint #%d", waypointId);
|
||||
waypoint->id = waypointId;
|
||||
waypoint->type = ET_WAYPOINT;
|
||||
|
@ -46,43 +46,43 @@ Entity *spawnWaypoint(void)
|
|||
waypoint->texture = getAtlasImage("gfx/entities/waypoint.png");
|
||||
waypoint->flags = EF_NO_MT_BOX+EF_MISSION_TARGET+EF_NO_HEALTH_BAR;
|
||||
waypoint->action = think;
|
||||
|
||||
|
||||
waypoint->w = waypoint->texture->rect.w;
|
||||
waypoint->h = waypoint->texture->rect.h;
|
||||
|
||||
|
||||
waypointId++;
|
||||
|
||||
|
||||
return waypoint;
|
||||
}
|
||||
|
||||
static void think(void)
|
||||
{
|
||||
self->angle += 0.25;
|
||||
|
||||
|
||||
if (self->angle >= 360)
|
||||
{
|
||||
self->angle -= 360;
|
||||
}
|
||||
|
||||
|
||||
if (--self->aiActionTime <= 0)
|
||||
{
|
||||
self->aiActionTime = 0;
|
||||
|
||||
|
||||
if (self->health && player->alive == ALIVE_ALIVE && getDistance(player->x, player->y, self->x, self->y) <= 128 && isCurrentObjective() && teamMatesClose())
|
||||
{
|
||||
self->health = 0;
|
||||
|
||||
|
||||
updateObjective("Waypoint", TT_WAYPOINT);
|
||||
|
||||
|
||||
runScriptFunction(self->name);
|
||||
|
||||
|
||||
if (battle.waypointAutoAdvance)
|
||||
{
|
||||
activateNextWaypoint();
|
||||
}
|
||||
|
||||
|
||||
battle.stats[STAT_WAYPOINTS_VISITED]++;
|
||||
|
||||
|
||||
playSound(SND_WAYPOINT);
|
||||
}
|
||||
}
|
||||
|
@ -91,28 +91,28 @@ static void think(void)
|
|||
static int isCurrentObjective(void)
|
||||
{
|
||||
int numActiveObjectives = battle.numObjectivesTotal - battle.numObjectivesComplete;
|
||||
|
||||
|
||||
if (numActiveObjectives > 1)
|
||||
{
|
||||
addHudMessage(colors.cyan, _("Cannot activate waypoint - outstanding objectives not yet complete"));
|
||||
self->aiActionTime = FPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.isChallenge && game.currentMission->challengeData.clearWaypointEnemies && battle.numEnemies > 0)
|
||||
{
|
||||
addHudMessage(colors.cyan, _("Cannot activate waypoint - eliminate enemies first"));
|
||||
self->aiActionTime = FPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int teamMatesClose(void)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
|
||||
if (player->side != SIDE_PANDORAN)
|
||||
{
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
|
@ -128,7 +128,7 @@ static int teamMatesClose(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,9 @@ void activateNextWaypoint(void)
|
|||
{
|
||||
Entity *e;
|
||||
Entity *nextWaypoint = NULL;
|
||||
|
||||
|
||||
currentWaypointId++;
|
||||
|
||||
|
||||
for (e = battle.entityHead.next ; e != NULL ; e = e->next)
|
||||
{
|
||||
if (e->type == ET_WAYPOINT && e->id == currentWaypointId)
|
||||
|
@ -146,11 +146,11 @@ void activateNextWaypoint(void)
|
|||
nextWaypoint = e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nextWaypoint != NULL)
|
||||
{
|
||||
nextWaypoint->active = 1;
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Activating %s", nextWaypoint->name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ static char *RESTRICTIONS_TEXT;
|
|||
void initChallengeHome(void)
|
||||
{
|
||||
Mission *m;
|
||||
|
||||
|
||||
startSectionTransition();
|
||||
|
||||
stopMusic();
|
||||
|
@ -80,7 +80,7 @@ void initChallengeHome(void)
|
|||
awardStatsTrophies();
|
||||
|
||||
app.saveGame = 1;
|
||||
|
||||
|
||||
CHALLENGES_TEXT = _("Challenges");
|
||||
COMPLETED_TEXT = _("Completed : %d / %d");
|
||||
PAGE_TEXT = _("Page : %d / %d");
|
||||
|
@ -102,14 +102,14 @@ void initChallengeHome(void)
|
|||
|
||||
planet.x = rand() % app.winWidth;
|
||||
planet.y = rand() % app.winHeight;
|
||||
|
||||
|
||||
maxPages = page = 0;
|
||||
|
||||
|
||||
for (m = game.challengeMissionHead.next ; m != NULL ; m = m->next)
|
||||
{
|
||||
maxPages++;
|
||||
}
|
||||
|
||||
|
||||
maxPages /= CHALLENGES_PER_PAGE;
|
||||
maxPages = ceil(maxPages);
|
||||
|
||||
|
@ -128,11 +128,11 @@ void initChallengeHome(void)
|
|||
getWidget("ok", "stats")->action = ok;
|
||||
getWidget("ok", "trophies")->action = ok;
|
||||
getWidget("ok", "fighterDB")->action = ok;
|
||||
|
||||
|
||||
prev = getWidget("prev", "challenges");
|
||||
prev->action = prevPage;
|
||||
prev->visible = 0;
|
||||
|
||||
|
||||
next = getWidget("next", "challenges");
|
||||
next->action = nextPage;
|
||||
next->visible = 1;
|
||||
|
@ -143,9 +143,9 @@ void initChallengeHome(void)
|
|||
game.currentMission = game.challengeMissionHead.next;
|
||||
updateChallengeMissionData();
|
||||
}
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 0);
|
||||
|
||||
|
||||
autoSizeWidgetButtons("challenges", 1);
|
||||
|
||||
endSectionTransition();
|
||||
|
@ -156,7 +156,7 @@ void initChallengeHome(void)
|
|||
static void nextPage(void)
|
||||
{
|
||||
page = MIN(page + 1, maxPages - 1);
|
||||
|
||||
|
||||
next->visible = page < maxPages - 1;
|
||||
prev->visible = 1;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ static void nextPage(void)
|
|||
static void prevPage(void)
|
||||
{
|
||||
page = MAX(0, page - 1);
|
||||
|
||||
|
||||
next->visible = 1;
|
||||
prev->visible = page > 0;
|
||||
}
|
||||
|
@ -223,12 +223,12 @@ static void logic(void)
|
|||
}
|
||||
|
||||
doWidgets();
|
||||
|
||||
|
||||
if (show == SHOW_FIGHTER_DB)
|
||||
{
|
||||
doFighterDatabase();
|
||||
}
|
||||
|
||||
|
||||
app.doTrophyAlerts = 1;
|
||||
}
|
||||
|
||||
|
@ -236,11 +236,11 @@ static void doChallenges(void)
|
|||
{
|
||||
Mission *c;
|
||||
int i, startIndex, end;
|
||||
|
||||
|
||||
i = 0;
|
||||
startIndex = page * CHALLENGES_PER_PAGE;
|
||||
end = startIndex + CHALLENGES_PER_PAGE;
|
||||
|
||||
|
||||
for (c = game.challengeMissionHead.next ; c != NULL ; c = c->next)
|
||||
{
|
||||
if (i >= startIndex && i < end && app.mouse.button[SDL_BUTTON_LEFT] && collision(app.uiMouse.x, app.uiMouse.y, 3, 3, c->rect.x, c->rect.y, c->rect.w, c->rect.h))
|
||||
|
@ -258,7 +258,7 @@ static void doChallenges(void)
|
|||
|
||||
app.mouse.button[SDL_BUTTON_LEFT] = 0;
|
||||
}
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ static void draw(void)
|
|||
blit(planetTexture, planet.x, planet.y, 1);
|
||||
|
||||
drawStars();
|
||||
|
||||
|
||||
if (show == SHOW_MENU)
|
||||
{
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
|
@ -315,9 +315,9 @@ static void draw(void)
|
|||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 40, 28, TA_CENTER, colors.white, CHALLENGES_TEXT);
|
||||
drawText(UI_WIDTH / 2, 83, 16, TA_CENTER, colors.lightGrey, COMPLETED_TEXT, game.completedChallenges, game.totalChallenges);
|
||||
drawText(UI_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, PAGE_TEXT, page + 1, (int)maxPages);
|
||||
|
@ -337,7 +337,7 @@ static void draw(void)
|
|||
case SHOW_STATS:
|
||||
drawStats();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_TROPHIES:
|
||||
drawTrophies();
|
||||
break;
|
||||
|
@ -345,12 +345,12 @@ static void draw(void)
|
|||
case SHOW_OPTIONS:
|
||||
drawOptions();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_FIGHTER_DB:
|
||||
drawFighterDatabase();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,7 @@ static void drawChallenges(void)
|
|||
|
||||
start = page * CHALLENGES_PER_PAGE;
|
||||
end = start + CHALLENGES_PER_PAGE;
|
||||
|
||||
|
||||
i = 0;
|
||||
|
||||
for (m = game.challengeMissionHead.next ; m != NULL ; m = m->next)
|
||||
|
@ -492,7 +492,7 @@ static void stats(void)
|
|||
static void fighterDatabase(void)
|
||||
{
|
||||
show = SHOW_FIGHTER_DB;
|
||||
|
||||
|
||||
initFighterDatabaseDisplay();
|
||||
}
|
||||
|
||||
|
|
|
@ -76,13 +76,13 @@ void initChallenges(void)
|
|||
sprintf(path, "data/challenges/%s", filenames[i]);
|
||||
|
||||
mission = loadMissionMeta(path);
|
||||
|
||||
|
||||
if (mission)
|
||||
{
|
||||
tail->next = mission;
|
||||
tail = mission;
|
||||
}
|
||||
|
||||
|
||||
free(filenames[i]);
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void loadChallenge(Mission *mission, cJSON *node)
|
|||
{
|
||||
int i;
|
||||
Challenge *challenge;
|
||||
|
||||
|
||||
mission->challengeData.isChallenge = 1;
|
||||
|
||||
/* limits */
|
||||
|
@ -112,12 +112,12 @@ void loadChallenge(Mission *mission, cJSON *node)
|
|||
mission->challengeData.noECM = getJSONValue(node, "noECM", 0);
|
||||
mission->challengeData.noBoost = getJSONValue(node, "noBoost", 0);
|
||||
mission->challengeData.noGuns = getJSONValue(node, "noGuns", 0);
|
||||
|
||||
|
||||
if (getJSONValue(node, "noWeapons", 0))
|
||||
{
|
||||
mission->challengeData.noMissiles = mission->challengeData.noGuns = 1;
|
||||
}
|
||||
|
||||
|
||||
/* misc */
|
||||
mission->challengeData.allowPlayerDeath = getJSONValue(node, "allowPlayerDeath", 0);
|
||||
mission->challengeData.clearWaypointEnemies = getJSONValue(node, "clearWaypointEnemies", 0);
|
||||
|
@ -152,18 +152,18 @@ void loadChallenge(Mission *mission, cJSON *node)
|
|||
void doChallenges(void)
|
||||
{
|
||||
int passed;
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.isChallenge && battle.status == MS_IN_PROGRESS)
|
||||
{
|
||||
if (challengeFinished())
|
||||
{
|
||||
passed = 0;
|
||||
|
||||
|
||||
if (player->health > 0 || (player->health <= 0 && game.currentMission->challengeData.allowPlayerDeath))
|
||||
{
|
||||
passed = updateChallenges();
|
||||
}
|
||||
|
||||
|
||||
if (passed)
|
||||
{
|
||||
completeChallenge();
|
||||
|
@ -182,53 +182,53 @@ static int challengeFinished(void)
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* disabled enemies count as killed during challenges - not player exclusive, but no need to worry about AI contributions here */
|
||||
if (game.currentMission->challengeData.killLimit > 0 && (battle.stats[STAT_ENEMIES_KILLED_PLAYER] + battle.stats[STAT_CAPITAL_SHIPS_DESTROYED] + battle.stats[STAT_ENEMIES_DISABLED]) >= game.currentMission->challengeData.killLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.escapeLimit > 0 && (battle.stats[STAT_ENEMIES_KILLED_PLAYER] + battle.stats[STAT_ENEMIES_ESCAPED]) >= game.currentMission->challengeData.escapeLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.waypointLimit > 0 && battle.stats[STAT_WAYPOINTS_VISITED] >= game.currentMission->challengeData.waypointLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.itemLimit > 0 && battle.stats[STAT_ITEMS_COLLECTED] + battle.stats[STAT_ITEMS_COLLECTED_PLAYER] >= game.currentMission->challengeData.itemLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.playerItemLimit > 0 && battle.stats[STAT_ITEMS_COLLECTED_PLAYER] >= game.currentMission->challengeData.playerItemLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.rescueLimit > 0 && (battle.stats[STAT_CIVILIANS_RESCUED] + battle.stats[STAT_CIVILIANS_KILLED]) >= game.currentMission->challengeData.rescueLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.surrenderLimit > 0 && battle.stats[STAT_ENEMIES_SURRENDERED] >= game.currentMission->challengeData.surrenderLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.waypointLimit > 0 && (battle.stats[STAT_WAYPOINTS_VISITED]) >= game.currentMission->challengeData.waypointLimit)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (game.currentMission->challengeData.eliminateThreats && !battle.hasThreats)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return (player->health <= 0 || player->alive == ALIVE_ESCAPED || battle.scriptedEnd);
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ static int updateChallenges(void)
|
|||
Challenge *c;
|
||||
|
||||
updateAccuracyStats(battle.stats);
|
||||
|
||||
|
||||
numPassed = 0;
|
||||
|
||||
for (i = 0 ; i < MAX_CHALLENGES ; i++)
|
||||
|
@ -254,7 +254,7 @@ static int updateChallenges(void)
|
|||
case CHALLENGE_TIME:
|
||||
updateTimeChallenge(c);
|
||||
break;
|
||||
|
||||
|
||||
case CHALLENGE_SURVIVE:
|
||||
updateSurvivalChallenge(c);
|
||||
break;
|
||||
|
@ -282,26 +282,26 @@ static int updateChallenges(void)
|
|||
case CHALLENGE_DISABLE:
|
||||
updateDisabledChallenge(c);
|
||||
break;
|
||||
|
||||
|
||||
case CHALLENGE_ITEMS:
|
||||
case CHALLENGE_PLAYER_ITEMS:
|
||||
updateItemsChallenge(c);
|
||||
break;
|
||||
|
||||
|
||||
case CHALLENGE_SURRENDER:
|
||||
updateSurrenderChallenge(c);
|
||||
break;
|
||||
|
||||
|
||||
case CHALLENGE_WAYPOINTS:
|
||||
updateWaypointChallenge(c);
|
||||
break;
|
||||
|
||||
|
||||
case CHALLENGE_RESCUE:
|
||||
updateRescueChallenge(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (c->passed)
|
||||
{
|
||||
numPassed++;
|
||||
|
@ -313,7 +313,7 @@ static int updateChallenges(void)
|
|||
{
|
||||
printStats();
|
||||
}
|
||||
|
||||
|
||||
return numPassed;
|
||||
}
|
||||
|
||||
|
@ -472,7 +472,7 @@ char *getChallengeDescription(Challenge *c)
|
|||
return getFormattedChallengeDescription(_("Complete challenge in %s or less"), timeToString(c->value * FPS, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return getFormattedChallengeDescription(challengeDescription[c->type], c->value);
|
||||
}
|
||||
|
||||
|
@ -545,13 +545,13 @@ static void completeChallenge(void)
|
|||
game.stats[STAT_CHALLENGES_COMPLETED]++;
|
||||
|
||||
player->flags |= EF_IMMORTAL;
|
||||
|
||||
|
||||
retreatAllies();
|
||||
|
||||
|
||||
retreatEnemies();
|
||||
|
||||
|
||||
awardStatsTrophies();
|
||||
|
||||
|
||||
awardCraftTrophy();
|
||||
}
|
||||
}
|
||||
|
@ -565,16 +565,16 @@ static void failChallenge(void)
|
|||
selectWidget("retry", "battleLost");
|
||||
|
||||
player->flags |= EF_IMMORTAL;
|
||||
|
||||
|
||||
if (alreadyPassed())
|
||||
{
|
||||
battle.status = MS_TIME_UP;
|
||||
}
|
||||
|
||||
|
||||
retreatAllies();
|
||||
|
||||
|
||||
retreatEnemies();
|
||||
|
||||
|
||||
awardStatsTrophies();
|
||||
}
|
||||
}
|
||||
|
@ -593,6 +593,6 @@ static int alreadyPassed(void)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void initGalacticMap(void)
|
|||
app.delegate.logic = &logic;
|
||||
app.delegate.draw = &draw;
|
||||
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
||||
|
||||
|
||||
MISSIONS_TEXT = _("Missions: %d / %d");
|
||||
PILOT_TEXT = _("Pilot: %s");
|
||||
CRAFT_TEXT = _("Craft: %s");
|
||||
|
@ -113,9 +113,9 @@ void initGalacticMap(void)
|
|||
awardCampaignTrophies();
|
||||
|
||||
awardStatsTrophies();
|
||||
|
||||
|
||||
updateCampaignProgress();
|
||||
|
||||
|
||||
hoverMission = NULL;
|
||||
|
||||
app.saveGame = 1;
|
||||
|
@ -123,7 +123,7 @@ void initGalacticMap(void)
|
|||
pulseTimer = 0;
|
||||
|
||||
arrowPulse = 0;
|
||||
|
||||
|
||||
selectedStarSystem = NULL;
|
||||
|
||||
/* clear the pulses */
|
||||
|
@ -145,11 +145,11 @@ void initGalacticMap(void)
|
|||
getWidget("ok", "fighterDB")->action = ok;
|
||||
|
||||
getWidget("ok", "fallen")->action = fallenOK;
|
||||
|
||||
|
||||
autoSizeWidgetButtons("galacticMap", 1);
|
||||
|
||||
endSectionTransition();
|
||||
|
||||
|
||||
SDL_SetWindowGrab(app.window, 0);
|
||||
|
||||
playMusic("music/main/Pressure.ogg", 1);
|
||||
|
@ -158,7 +158,7 @@ void initGalacticMap(void)
|
|||
static void updateCampaignProgress(void)
|
||||
{
|
||||
StarSystem *starSystem;
|
||||
|
||||
|
||||
if (!campaignComplete && game.completedMissions == game.totalMissions)
|
||||
{
|
||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||
|
@ -168,9 +168,9 @@ static void updateCampaignProgress(void)
|
|||
starSystem->activeMission = starSystem->missionHead.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
campaignComplete = 1;
|
||||
|
||||
|
||||
showOKDialog(&campaignCompleteOK, _("Congratulations, you have completed the campaign! You may now replay past missions, for fun, to boost stats, or to earn missing trophies!"));
|
||||
}
|
||||
}
|
||||
|
@ -230,12 +230,12 @@ static void logic(void)
|
|||
arrowPulse += 0.1;
|
||||
|
||||
doWidgets();
|
||||
|
||||
|
||||
if (show == SHOW_FIGHTER_DB)
|
||||
{
|
||||
doFighterDatabase();
|
||||
}
|
||||
|
||||
|
||||
app.doTrophyAlerts = 1;
|
||||
}
|
||||
|
||||
|
@ -302,13 +302,13 @@ static void scrollGalaxy(void)
|
|||
|
||||
ssx = -app.mouse.dx;
|
||||
ssx /= 3;
|
||||
|
||||
|
||||
ssy = -app.mouse.dy;
|
||||
ssy /= 3;
|
||||
|
||||
camera.x = MAX(cameraMin.x, MIN(camera.x, cameraMax.x));
|
||||
camera.y = MAX(cameraMin.y, MIN(camera.y, cameraMax.y));
|
||||
|
||||
|
||||
if (lastX == camera.x)
|
||||
{
|
||||
ssx = 0;
|
||||
|
@ -330,7 +330,7 @@ static void doStarSystemView(void)
|
|||
if (mission->available && collision(app.uiMouse.x - app.mouse.w / 2, app.uiMouse.y - app.mouse.h / 2, app.mouse.w, app.mouse.h, mission->rect.x, mission->rect.y, mission->rect.w, mission->rect.h))
|
||||
{
|
||||
hoverMission = mission;
|
||||
|
||||
|
||||
if (app.mouse.button[SDL_BUTTON_LEFT])
|
||||
{
|
||||
if (game.currentMission != mission)
|
||||
|
@ -343,12 +343,12 @@ static void doStarSystemView(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* allow closing by pressing the right mouse button */
|
||||
if (app.mouse.button[SDL_BUTTON_RIGHT])
|
||||
{
|
||||
show = SHOW_GALAXY;
|
||||
|
||||
|
||||
playSound(SND_GUI_CLOSE);
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ static void addPulses(void)
|
|||
pulse->x = starSystem->x;
|
||||
pulse->y = starSystem->y;
|
||||
pulse->life = 255;
|
||||
|
||||
|
||||
switch (starSystem->type)
|
||||
{
|
||||
case SS_NORMAL:
|
||||
|
@ -383,18 +383,18 @@ static void addPulses(void)
|
|||
pulse->b = 255;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SS_SOL:
|
||||
pulse->g = 255;
|
||||
break;
|
||||
|
||||
|
||||
case SS_PANDORAN:
|
||||
pulse->r = 128;
|
||||
pulse->g = 128;
|
||||
pulse->b = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
pulseTail->next = pulse;
|
||||
pulseTail = pulse;
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ static void draw(void)
|
|||
case SHOW_STATS:
|
||||
drawStats();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_TROPHIES:
|
||||
drawTrophies();
|
||||
break;
|
||||
|
@ -461,7 +461,7 @@ static void draw(void)
|
|||
case SHOW_OPTIONS:
|
||||
drawOptions();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_FIGHTER_DB:
|
||||
drawFighterDatabase();
|
||||
break;
|
||||
|
@ -555,18 +555,18 @@ static void drawGalaxy(void)
|
|||
case SS_NORMAL:
|
||||
setAtlasColor(255, 0, 0, 255);
|
||||
break;
|
||||
|
||||
|
||||
case SS_SOL:
|
||||
setAtlasColor(0, 255, 0, 255);
|
||||
break;
|
||||
|
||||
|
||||
case SS_PANDORAN:
|
||||
setAtlasColor(64, 128, 255, 255);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
blitRotated(arrowTexture, ax, ay, aa);
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ static void selectStarSystem(void)
|
|||
static Mission *nextAvailableMission(StarSystem *starSystem)
|
||||
{
|
||||
Mission *m;
|
||||
|
||||
|
||||
for (m = starSystem->missionHead.next ; m != NULL ; m = m->next)
|
||||
{
|
||||
if (m->available && !m->completed)
|
||||
|
@ -626,7 +626,7 @@ static Mission *nextAvailableMission(StarSystem *starSystem)
|
|||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return starSystem->missionHead.next;
|
||||
}
|
||||
|
||||
|
@ -635,7 +635,7 @@ static void drawStarSystemDetail(void)
|
|||
int y;
|
||||
Mission *mission;
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 900;
|
||||
|
@ -668,7 +668,7 @@ static void drawStarSystemDetail(void)
|
|||
mission->rect.y = y - 2;
|
||||
mission->rect.w = 300;
|
||||
mission->rect.h = 38;
|
||||
|
||||
|
||||
if (mission == hoverMission)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 16, 32, 64, 255);
|
||||
|
@ -690,7 +690,7 @@ static void drawStarSystemDetail(void)
|
|||
if (mission->available)
|
||||
{
|
||||
drawText(210, y, 22, TA_LEFT, mission->completed ? colors.lightGrey : colors.yellow, mission->name);
|
||||
|
||||
|
||||
y += 42;
|
||||
}
|
||||
}
|
||||
|
@ -702,9 +702,9 @@ static void drawStarSystemDetail(void)
|
|||
drawText(525, 185, 18, TA_LEFT, colors.lightGrey, SQUADRON_TEXT, game.currentMission->squadron);
|
||||
|
||||
app.textWidth = 525;
|
||||
|
||||
|
||||
drawText(525, 230, 22, TA_LEFT, colors.white, game.currentMission->description);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
}
|
||||
|
||||
|
@ -724,7 +724,7 @@ static void drawStarSystemDetail(void)
|
|||
startMissionButton->enabled = (!game.currentMission->completed || selectedStarSystem->type == SS_SOL || campaignComplete);
|
||||
|
||||
drawWidgets("starSystem");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ static void campaignCompleteOK(void)
|
|||
show = SHOW_GALAXY;
|
||||
|
||||
app.modalDialog.type = MD_NONE;
|
||||
|
||||
|
||||
campaignComplete = 2;
|
||||
}
|
||||
|
||||
|
@ -791,7 +791,7 @@ static void handleMouse(void)
|
|||
{
|
||||
scrollingMap = 0;
|
||||
}
|
||||
|
||||
|
||||
setMouseCursor(app.mouse.button[SDL_BUTTON_LEFT] && show == SHOW_GALAXY);
|
||||
}
|
||||
|
||||
|
@ -805,12 +805,12 @@ static void startMission(void)
|
|||
static void drawMenu(void)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 400;
|
||||
|
@ -824,7 +824,7 @@ static void drawMenu(void)
|
|||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
drawWidgets("galacticMap");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -843,7 +843,7 @@ static void options(void)
|
|||
static void fighterDatabase(void)
|
||||
{
|
||||
show = SHOW_FIGHTER_DB;
|
||||
|
||||
|
||||
initFighterDatabaseDisplay();
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ Mission *loadMissionMeta(char *filename)
|
|||
STRNCPY(mission->filename, filename, MAX_DESCRIPTION_LENGTH);
|
||||
|
||||
mission->requires = getJSONValue(root, "requires", 0);
|
||||
|
||||
|
||||
mission->isOptional = getJSONValue(root, "isOptional", 0);
|
||||
mission->requiresOptional = getJSONValue(root, "requiresOptional", 0);
|
||||
mission->expires = getJSONValue(root, "expires", 0);
|
||||
|
||||
|
||||
if (cJSON_GetObjectItem(root, "epic"))
|
||||
{
|
||||
mission->epic = 1;
|
||||
|
@ -154,27 +154,27 @@ void loadMission(char *filename)
|
|||
{
|
||||
planet = getAutoPlanet(filename);
|
||||
}
|
||||
|
||||
|
||||
battle.planetTexture = getAtlasImage(planet);
|
||||
battle.fireStormTexture = getAtlasImage("gfx/misc/torelliFireStorm.png");
|
||||
battle.planet.x = (app.winWidth / 2) - (rand() % app.winWidth) + (rand() % app.winWidth);
|
||||
battle.planet.y = (app.winHeight / 2) - (rand() % app.winHeight) + (rand() % app.winHeight);
|
||||
|
||||
|
||||
if (strcmp(planet, "gfx/planets/star.png") != 0)
|
||||
{
|
||||
battle.planetWidth = battle.planetTexture->rect.w;
|
||||
battle.planetHeight = battle.planetTexture->rect.h;
|
||||
|
||||
|
||||
planetScale = 75 + (rand() % 125);
|
||||
planetScale *= 0.01;
|
||||
|
||||
|
||||
if (getJSONValue(root, "largePlanet", 0))
|
||||
{
|
||||
battle.planet.x = (app.winWidth / 2);
|
||||
battle.planet.y = (app.winHeight / 2);
|
||||
planetScale = 5;
|
||||
}
|
||||
|
||||
|
||||
battle.planetWidth *= planetScale;
|
||||
battle.planetHeight *= planetScale;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ void loadMission(char *filename)
|
|||
{
|
||||
battle.status = MS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
|
||||
if (battle.waypointAutoAdvance)
|
||||
{
|
||||
activateNextWaypoint();
|
||||
|
@ -209,7 +209,7 @@ void loadMission(char *filename)
|
|||
initPlayer();
|
||||
|
||||
initMissionInfo();
|
||||
|
||||
|
||||
setInitialPlayerAngle();
|
||||
|
||||
addAllToQuadtree();
|
||||
|
@ -274,10 +274,10 @@ void completeMission(void)
|
|||
selectWidget("continue", "battleWon");
|
||||
|
||||
game.stats[STAT_MISSIONS_COMPLETED]++;
|
||||
|
||||
|
||||
if (game.currentMission->isOptional)
|
||||
{
|
||||
game.stats[STAT_OPTIONAL_COMPLETED]++;
|
||||
game.stats[STAT_OPTIONAL_COMPLETED]++;
|
||||
}
|
||||
|
||||
completeConditions();
|
||||
|
@ -285,11 +285,11 @@ void completeMission(void)
|
|||
retreatEnemies();
|
||||
|
||||
player->flags |= EF_IMMORTAL;
|
||||
|
||||
|
||||
awardStatsTrophies();
|
||||
|
||||
|
||||
awardPostMissionTrophies();
|
||||
|
||||
|
||||
awardCraftTrophy();
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ void failMission(void)
|
|||
failIncompleteObjectives();
|
||||
|
||||
player->flags |= EF_IMMORTAL;
|
||||
|
||||
|
||||
awardStatsTrophies();
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ static void loadEntities(cJSON *node)
|
|||
active = getJSONValue(node, "active", 1);
|
||||
scatter = getJSONValue(node, "scatter", 1);
|
||||
side = lookup(getJSONValueStr(node, "side", "SIDE_NONE"));
|
||||
|
||||
|
||||
if (cJSON_GetObjectItem(node, "flags"))
|
||||
{
|
||||
flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags);
|
||||
|
@ -356,7 +356,7 @@ static void loadEntities(cJSON *node)
|
|||
case ET_JUMPGATE:
|
||||
e = spawnJumpgate(side, flags);
|
||||
break;
|
||||
|
||||
|
||||
case ET_MINE:
|
||||
case ET_SHADOW_MINE:
|
||||
e = spawnMine(type);
|
||||
|
@ -394,7 +394,7 @@ static void loadEntities(cJSON *node)
|
|||
|
||||
e->x = x;
|
||||
e->y = y;
|
||||
|
||||
|
||||
e->side = side;
|
||||
|
||||
if (scatter > 1)
|
||||
|
@ -423,12 +423,12 @@ static void loadEpicData(cJSON *node)
|
|||
battle.unlimitedEnemies = getJSONValue(node, "unlimitedEnemies", 0);
|
||||
battle.epicLives = getJSONValue(node, "lives", 0);
|
||||
battle.epicKills = getJSONValue(node, "kills", 0);
|
||||
|
||||
|
||||
if (battle.epicLives > 0)
|
||||
{
|
||||
addEpicLivesObjective();
|
||||
}
|
||||
|
||||
|
||||
if (battle.epicKills != 0)
|
||||
{
|
||||
addEpicKillsObjective();
|
||||
|
@ -490,7 +490,7 @@ int isMissionAvailable(Mission *mission, Mission *prev)
|
|||
else
|
||||
{
|
||||
return mission->completed || (
|
||||
game.completedMissions >= mission->requires &&
|
||||
game.completedMissions >= mission->requires &&
|
||||
game.stats[STAT_OPTIONAL_COMPLETED] >= mission->requiresOptional &&
|
||||
game.completedMissions < mission->expires
|
||||
) || dev.debug;
|
||||
|
|
|
@ -57,7 +57,7 @@ static StarSystem *loadStarSystem(cJSON *starSystemJSON)
|
|||
starSystem->x = cJSON_GetObjectItem(starSystemJSON, "x")->valueint;
|
||||
starSystem->y = cJSON_GetObjectItem(starSystemJSON, "y")->valueint;
|
||||
starSystem->fallsToPandorans = getJSONValue(starSystemJSON, "fallsToPandorans", 0);
|
||||
|
||||
|
||||
starSystem->type = (starSystem->side != SIDE_PANDORAN) ? SS_NORMAL : SS_PANDORAN;
|
||||
|
||||
if (strcmp(starSystem->name, "Sol") == 0)
|
||||
|
@ -91,26 +91,26 @@ static void loadMissions(StarSystem *starSystem)
|
|||
{
|
||||
name[i] = tolower(name[i]);
|
||||
}
|
||||
|
||||
|
||||
sprintf(path, "data/missions/%s", name);
|
||||
|
||||
|
||||
filenames = getFileList(path, &count);
|
||||
|
||||
|
||||
for (i = 0 ; i < count ; i++)
|
||||
{
|
||||
sprintf(path, "data/missions/%s/%s", name, filenames[i]);
|
||||
|
||||
|
||||
mission = loadMissionMeta(path);
|
||||
|
||||
|
||||
if (mission)
|
||||
{
|
||||
tail->next = mission;
|
||||
tail = mission;
|
||||
}
|
||||
|
||||
|
||||
free(filenames[i]);
|
||||
}
|
||||
|
||||
|
||||
free(filenames);
|
||||
}
|
||||
|
||||
|
@ -143,16 +143,16 @@ void updateStarSystemMissions(void)
|
|||
for (mission = starSystem->missionHead.next ; mission != NULL ; mission = mission->next)
|
||||
{
|
||||
starSystem->totalMissions++;
|
||||
|
||||
|
||||
if (starSystem->type == SS_NORMAL && !mission->isOptional)
|
||||
{
|
||||
game.totalMissions++;
|
||||
}
|
||||
|
||||
|
||||
if (mission->completed)
|
||||
{
|
||||
starSystem->completedMissions++;
|
||||
|
||||
|
||||
if (starSystem->type == SS_NORMAL && !mission->isOptional)
|
||||
{
|
||||
game.completedMissions++;
|
||||
|
@ -172,12 +172,12 @@ void updateStarSystemMissions(void)
|
|||
if (mission->available)
|
||||
{
|
||||
starSystem->availableMissions++;
|
||||
|
||||
|
||||
if (starSystem->type == SS_NORMAL && !mission->isOptional)
|
||||
{
|
||||
game.availableMissions++;
|
||||
}
|
||||
|
||||
|
||||
if (!mission->completed)
|
||||
{
|
||||
starSystem->activeMission = mission;
|
||||
|
|
|
@ -36,51 +36,51 @@ static int timeout;
|
|||
void initCredits(void)
|
||||
{
|
||||
startSectionTransition();
|
||||
|
||||
|
||||
stopMusic();
|
||||
|
||||
|
||||
memset(&head, 0, sizeof(Credit));
|
||||
tail = &head;
|
||||
|
||||
|
||||
app.delegate.logic = &logic;
|
||||
app.delegate.draw = &draw;
|
||||
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
||||
|
||||
|
||||
background = getTexture("gfx/backgrounds/background02.jpg");
|
||||
|
||||
|
||||
earthTexture = getAtlasImage("gfx/planets/earth.png");
|
||||
|
||||
|
||||
loadCredits();
|
||||
|
||||
|
||||
app.hideMouse = 1;
|
||||
|
||||
|
||||
endSectionTransition();
|
||||
|
||||
|
||||
playMusic("music/main/Her Violet Eyes.mp3", 0);
|
||||
}
|
||||
|
||||
static void logic(void)
|
||||
{
|
||||
Credit *c;
|
||||
|
||||
|
||||
handleKeyboard();
|
||||
|
||||
|
||||
for (c = head.next ; c != NULL ; c = c->next)
|
||||
{
|
||||
c->y -= creditSpeed;
|
||||
|
||||
|
||||
if (!c->next)
|
||||
{
|
||||
c->y = MAX(c->y, (app.winHeight - c->h) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (--timeout <= 0)
|
||||
{
|
||||
app.hideMouse = 0;
|
||||
|
||||
|
||||
destroyCredits();
|
||||
|
||||
|
||||
initTitle();
|
||||
}
|
||||
}
|
||||
|
@ -88,13 +88,13 @@ static void logic(void)
|
|||
static void draw(void)
|
||||
{
|
||||
Credit *c;
|
||||
|
||||
|
||||
drawBackground(background);
|
||||
|
||||
|
||||
blit(earthTexture, app.winWidth - 200, (app.winHeight / 2) + 100, 1);
|
||||
|
||||
|
||||
app.textWidth = CREDIT_LINE_LIMIT;
|
||||
|
||||
|
||||
for (c = head.next ; c != NULL ; c = c->next)
|
||||
{
|
||||
if (c->y > -c->h && c->y < app.winHeight)
|
||||
|
@ -102,7 +102,7 @@ static void draw(void)
|
|||
drawText(app.winWidth / 2, (int)c->y, c->size, TA_CENTER, colors.white, c->text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
}
|
||||
|
||||
|
@ -112,12 +112,12 @@ static void loadCredits(void)
|
|||
int y, dist;
|
||||
char *text;
|
||||
Credit *c;
|
||||
|
||||
|
||||
y = app.winHeight + 100;
|
||||
|
||||
text = readFile("data/credits/credits.json");
|
||||
root = cJSON_Parse(text);
|
||||
|
||||
|
||||
app.textWidth = CREDIT_LINE_LIMIT;
|
||||
|
||||
for (node = root->child ; node != NULL ; node = node->next)
|
||||
|
@ -126,28 +126,28 @@ static void loadCredits(void)
|
|||
memset(c, 0, sizeof(Credit));
|
||||
tail->next = c;
|
||||
tail = c;
|
||||
|
||||
|
||||
c->y = y;
|
||||
|
||||
|
||||
c->text = malloc(sizeof(char) * strlen(node->valuestring));
|
||||
memset(c->text, '\0', sizeof(char) * strlen(node->valuestring));
|
||||
|
||||
|
||||
sscanf(node->valuestring, "%d %d %[^\n]", &dist, &c->size, c->text);
|
||||
|
||||
|
||||
c->y += dist;
|
||||
c->h = getWrappedTextHeight(c->text, c->size);
|
||||
|
||||
|
||||
y += c->h + dist;
|
||||
}
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
/* the music that plays over the credits is 2m 44s, so scroll credits roughly inline with that (plus 2 seconds) */
|
||||
timeout = ((2 * 60) + 46) * FPS;
|
||||
|
||||
|
||||
creditSpeed = y;
|
||||
creditSpeed /= timeout;
|
||||
|
||||
|
||||
cJSON_Delete(root);
|
||||
free(text);
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ static void handleKeyboard(void)
|
|||
void destroyCredits(void)
|
||||
{
|
||||
Credit *c;
|
||||
|
||||
|
||||
while (head.next)
|
||||
{
|
||||
c = head.next;
|
||||
|
|
|
@ -48,7 +48,7 @@ void initFighterDatabase(void)
|
|||
{
|
||||
DB_TEXT = _("Fighter Database");
|
||||
PAGE_TEXT = _("Page %d / %d");
|
||||
|
||||
|
||||
COMMON_TEXT = _("(Common)");
|
||||
DESTROYED_TEXT = _("Destroyed");
|
||||
AFFILIATION_TEXT = _("Affiliation");
|
||||
|
@ -57,9 +57,9 @@ void initFighterDatabase(void)
|
|||
SPEED_TEXT = _("Speed");
|
||||
MISSILES_TEXT = _("Missiles");
|
||||
MISSILE_NUM_TEXT = _("Missiles x %d");
|
||||
|
||||
|
||||
dbFighters = getDBFighters(&maxPages);
|
||||
|
||||
|
||||
gunName[BT_NONE] = "";
|
||||
gunName[BT_PARTICLE] = _("Particle Cannon");
|
||||
gunName[BT_PLASMA] = _("Plasma Cannon");
|
||||
|
@ -67,7 +67,7 @@ void initFighterDatabase(void)
|
|||
gunName[BT_MAG] = _("Mag Cannon");
|
||||
gunName[BT_ROCKET] = _("Rockets");
|
||||
gunName[BT_MISSILE] = _("Missiles");
|
||||
|
||||
|
||||
rotation = 0;
|
||||
}
|
||||
|
||||
|
@ -79,13 +79,13 @@ void destroyFighterDatabase(void)
|
|||
void initFighterDatabaseDisplay(void)
|
||||
{
|
||||
page = 0;
|
||||
|
||||
|
||||
prev = getWidget("prev", "fighterDB");
|
||||
prev->action = prevFighter;
|
||||
|
||||
|
||||
next = getWidget("next", "fighterDB");
|
||||
next->action = nextFighter;
|
||||
|
||||
|
||||
setNumDestroyed();
|
||||
}
|
||||
|
||||
|
@ -99,83 +99,83 @@ void drawFighterDatabase(void)
|
|||
SDL_Rect r;
|
||||
Entity *fighter;
|
||||
int i, y, numCannons;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
|
||||
r.w = 700;
|
||||
r.h = 650;
|
||||
r.x = (UI_WIDTH / 2) - r.w / 2;
|
||||
r.y = (UI_HEIGHT / 2) - r.h / 2;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 50, 28, TA_CENTER, colors.white, DB_TEXT);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 90, 16, TA_CENTER, colors.lightGrey, PAGE_TEXT, page + 1, (int)maxPages);
|
||||
|
||||
|
||||
fighter = dbFighters[page];
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 130, 28, TA_CENTER, colors.white, fighter->name);
|
||||
|
||||
|
||||
blitRotated(fighter->texture, r.x + (r.w / 2), 250, rotation);
|
||||
|
||||
|
||||
if (fighter->flags & EF_COMMON_FIGHTER)
|
||||
{
|
||||
drawText(UI_WIDTH / 2, 170, 18, TA_CENTER, colors.darkGrey, COMMON_TEXT);
|
||||
|
||||
|
||||
drawText(r.x + (r.w / 2), 290, 18, TA_CENTER, colors.lightGrey, "%s: %d", DESTROYED_TEXT, numDestroyed);
|
||||
}
|
||||
|
||||
|
||||
drawText(r.x + 25, 200, 22, TA_LEFT, colors.white, "%s: %s", AFFILIATION_TEXT, fighter->affiliation);
|
||||
drawText(r.x + 25, 240, 22, TA_LEFT, colors.white, "%s: %d", ARMOUR_TEXT, fighter->health);
|
||||
drawText(r.x + 25, 280, 22, TA_LEFT, colors.white, "%s: %d", SHIELD_TEXT, fighter->shield);
|
||||
drawText(r.x + 25, 320, 22, TA_LEFT, colors.white, "%s: %.0f", SPEED_TEXT, ((fighter->speed * fighter->speed) * FPS));
|
||||
|
||||
|
||||
y = 200;
|
||||
|
||||
|
||||
for (i = 1 ; i < BT_MAX ; i++)
|
||||
{
|
||||
numCannons = countFighterGuns(fighter, i);
|
||||
if (numCannons > 0)
|
||||
{
|
||||
drawText(r.x + r.w - 25, y, 22, TA_RIGHT, colors.white, "%s x %d", gunName[i], numCannons);
|
||||
|
||||
|
||||
y += 40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fighter->missiles > 0)
|
||||
{
|
||||
drawText(r.x + r.w - 25, y, 22, TA_RIGHT, colors.white, MISSILE_NUM_TEXT, fighter->missiles);
|
||||
}
|
||||
|
||||
|
||||
y = MAX(y, 320) + 75;
|
||||
|
||||
|
||||
app.textWidth = r.w - 50;
|
||||
|
||||
|
||||
drawText(r.x + 25, y, 18, TA_LEFT, colors.white, fighter->description);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
drawWidgets("fighterDB");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
static int countFighterGuns(Entity *fighter, int type)
|
||||
{
|
||||
int i, num;
|
||||
|
||||
|
||||
num = 0;
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_FIGHTER_GUNS ; i++)
|
||||
{
|
||||
if (fighter->guns[i].type == type)
|
||||
|
@ -183,21 +183,21 @@ static int countFighterGuns(Entity *fighter, int type)
|
|||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static void prevFighter(void)
|
||||
{
|
||||
page = mod(page - 1, maxPages);
|
||||
|
||||
|
||||
setNumDestroyed();
|
||||
}
|
||||
|
||||
static void nextFighter(void)
|
||||
{
|
||||
page = mod(page + 1, maxPages);
|
||||
|
||||
|
||||
setNumDestroyed();
|
||||
}
|
||||
|
||||
|
@ -205,11 +205,11 @@ static void setNumDestroyed(void)
|
|||
{
|
||||
Tuple *t;
|
||||
Entity *fighter;
|
||||
|
||||
|
||||
fighter = dbFighters[page];
|
||||
|
||||
|
||||
numDestroyed = 0;
|
||||
|
||||
|
||||
for (t = game.fighterStatHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
if (strcmp(t->key, fighter->name) == 0)
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
void initGame(void)
|
||||
{
|
||||
memset(&game, 0, sizeof(Game));
|
||||
|
||||
|
||||
STRNCPY(game.selectedStarSystem, "Sol", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@ void loadGame(void)
|
|||
loadChallenges(cJSON_GetObjectItem(gameJSON, "challenges"));
|
||||
|
||||
loadStats(cJSON_GetObjectItem(gameJSON, "stats"));
|
||||
|
||||
|
||||
loadTrophies(cJSON_GetObjectItem(gameJSON, "trophies"));
|
||||
|
||||
|
||||
loadFighterStats(cJSON_GetObjectItem(gameJSON, "fighterStats"));
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
@ -76,7 +76,7 @@ static void loadMissions(cJSON *missionsJSON)
|
|||
for (missionJSON = missionsJSON->child ; missionJSON != NULL ; missionJSON = missionJSON->next)
|
||||
{
|
||||
mission = getMission(cJSON_GetObjectItem(missionJSON, "filename")->valuestring);
|
||||
|
||||
|
||||
if (mission)
|
||||
{
|
||||
mission->completed = cJSON_GetObjectItem(missionJSON, "completed")->valueint;
|
||||
|
@ -133,13 +133,13 @@ static void loadTrophies(cJSON *trophiesJSON)
|
|||
{
|
||||
Trophy *t;
|
||||
cJSON *trophyJSON;
|
||||
|
||||
|
||||
if (trophiesJSON)
|
||||
{
|
||||
for (trophyJSON = trophiesJSON->child ; trophyJSON != NULL ; trophyJSON = trophyJSON->next)
|
||||
{
|
||||
t = getTrophy(cJSON_GetObjectItem(trophyJSON, "id")->valuestring);
|
||||
|
||||
|
||||
if (t)
|
||||
{
|
||||
t->awardDate = cJSON_GetObjectItem(trophyJSON, "awardDate")->valueint;
|
||||
|
@ -153,21 +153,21 @@ static void loadFighterStats(cJSON *fighterStatsJSON)
|
|||
{
|
||||
Tuple *t, *tail;
|
||||
cJSON *fighterStatJSON;
|
||||
|
||||
|
||||
destroyFighterStats();
|
||||
|
||||
|
||||
tail = &game.fighterStatHead;
|
||||
|
||||
|
||||
if (fighterStatsJSON)
|
||||
{
|
||||
for (fighterStatJSON = fighterStatsJSON->child ; fighterStatJSON != NULL ; fighterStatJSON = fighterStatJSON->next)
|
||||
{
|
||||
t = malloc(sizeof(Tuple));
|
||||
memset(t, 0, sizeof(Tuple));
|
||||
|
||||
|
||||
STRNCPY(t->key, cJSON_GetObjectItem(fighterStatJSON, "key")->valuestring, MAX_NAME_LENGTH);
|
||||
t->value = cJSON_GetObjectItem(fighterStatJSON, "value")->valueint;
|
||||
|
||||
|
||||
tail->next = t;
|
||||
tail = t;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void initOptions(void (*rtn)(void))
|
|||
setWidgetOption("musicVolume", "options", optionStr);
|
||||
|
||||
setWidgetOption("fullscreen", "options", app.fullscreen ? "On" : "Off");
|
||||
|
||||
|
||||
OPTIONS_TEXT = _("Options");
|
||||
RESOLUTION_TEXT = _("Note: you must restart the game for window size and fullscreen options to take effect.");
|
||||
|
||||
|
@ -69,7 +69,7 @@ void initOptions(void (*rtn)(void))
|
|||
#endif
|
||||
|
||||
returnFromOptions = rtn;
|
||||
|
||||
|
||||
show = SHOW_MAIN;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ void drawOptions(void)
|
|||
case SHOW_MAIN:
|
||||
drawMain();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_CONTROLS:
|
||||
drawControls();
|
||||
break;
|
||||
|
@ -90,12 +90,12 @@ void drawOptions(void)
|
|||
static void drawMain(void)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 500;
|
||||
|
@ -116,11 +116,11 @@ static void drawMain(void)
|
|||
drawWidgets("options");
|
||||
|
||||
app.textWidth = r.w - 100;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, r.y + r.h - 135, 16, TA_CENTER, colors.yellow, RESOLUTION_TEXT);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -129,11 +129,11 @@ void updateCustomResolutionOption(void)
|
|||
Widget *w;
|
||||
char value[MAX_NAME_LENGTH];
|
||||
int i;
|
||||
|
||||
|
||||
sprintf(value, "%d x %d", app.winWidth, app.winHeight);
|
||||
|
||||
|
||||
w = getWidget("windowSize", "options");
|
||||
|
||||
|
||||
for (i = 0 ; i < w->numOptions - 1 ; i++)
|
||||
{
|
||||
if (strcmp(w->options[i], value) == 0)
|
||||
|
@ -142,7 +142,7 @@ void updateCustomResolutionOption(void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
w->options[w->numOptions - 1] = malloc(strlen(value) + 1);
|
||||
strcpy(w->options[w->numOptions - 1], value);
|
||||
}
|
||||
|
@ -150,25 +150,25 @@ void updateCustomResolutionOption(void)
|
|||
static void controls(void)
|
||||
{
|
||||
initControlsDisplay();
|
||||
|
||||
|
||||
show = SHOW_CONTROLS;
|
||||
}
|
||||
|
||||
static void changeWindowSize(char *value)
|
||||
{
|
||||
sscanf(value, "%d x %d", &app.winWidth, &app.winHeight);
|
||||
|
||||
|
||||
SDL_SetWindowSize(app.window, app.winWidth, app.winHeight);
|
||||
|
||||
|
||||
app.uiOffset.x = (app.winWidth / 2) - (UI_WIDTH / 2);
|
||||
app.uiOffset.y = (app.winHeight / 2) - (UI_HEIGHT / 2);
|
||||
|
||||
|
||||
SDL_DestroyTexture(app.backBuffer);
|
||||
|
||||
|
||||
app.backBuffer = SDL_CreateTexture(app.renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, app.winWidth, app.winHeight);
|
||||
|
||||
|
||||
initGraphics();
|
||||
|
||||
|
||||
initStars();
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ static void changeMusicVolume(char *value)
|
|||
static void changeFullscreen(char *value)
|
||||
{
|
||||
app.fullscreen = strcmp(value, "On") == 0;
|
||||
|
||||
|
||||
SDL_SetWindowFullscreen(app.window, app.fullscreen? SDL_WINDOW_FULLSCREEN : 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ void saveGame(void)
|
|||
saveChallenges(gameJSON);
|
||||
|
||||
saveStats(gameJSON);
|
||||
|
||||
|
||||
saveTrophies(gameJSON);
|
||||
|
||||
|
||||
saveFighterStats(gameJSON);
|
||||
|
||||
out = cJSON_Print(root);
|
||||
|
@ -118,18 +118,18 @@ static void saveChallenges(cJSON *gameJSON)
|
|||
cJSON_AddStringToObject(missionJSON, "filename", mission->filename);
|
||||
|
||||
challengesJSON = cJSON_CreateArray();
|
||||
|
||||
|
||||
for (i = 0 ; i < MAX_CHALLENGES ; i++)
|
||||
{
|
||||
c = mission->challengeData.challenges[i];
|
||||
|
||||
|
||||
if (c)
|
||||
{
|
||||
challengeJSON = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(challengeJSON, "type", getLookupName("CHALLENGE_", c->type));
|
||||
cJSON_AddNumberToObject(challengeJSON, "value", c->value);
|
||||
cJSON_AddNumberToObject(challengeJSON, "passed", c->passed);
|
||||
|
||||
|
||||
cJSON_AddItemToArray(challengesJSON, challengeJSON);
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ static void saveTrophies(cJSON *gameJSON)
|
|||
{
|
||||
Trophy *t;
|
||||
cJSON *trophiesJSON, *trophyJSON;
|
||||
|
||||
|
||||
trophiesJSON = cJSON_CreateArray();
|
||||
|
||||
for (t = game.trophyHead.next ; t != NULL ; t = t->next)
|
||||
|
@ -168,14 +168,14 @@ static void saveTrophies(cJSON *gameJSON)
|
|||
if (t->awarded)
|
||||
{
|
||||
trophyJSON = cJSON_CreateObject();
|
||||
|
||||
|
||||
cJSON_AddStringToObject(trophyJSON, "id", t->id);
|
||||
cJSON_AddNumberToObject(trophyJSON, "awardDate", t->awardDate);
|
||||
|
||||
|
||||
cJSON_AddItemToArray(trophiesJSON, trophyJSON);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cJSON_AddItemToObject(gameJSON, "trophies", trophiesJSON);
|
||||
}
|
||||
|
||||
|
@ -183,18 +183,18 @@ static void saveFighterStats(cJSON *gameJSON)
|
|||
{
|
||||
Tuple *t;
|
||||
cJSON *fighterStatsJSON, *fighterStatJSON;
|
||||
|
||||
|
||||
fighterStatsJSON = cJSON_CreateArray();
|
||||
|
||||
for (t = game.fighterStatHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
fighterStatJSON = cJSON_CreateObject();
|
||||
|
||||
|
||||
cJSON_AddStringToObject(fighterStatJSON, "key", t->key);
|
||||
cJSON_AddNumberToObject(fighterStatJSON, "value", t->value);
|
||||
|
||||
|
||||
cJSON_AddItemToArray(fighterStatsJSON, fighterStatJSON);
|
||||
}
|
||||
|
||||
|
||||
cJSON_AddItemToObject(gameJSON, "fighterStats", fighterStatsJSON);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ void initStats(void)
|
|||
statDescription[STAT_MINES_DESTROYED] = _("Mines Destroyed");
|
||||
statDescription[STAT_ENEMIES_SURRENDERED] = _("Enemies Surrendered");
|
||||
statDescription[STAT_TIME] = _("Time Played");
|
||||
|
||||
|
||||
STATS_TEXT = _("Stats");
|
||||
PAGE_TEXT = _("Page %d / %d");
|
||||
}
|
||||
|
@ -82,21 +82,21 @@ void initStats(void)
|
|||
void initStatsDisplay(void)
|
||||
{
|
||||
page = 0;
|
||||
|
||||
|
||||
maxPages = STAT_TIME;
|
||||
maxPages /= STATS_PER_PAGE;
|
||||
maxPages = ceil(maxPages);
|
||||
|
||||
|
||||
prev = getWidget("prev", "stats");
|
||||
prev->action = prevPage;
|
||||
prev->visible = 0;
|
||||
|
||||
|
||||
next = getWidget("next", "stats");
|
||||
next->action = nextPage;
|
||||
next->visible = 1;
|
||||
|
||||
|
||||
calculatePercentComplete();
|
||||
|
||||
|
||||
updateAccuracyStats(game.stats);
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,9 @@ static void calculatePercentComplete(void)
|
|||
StarSystem *starSystem;
|
||||
Mission *mission;
|
||||
int completed, total;
|
||||
|
||||
|
||||
completed = total = 0;
|
||||
|
||||
|
||||
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
|
||||
{
|
||||
if (starSystem->type == SS_NORMAL)
|
||||
|
@ -116,13 +116,13 @@ static void calculatePercentComplete(void)
|
|||
total += starSystem->totalMissions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (mission = game.challengeMissionHead.next ; mission != NULL ; mission = mission->next)
|
||||
{
|
||||
completed += mission->completedChallenges;
|
||||
total += mission->totalChallenges;
|
||||
}
|
||||
|
||||
|
||||
game.stats[STAT_PERCENT_COMPLETE] = getPercent(completed, total);
|
||||
}
|
||||
|
||||
|
@ -130,41 +130,41 @@ void drawStats(void)
|
|||
{
|
||||
int i, y, startIndex;
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
|
||||
r.w = 500;
|
||||
r.h = 600;
|
||||
r.x = (UI_WIDTH / 2) - r.w / 2;
|
||||
r.y = (UI_HEIGHT / 2) - r.h / 2;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 70, 28, TA_CENTER, colors.white, STATS_TEXT);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, PAGE_TEXT, page + 1, (int)maxPages);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255);
|
||||
SDL_RenderDrawLine(app.renderer, r.x, 150, r.x + r.w, 150);
|
||||
|
||||
|
||||
y = 170;
|
||||
|
||||
|
||||
startIndex = (page * STATS_PER_PAGE);
|
||||
|
||||
|
||||
for (i = startIndex ; i < startIndex + STATS_PER_PAGE ; i++)
|
||||
{
|
||||
if (i < STAT_TIME)
|
||||
{
|
||||
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, statDescription[i]);
|
||||
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case STAT_PERCENT_COMPLETE:
|
||||
|
@ -173,28 +173,28 @@ void drawStats(void)
|
|||
case STAT_MISSILE_ACCURACY:
|
||||
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d%%", game.stats[i]);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
y += 40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawText(r.x + 20, 565, 18, TA_LEFT, colors.white, statDescription[STAT_TIME]);
|
||||
drawText(r.x + r.w - 20, 565, 18, TA_RIGHT, colors.white, timeToString(game.stats[STAT_TIME], 1));
|
||||
|
||||
|
||||
drawWidgets("stats");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
static void nextPage(void)
|
||||
{
|
||||
page = MIN(page + 1, maxPages - 1);
|
||||
|
||||
|
||||
next->visible = page < maxPages - 1;
|
||||
prev->visible = 1;
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ static void nextPage(void)
|
|||
static void prevPage(void)
|
||||
{
|
||||
page = MAX(0, page - 1);
|
||||
|
||||
|
||||
next->visible = 1;
|
||||
prev->visible = page > 0;
|
||||
}
|
||||
|
|
126
src/game/title.c
126
src/game/title.c
|
@ -49,35 +49,35 @@ static int show;
|
|||
void initTitle(void)
|
||||
{
|
||||
startSectionTransition();
|
||||
|
||||
|
||||
stopMusic();
|
||||
|
||||
|
||||
app.delegate.logic = &logic;
|
||||
app.delegate.draw = &draw;
|
||||
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
||||
|
||||
|
||||
battle.camera.x = battle.camera.y = 0;
|
||||
|
||||
|
||||
destroyBattle();
|
||||
|
||||
|
||||
logo[0] = getAtlasImage("gfx/title/logo01.png");
|
||||
logo[1] = getAtlasImage("gfx/title/logo02.png");
|
||||
|
||||
|
||||
pandoranWar = getAtlasImage("gfx/title/pandoran.png");
|
||||
|
||||
|
||||
background = getTexture("gfx/backgrounds/background02.jpg");
|
||||
|
||||
|
||||
earthTexture = getAtlasImage("gfx/planets/earth.png");
|
||||
|
||||
|
||||
earth.x = rand() % app.winWidth;
|
||||
earth.y = -(128 + (rand() % 128));
|
||||
|
||||
|
||||
initEffects();
|
||||
|
||||
|
||||
initFighters();
|
||||
|
||||
|
||||
updateAllMissions();
|
||||
|
||||
|
||||
getWidget("campaign", "title")->action = campaign;
|
||||
getWidget("challenges", "title")->action = challenges;
|
||||
getWidget("trophies", "title")->action = trophies;
|
||||
|
@ -86,28 +86,28 @@ void initTitle(void)
|
|||
getWidget("options", "title")->action = options;
|
||||
getWidget("credits", "title")->action = credits;
|
||||
getWidget("quit", "title")->action = quit;
|
||||
|
||||
|
||||
getWidget("ok", "stats")->action = ok;
|
||||
getWidget("ok", "trophies")->action = ok;
|
||||
getWidget("ok", "fighterDB")->action = ok;
|
||||
|
||||
|
||||
autoSizeWidgetButtons("title", 1);
|
||||
|
||||
|
||||
show = SHOW_TITLE;
|
||||
|
||||
|
||||
endSectionTransition();
|
||||
|
||||
|
||||
playMusic("music/main/Rise of spirit.ogg", 0);
|
||||
}
|
||||
|
||||
static void initFighters(void)
|
||||
{
|
||||
int i, numTextures;
|
||||
|
||||
|
||||
numTextures = sizeof(fighterTextures) / sizeof(char*);
|
||||
|
||||
|
||||
memset(&fighters, 0, sizeof(Entity) * NUM_FIGHTERS);
|
||||
|
||||
|
||||
for (i = 0 ; i < NUM_FIGHTERS ; i++)
|
||||
{
|
||||
fighters[i].x = rand() % (app.winWidth - 32);
|
||||
|
@ -120,50 +120,50 @@ static void initFighters(void)
|
|||
static void logic(void)
|
||||
{
|
||||
handleKeyboard();
|
||||
|
||||
|
||||
scrollBackground(0, 0.25);
|
||||
|
||||
|
||||
doStars(0, -0.5);
|
||||
|
||||
|
||||
earth.y += 0.1;
|
||||
|
||||
|
||||
if (earth.y > app.winHeight + 128)
|
||||
{
|
||||
earth.x = rand() % app.winWidth;
|
||||
earth.y = -(128 + (rand() % 128));
|
||||
}
|
||||
|
||||
|
||||
doFighters();
|
||||
|
||||
|
||||
doEffects();
|
||||
|
||||
|
||||
app.doTrophyAlerts = 1;
|
||||
|
||||
|
||||
if (show == SHOW_FIGHTER_DB)
|
||||
{
|
||||
doFighterDatabase();
|
||||
}
|
||||
|
||||
|
||||
doWidgets();
|
||||
}
|
||||
|
||||
static void doFighters(void)
|
||||
{
|
||||
int i, numTextures;
|
||||
|
||||
|
||||
numTextures = sizeof(fighterTextures) / sizeof(char*);
|
||||
|
||||
|
||||
for (i = 0 ; i < NUM_FIGHTERS ; i++)
|
||||
{
|
||||
self = &fighters[i];
|
||||
|
||||
|
||||
/* engine position hack, due to camera being fixed */
|
||||
self->y += 16;
|
||||
addEngineEffect();
|
||||
self->y -= 16;
|
||||
|
||||
|
||||
self->y += self->dy;
|
||||
|
||||
|
||||
if (self->y <= -64)
|
||||
{
|
||||
self->x = rand() % (app.winWidth - 32);
|
||||
|
@ -177,27 +177,27 @@ static void doFighters(void)
|
|||
static void draw(void)
|
||||
{
|
||||
drawBackground(background);
|
||||
|
||||
|
||||
drawStars();
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blit(earthTexture, earth.x, earth.y, 1);
|
||||
|
||||
|
||||
drawFighters();
|
||||
|
||||
|
||||
drawEffects();
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
blit(logo[0], (app.winWidth / 2) - logo[0]->rect.w, 30, 0);
|
||||
blit(logo[1], (app.winWidth / 2), 30, 0);
|
||||
|
||||
|
||||
blit(pandoranWar, app.winWidth / 2, 110, 1);
|
||||
|
||||
|
||||
drawText(10, app.winHeight - 25, 14, TA_LEFT, colors.white, "Copyright Parallel Realities, 2015-2019");
|
||||
drawText(app.winWidth - 10, app.winHeight - 25, 14, TA_RIGHT, colors.white, "Version %.2f.%d", VERSION, REVISION);
|
||||
|
||||
|
||||
switch (show)
|
||||
{
|
||||
case SHOW_TITLE:
|
||||
|
@ -205,19 +205,19 @@ static void draw(void)
|
|||
drawWidgets("title");
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_STATS:
|
||||
drawStats();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_OPTIONS:
|
||||
drawOptions();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_TROPHIES:
|
||||
drawTrophies();
|
||||
break;
|
||||
|
||||
|
||||
case SHOW_FIGHTER_DB:
|
||||
drawFighterDatabase();
|
||||
break;
|
||||
|
@ -227,9 +227,9 @@ static void draw(void)
|
|||
static void drawFighters(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
for (i = 0 ; i < NUM_FIGHTERS ; i++)
|
||||
{
|
||||
blit(fighters[i].texture, fighters[i].x, fighters[i].y, 1);
|
||||
|
@ -242,7 +242,7 @@ static void handleKeyboard(void)
|
|||
{
|
||||
returnFromOptions();
|
||||
playSound(SND_GUI_CLOSE);
|
||||
|
||||
|
||||
clearInput();
|
||||
}
|
||||
}
|
||||
|
@ -250,57 +250,57 @@ static void handleKeyboard(void)
|
|||
static void campaign(void)
|
||||
{
|
||||
destroyBattle();
|
||||
|
||||
|
||||
initGalacticMap();
|
||||
}
|
||||
|
||||
static void challenges(void)
|
||||
{
|
||||
destroyBattle();
|
||||
|
||||
|
||||
game.currentMission = NULL;
|
||||
|
||||
|
||||
initChallengeHome();
|
||||
}
|
||||
|
||||
static void trophies(void)
|
||||
{
|
||||
selectWidget("ok", "trophies");
|
||||
|
||||
|
||||
show = SHOW_TROPHIES;
|
||||
|
||||
|
||||
initTrophiesDisplay();
|
||||
}
|
||||
|
||||
static void fighterDatabase(void)
|
||||
{
|
||||
show = SHOW_FIGHTER_DB;
|
||||
|
||||
|
||||
initFighterDatabaseDisplay();
|
||||
}
|
||||
|
||||
static void options(void)
|
||||
{
|
||||
selectWidget("ok", "options");
|
||||
|
||||
|
||||
show = SHOW_OPTIONS;
|
||||
|
||||
|
||||
initOptions(returnFromOptions);
|
||||
}
|
||||
|
||||
static void stats(void)
|
||||
{
|
||||
selectWidget("ok", "stats");
|
||||
|
||||
|
||||
show = SHOW_STATS;
|
||||
|
||||
|
||||
initStatsDisplay();
|
||||
}
|
||||
|
||||
static void ok(void)
|
||||
{
|
||||
selectWidget("stats", "title");
|
||||
|
||||
|
||||
show = SHOW_TITLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ void initTrophies(void)
|
|||
trophyIcons[TROPHY_UNEARNED] = getAtlasImage("gfx/trophies/unearned.png");
|
||||
sparkle = getAtlasImage("gfx/trophies/sparkle.png");
|
||||
alertSphere = getAtlasImage("gfx/trophies/alertSphere.png");
|
||||
|
||||
|
||||
alertRect.h = 90;
|
||||
alertRect.y = 10;
|
||||
|
||||
|
||||
sparkleAngle = 0;
|
||||
|
||||
|
||||
TROPHIES_TEXT = _("Trophies");
|
||||
AWARDED_TEXT = _("Awarded : %d / %d");
|
||||
PAGE_TEXT = _("Page : %d / %d");
|
||||
|
@ -75,37 +75,37 @@ void initTrophiesDisplay(void)
|
|||
{
|
||||
int w, h;
|
||||
Trophy *t;
|
||||
|
||||
|
||||
boxWidth = total = awarded = 0;
|
||||
|
||||
|
||||
for (t = game.trophyHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
total++;
|
||||
|
||||
|
||||
if (t->awarded)
|
||||
{
|
||||
awarded++;
|
||||
|
||||
|
||||
STRNCPY(t->awardDateStr, timeToDate(t->awardDate), MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
calcTextDimensions(t->description, 18, &w, &h);
|
||||
|
||||
|
||||
boxWidth = MAX(boxWidth, w);
|
||||
}
|
||||
|
||||
|
||||
boxWidth += 125;
|
||||
|
||||
|
||||
page = 0;
|
||||
|
||||
|
||||
maxPages = total;
|
||||
maxPages /= TROPHIES_PER_PAGE;
|
||||
maxPages = ceil(maxPages);
|
||||
|
||||
|
||||
prev = getWidget("prev", "trophies");
|
||||
prev->action = prevPage;
|
||||
prev->visible = 0;
|
||||
|
||||
|
||||
next = getWidget("next", "trophies");
|
||||
next->action = nextPage;
|
||||
next->visible = 1;
|
||||
|
@ -114,7 +114,7 @@ void initTrophiesDisplay(void)
|
|||
static void nextPage(void)
|
||||
{
|
||||
page = MIN(page + 1, maxPages - 1);
|
||||
|
||||
|
||||
next->visible = page < maxPages - 1;
|
||||
prev->visible = 1;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ static void nextPage(void)
|
|||
static void prevPage(void)
|
||||
{
|
||||
page = MAX(0, page - 1);
|
||||
|
||||
|
||||
next->visible = 1;
|
||||
prev->visible = page > 0;
|
||||
}
|
||||
|
@ -132,37 +132,37 @@ void drawTrophies(void)
|
|||
Trophy *t;
|
||||
SDL_Rect r;
|
||||
int start, end, i, x, y;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
|
||||
r.w = boxWidth;
|
||||
r.h = 650;
|
||||
r.x = (UI_WIDTH / 2) - r.w / 2;
|
||||
r.y = (UI_HEIGHT / 2) - r.h / 2;
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(app.renderer, &r);
|
||||
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
|
||||
SDL_RenderDrawRect(app.renderer, &r);
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 40, 28, TA_CENTER, colors.white, TROPHIES_TEXT);
|
||||
drawText(UI_WIDTH / 2, 83, 16, TA_CENTER, colors.lightGrey, AWARDED_TEXT, awarded, total);
|
||||
drawText(UI_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, PAGE_TEXT, page + 1, (int)maxPages);
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255);
|
||||
SDL_RenderDrawLine(app.renderer, r.x, 150, r.x + r.w, 150);
|
||||
|
||||
|
||||
x = r.x + 15;
|
||||
y = 180;
|
||||
start = page * TROPHIES_PER_PAGE;
|
||||
end = start + TROPHIES_PER_PAGE;
|
||||
i = 0;
|
||||
|
||||
|
||||
for (t = game.trophyHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
if (i >= start && i < end)
|
||||
|
@ -172,7 +172,7 @@ void drawTrophies(void)
|
|||
setSparkleColor(t);
|
||||
blitRotated(sparkle, x + 32, y + 32, sparkleAngle);
|
||||
blitRotated(sparkle, x + 32, y + 32, -sparkleAngle);
|
||||
|
||||
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
blitScaled(trophyIcons[t->value], x, y, 64, 64, 0);
|
||||
drawText(x + 85, y - 10, 20, TA_LEFT, colors.yellow, t->title);
|
||||
|
@ -195,15 +195,15 @@ void drawTrophies(void)
|
|||
drawText(x + 85, y + 20, 20, TA_LEFT, colors.darkGrey, HIDDEN_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
y += 120;
|
||||
}
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
drawWidgets("trophies");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -211,9 +211,9 @@ void awardTrophy(char *id)
|
|||
{
|
||||
Trophy *t;
|
||||
int numRemaining;
|
||||
|
||||
|
||||
numRemaining = 0;
|
||||
|
||||
|
||||
for (t = game.trophyHead.next ; t != NULL ; t = t->next)
|
||||
{
|
||||
if (!t->awarded && strcmp(t->id, id) == 0)
|
||||
|
@ -221,21 +221,21 @@ void awardTrophy(char *id)
|
|||
t->awarded = 1;
|
||||
t->awardDate = time(NULL);
|
||||
t->notify = SDL_GetTicks();
|
||||
|
||||
|
||||
/* prevent race condition */
|
||||
SDL_Delay(1);
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Awarding trophy '%s'", t->id);
|
||||
|
||||
|
||||
app.saveGame = 1;
|
||||
}
|
||||
|
||||
|
||||
if (!t->awarded)
|
||||
{
|
||||
numRemaining++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* the Platinum will always be the last trophy to unlock */
|
||||
if (numRemaining == 1)
|
||||
{
|
||||
|
@ -264,7 +264,7 @@ void doTrophyAlerts(void)
|
|||
resetAlert();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sparkleAngle = mod(sparkleAngle + 0.25, 360);
|
||||
}
|
||||
|
||||
|
@ -283,15 +283,15 @@ static void nextAlert(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (alertTrophy)
|
||||
{
|
||||
playSound(SND_TROPHY);
|
||||
|
||||
|
||||
calcTextDimensions(alertTrophy->title, 30, &alertRect.w, &h);
|
||||
|
||||
|
||||
calcTextDimensions(alertTrophy->description, 20, &w, &h);
|
||||
|
||||
|
||||
alertRect.w = MAX(alertRect.w, w);
|
||||
alertRect.w = MAX(400, alertRect.w);
|
||||
alertRect.w += 125;
|
||||
|
@ -308,7 +308,7 @@ static void resetAlert(void)
|
|||
void drawTrophyAlert(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
|
||||
if (alertTrophy)
|
||||
{
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
|
@ -319,9 +319,9 @@ void drawTrophyAlert(void)
|
|||
|
||||
drawText(alertRect.x + 15, alertRect.y + 5, 30, TA_LEFT, colors.white, alertTrophy->title);
|
||||
drawText(alertRect.x + 15, alertRect.y + 45, 20, TA_LEFT, colors.white, alertTrophy->description);
|
||||
|
||||
|
||||
setSparkleColor(alertTrophy);
|
||||
|
||||
|
||||
x = alertRect.x + alertRect.w - 72;
|
||||
y = alertRect.y + 20;
|
||||
|
||||
|
@ -360,7 +360,7 @@ static void loadTrophyData(char *filename)
|
|||
root = cJSON_Parse(text);
|
||||
|
||||
tail = &game.trophyHead;
|
||||
|
||||
|
||||
memset(count, 0, sizeof(int) * TROPHY_MAX);
|
||||
|
||||
for (node = root->child ; node != NULL ; node = node->next)
|
||||
|
@ -375,16 +375,16 @@ static void loadTrophyData(char *filename)
|
|||
STRNCPY(t->description, _(cJSON_GetObjectItem(node, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
||||
t->value = lookup(cJSON_GetObjectItem(node, "value")->valuestring);
|
||||
t->hidden = getJSONValue(node, "hidden", 0);
|
||||
|
||||
|
||||
t->stat = -1;
|
||||
|
||||
|
||||
/* can't use the getJSONValue here, as it could lead to false positives */
|
||||
if (cJSON_GetObjectItem(node, "stat"))
|
||||
{
|
||||
t->stat = lookup(cJSON_GetObjectItem(node, "stat")->valuestring);
|
||||
t->statValue = cJSON_GetObjectItem(node, "statValue")->valueint;
|
||||
}
|
||||
|
||||
|
||||
count[t->value]++;
|
||||
count[TROPHY_UNEARNED]++;
|
||||
|
||||
|
@ -392,7 +392,7 @@ static void loadTrophyData(char *filename)
|
|||
tail = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Trophies (%d) [Bronze=%d, Silver=%d, Gold=%d, Platinum=%d]", count[TROPHY_UNEARNED], count[TROPHY_BRONZE], count[TROPHY_SILVER], count[TROPHY_GOLD], count[TROPHY_PLATINUM]);
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
@ -411,7 +411,7 @@ void awardStatsTrophies(void)
|
|||
awardTrophy(t->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check to see if we've destroyed one of each common starfighter */
|
||||
for (tp = game.fighterStatHead.next ; tp != NULL ; tp = tp->next)
|
||||
{
|
||||
|
@ -420,7 +420,7 @@ void awardStatsTrophies(void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
awardTrophy("FREQUENT_FLYER");
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,7 @@ void awardCampaignTrophies(void)
|
|||
char name[MAX_NAME_LENGTH];
|
||||
int i, len;
|
||||
StarSystem *starSystem;
|
||||
|
||||
|
||||
if (game.completedMissions)
|
||||
{
|
||||
awardTrophy("CAMPAIGN_1");
|
||||
|
@ -449,7 +449,7 @@ void awardCampaignTrophies(void)
|
|||
{
|
||||
name[i] = toupper(starSystem->name[i]);
|
||||
}
|
||||
|
||||
|
||||
sprintf(trophyId, "CAMPAIGN_%s", name);
|
||||
awardTrophy(trophyId);
|
||||
}
|
||||
|
@ -472,13 +472,13 @@ void awardPostMissionTrophies(void)
|
|||
if (game.currentMission->epic)
|
||||
{
|
||||
awardTrophy("EPIC");
|
||||
|
||||
|
||||
if (battle.stats[STAT_PLAYER_KILLED] == 0 && player->flags & EF_COMMON_FIGHTER)
|
||||
{
|
||||
awardTrophy("SURVIVOR");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Must be a non-challenge mission, a common fighter, must not be Sol, and must not have fired any shots or missiles (and there should have been some enemies present)
|
||||
*/
|
||||
|
@ -508,7 +508,7 @@ void awardCraftTrophy(void)
|
|||
awardTrophy("SHUTTLE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
awardPandoranCraftTrophy();
|
||||
}
|
||||
|
||||
|
@ -519,15 +519,15 @@ static void setSparkleColor(Trophy *t)
|
|||
case TROPHY_BRONZE:
|
||||
setAtlasColor(255, 128, 0, 255);
|
||||
break;
|
||||
|
||||
|
||||
case TROPHY_SILVER:
|
||||
setAtlasColor(192, 192, 192, 255);
|
||||
break;
|
||||
|
||||
|
||||
case TROPHY_GOLD:
|
||||
setAtlasColor(255, 255, 0, 255);
|
||||
break;
|
||||
|
||||
|
||||
case TROPHY_PLATINUM:
|
||||
setAtlasColor(0, 128, 255, 255);
|
||||
break;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -36,7 +36,7 @@ extern "C"
|
|||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
|
@ -83,7 +83,7 @@ extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
|||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
|
@ -113,7 +113,7 @@ extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
|||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
|
|
90
src/main.c
90
src/main.c
|
@ -28,103 +28,103 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
long then, lastFrameTime, frames;
|
||||
float remainder;
|
||||
|
||||
|
||||
memset(&app, 0, sizeof(App));
|
||||
memset(&dev, 0, sizeof(Dev));
|
||||
|
||||
|
||||
handleLoggingArgs(argc, argv);
|
||||
|
||||
|
||||
atexit(cleanup);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
|
||||
init18N(argc, argv);
|
||||
|
||||
|
||||
initLookups();
|
||||
|
||||
initSDL(argc, argv);
|
||||
|
||||
|
||||
initGameSystem();
|
||||
|
||||
|
||||
createScreenshotFolder();
|
||||
|
||||
|
||||
if (fileExists(getSaveFilePath(SAVE_FILENAME)))
|
||||
{
|
||||
loadGame();
|
||||
}
|
||||
|
||||
|
||||
handleMissionArgs(argc, argv);
|
||||
|
||||
|
||||
remainder = 0;
|
||||
dev.fps = frames = 0;
|
||||
then = SDL_GetTicks();
|
||||
lastFrameTime = SDL_GetTicks() + 1000;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
capFrameRate(&then, &remainder);
|
||||
|
||||
|
||||
doInput();
|
||||
|
||||
|
||||
if (app.modalDialog.type != MD_NONE)
|
||||
{
|
||||
doModalDialog();
|
||||
}
|
||||
|
||||
|
||||
/* let the delegate decide during logic() */
|
||||
app.doTrophyAlerts = 0;
|
||||
|
||||
|
||||
app.delegate.logic();
|
||||
|
||||
|
||||
if (app.doTrophyAlerts)
|
||||
{
|
||||
doTrophyAlerts();
|
||||
}
|
||||
|
||||
|
||||
game.stats[STAT_TIME]++;
|
||||
|
||||
|
||||
/* always zero the mouse motion */
|
||||
app.mouse.dx = app.mouse.dy = 0;
|
||||
|
||||
|
||||
prepareScene();
|
||||
|
||||
app.delegate.draw();
|
||||
|
||||
|
||||
if (app.doTrophyAlerts)
|
||||
{
|
||||
drawTrophyAlert();
|
||||
}
|
||||
|
||||
|
||||
if (app.modalDialog.type != MD_NONE)
|
||||
{
|
||||
drawModalDialog();
|
||||
}
|
||||
|
||||
|
||||
presentScene();
|
||||
|
||||
|
||||
doDevKeys();
|
||||
|
||||
|
||||
frames++;
|
||||
|
||||
|
||||
if (SDL_GetTicks() > lastFrameTime)
|
||||
{
|
||||
dev.fps = frames;
|
||||
frames = 0;
|
||||
lastFrameTime = SDL_GetTicks() + 1000;
|
||||
|
||||
|
||||
if (dev.takeScreenshots)
|
||||
{
|
||||
saveScreenshot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isControl(CONTROL_SCREENSHOT))
|
||||
{
|
||||
saveScreenshot();
|
||||
|
||||
|
||||
clearControl(CONTROL_SCREENSHOT);
|
||||
}
|
||||
|
||||
|
||||
/* don't save more than once per request, and not in the middle of battle */
|
||||
if (app.saveGame && battle.status != MS_IN_PROGRESS)
|
||||
{
|
||||
|
@ -141,40 +141,40 @@ int main(int argc, char *argv[])
|
|||
static void capFrameRate(long *then, float *remainder)
|
||||
{
|
||||
long wait;
|
||||
|
||||
|
||||
wait = 16 + *remainder;
|
||||
|
||||
|
||||
*remainder -= (int)*remainder;
|
||||
|
||||
|
||||
wait -= (SDL_GetTicks() - *then);
|
||||
|
||||
|
||||
if (wait < 1)
|
||||
{
|
||||
wait = 1;
|
||||
}
|
||||
|
||||
|
||||
SDL_Delay(wait);
|
||||
|
||||
|
||||
*remainder += 0.666667;
|
||||
|
||||
|
||||
*then = SDL_GetTicks();
|
||||
}
|
||||
|
||||
static void handleLoggingArgs(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN);
|
||||
|
||||
|
||||
for (i = 1 ; i < argc ; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "-debug") == 0)
|
||||
{
|
||||
dev.debug = 1;
|
||||
|
||||
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(argv[i], "-info") == 0)
|
||||
{
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
@ -185,25 +185,25 @@ static void handleLoggingArgs(int argc, char *argv[])
|
|||
static void handleMissionArgs(int argc, char *argv[])
|
||||
{
|
||||
int i, testingMission, showCredits;
|
||||
|
||||
|
||||
showCredits = testingMission = 0;
|
||||
|
||||
|
||||
for (i = 1 ; i < argc ; i++)
|
||||
{
|
||||
/* assume this is filename for testing */
|
||||
if (strcmp(argv[i], "-mission") == 0)
|
||||
{
|
||||
loadTestMission(argv[++i]);
|
||||
|
||||
|
||||
testingMission = 1;
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(argv[i], "-credits") == 0)
|
||||
{
|
||||
showCredits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (showCredits)
|
||||
{
|
||||
initCredits();
|
||||
|
|
|
@ -19,35 +19,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
|
||||
#include "unixInit.h"
|
||||
|
||||
|
||||
void createSaveFolder(void)
|
||||
{
|
||||
char *userHome;
|
||||
char dir[MAX_FILENAME_LENGTH];
|
||||
|
||||
|
||||
userHome = getenv("HOME");
|
||||
|
||||
|
||||
if (!userHome)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Unable to determine user save folder. Will save to current dir.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "User home = %s", userHome);
|
||||
|
||||
|
||||
sprintf(dir, "%s/.local/share/tbftss", userHome);
|
||||
if (mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0 && errno != EEXIST)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Failed to create save dir '%s'. Will save to current dir.", dir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
STRNCPY(app.saveDir, dir, MAX_FILENAME_LENGTH);
|
||||
}
|
||||
|
||||
void createScreenshotFolder(void)
|
||||
{
|
||||
mkdir("/tmp/tbftss", S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
|
||||
|
||||
|
||||
dev.screenshotFolder = "/tmp/tbftss";
|
||||
}
|
||||
|
|
|
@ -24,24 +24,24 @@ void createSaveFolder(void)
|
|||
{
|
||||
char *userHome;
|
||||
char dir[MAX_FILENAME_LENGTH];
|
||||
|
||||
|
||||
userHome = getenv("USERPROFILE");
|
||||
|
||||
|
||||
if (!userHome)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Unable to determine user save folder. Will save to current dir.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "User home = %s", userHome);
|
||||
|
||||
|
||||
sprintf(dir, "%s\\tbftss", userHome);
|
||||
if (mkdir(dir) != 0 && errno != EEXIST)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Failed to create save dir '%s'. Will save to current dir.", dir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
STRNCPY(app.saveDir, dir, MAX_FILENAME_LENGTH);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ static SDL_Texture *atlasTexture;
|
|||
void initAtlas(void)
|
||||
{
|
||||
memset(&atlases, 0, sizeof(AtlasImage) * NUM_ATLAS_BUCKETS);
|
||||
|
||||
|
||||
atlasTexture = getTexture("gfx/atlas/atlas.png");
|
||||
|
||||
loadAtlasData();
|
||||
|
@ -46,7 +46,7 @@ AtlasImage *getAtlasImage(char *filename)
|
|||
unsigned long i;
|
||||
|
||||
i = hashcode(filename) % NUM_ATLAS_BUCKETS;
|
||||
|
||||
|
||||
for (a = atlases[i].next ; a != NULL ; a = a->next)
|
||||
{
|
||||
if (strcmp(a->filename, filename) == 0)
|
||||
|
@ -54,10 +54,10 @@ AtlasImage *getAtlasImage(char *filename)
|
|||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_CRITICAL, "No such atlas image '%s'", filename);
|
||||
exit(1);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ char **getAtlasFileList(char *dir, int *count)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
filenames = malloc(sizeof(char*) * i);
|
||||
|
@ -121,11 +121,11 @@ static void loadAtlasData(void)
|
|||
cJSON *root, *node;
|
||||
char *text, *filename;
|
||||
unsigned long i;
|
||||
|
||||
|
||||
text = readFile("data/atlas/atlas.json");
|
||||
|
||||
root = cJSON_Parse(text);
|
||||
|
||||
|
||||
for (node = root->child ; node != NULL ; node = node->next)
|
||||
{
|
||||
filename = cJSON_GetObjectItem(node, "filename")->valuestring;
|
||||
|
@ -143,21 +143,21 @@ static void loadAtlasData(void)
|
|||
{
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
|
||||
atlasImage = malloc(sizeof(AtlasImage));
|
||||
memset(atlasImage, 0, sizeof(AtlasImage));
|
||||
a->next = atlasImage;
|
||||
|
||||
|
||||
STRNCPY(atlasImage->filename, filename, MAX_FILENAME_LENGTH);
|
||||
atlasImage->rect.x = x;
|
||||
atlasImage->rect.y = y;
|
||||
atlasImage->rect.w = w;
|
||||
atlasImage->rect.h = h;
|
||||
|
||||
|
||||
atlasImage->texture = atlasTexture;
|
||||
}
|
||||
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
||||
|
||||
free(text);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ static char *ESCAPE_TEXT;
|
|||
void initControls(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
controlName[CONTROL_FIRE] = _("Fire");
|
||||
controlName[CONTROL_ACCELERATE] = _("Accelerate");
|
||||
controlName[CONTROL_BOOST] = _("Boost");
|
||||
|
@ -45,7 +45,7 @@ void initControls(void)
|
|||
controlName[CONTROL_NEXT_FIGHTER] = _("Next Fighter");
|
||||
controlName[CONTROL_PREV_FIGHTER] = _("Previous Fighter");
|
||||
controlName[CONTROL_SCREENSHOT] = _("Screenshot");
|
||||
|
||||
|
||||
for (i = 0 ; i < CONTROL_MAX ; i++)
|
||||
{
|
||||
controlWidget[i] = getWidget(getLookupName("CONTROL_", i), "controls");
|
||||
|
@ -56,7 +56,7 @@ void initControls(void)
|
|||
strcpy(controlWidget[i]->options[0], "");
|
||||
strcpy(controlWidget[i]->options[1], "");
|
||||
}
|
||||
|
||||
|
||||
CONTROLS_TEXT = _("Controls");
|
||||
HELP_TEXT = _("Click a control to change it, and then the key or mouse button you want to use.");
|
||||
BACKSPACE_TEXT = _("[BACKSPACE] - Clear");
|
||||
|
@ -66,23 +66,23 @@ void initControls(void)
|
|||
void initControlsDisplay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0 ; i < CONTROL_MAX ; i++)
|
||||
{
|
||||
strcpy(controlWidget[i]->options[0], "");
|
||||
strcpy(controlWidget[i]->options[1], "");
|
||||
|
||||
|
||||
if (app.keyControls[i] != 0)
|
||||
{
|
||||
sprintf(controlWidget[i]->options[0], "%s", SDL_GetScancodeName(app.keyControls[i]));
|
||||
}
|
||||
|
||||
|
||||
if (app.mouseControls[i] != 0)
|
||||
{
|
||||
sprintf(controlWidget[i]->options[1], "Btn %d", app.mouseControls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getWidget("restore", "controls")->action = restoreDefaults;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ int isControl(int type)
|
|||
{
|
||||
int key = app.keyControls[type];
|
||||
int btn = app.mouseControls[type];
|
||||
|
||||
|
||||
return ((key != 0 && app.keyboard[key]) || (btn != 0 && app.mouse.button[btn]));
|
||||
}
|
||||
|
||||
|
@ -103,12 +103,12 @@ void clearControl(int type)
|
|||
{
|
||||
int key = app.keyControls[type];
|
||||
int btn = app.mouseControls[type];
|
||||
|
||||
|
||||
if (key != 0)
|
||||
{
|
||||
app.keyboard[key] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (btn != 0)
|
||||
{
|
||||
app.mouse.button[btn] = 0;
|
||||
|
@ -118,32 +118,32 @@ void clearControl(int type)
|
|||
void resetAcceptControls(void)
|
||||
{
|
||||
app.keyboard[SDL_SCANCODE_SPACE] = app.keyboard[SDL_SCANCODE_RETURN] = 0;
|
||||
|
||||
|
||||
clearControl(CONTROL_FIRE);
|
||||
}
|
||||
|
||||
void updateControlKey(char *name)
|
||||
{
|
||||
app.keyControls[lookup(name)] = app.lastKeyPressed;
|
||||
|
||||
|
||||
initControlsDisplay();
|
||||
}
|
||||
|
||||
void updateControlButton(char *name)
|
||||
{
|
||||
app.mouseControls[lookup(name)] = app.lastButtonPressed;
|
||||
|
||||
|
||||
initControlsDisplay();
|
||||
}
|
||||
|
||||
void clearControlConfig(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
i = lookup(name);
|
||||
|
||||
|
||||
app.keyControls[i] = app.mouseControls[i] = 0;
|
||||
|
||||
|
||||
initControlsDisplay();
|
||||
}
|
||||
|
||||
|
@ -151,12 +151,12 @@ void drawControls(void)
|
|||
{
|
||||
int i;
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 800;
|
||||
|
@ -173,37 +173,37 @@ void drawControls(void)
|
|||
|
||||
SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255);
|
||||
SDL_RenderDrawLine(app.renderer, r.x, r.y + 65, r.x + r.w, r.y + 65);
|
||||
|
||||
|
||||
r.x += 25;
|
||||
r.y = 125;
|
||||
|
||||
|
||||
for (i = 0 ; i < CONTROL_MAX ; i++)
|
||||
{
|
||||
drawText(r.x, r.y + 2, 20, TA_LEFT, colors.white, controlName[i]);
|
||||
|
||||
|
||||
controlWidget[i]->rect.x = r.x + 175;
|
||||
controlWidget[i]->rect.y = r.y;
|
||||
|
||||
|
||||
r.y += 65;
|
||||
|
||||
|
||||
if (r.y > 500)
|
||||
{
|
||||
r.y = 125;
|
||||
r.x += 400;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawText((UI_WIDTH / 2) - 50, 525, 16, TA_RIGHT, colors.white, BACKSPACE_TEXT);
|
||||
drawText((UI_WIDTH / 2) + 50, 525, 16, TA_LEFT, colors.white, ESCAPE_TEXT);
|
||||
|
||||
|
||||
app.textWidth = r.w - 100;
|
||||
|
||||
|
||||
drawText(UI_WIDTH / 2, 560, 16, TA_CENTER, colors.white, HELP_TEXT);
|
||||
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
drawWidgets("controls");
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
||||
|
@ -243,6 +243,6 @@ static void restoreDefaults(void)
|
|||
|
||||
cJSON_Delete(root);
|
||||
free(text);
|
||||
|
||||
|
||||
initControlsDisplay();
|
||||
}
|
||||
|
|
|
@ -30,48 +30,48 @@ void doDevKeys(void)
|
|||
app.keyboard[SDL_SCANCODE_1] = 0;
|
||||
printf("DEBUG: dev.playerImmortal=%d\n", dev.playerImmortal);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_2])
|
||||
{
|
||||
dev.playerUnlimitedMissiles = !dev.playerUnlimitedMissiles;
|
||||
app.keyboard[SDL_SCANCODE_2] = 0;
|
||||
printf("DEBUG: dev.playerUnlimitedMissiles=%d\n", dev.playerUnlimitedMissiles);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_3])
|
||||
{
|
||||
dev.noAIWeapons = !dev.noAIWeapons;
|
||||
app.keyboard[SDL_SCANCODE_3] = 0;
|
||||
printf("DEBUG: dev.noAIWeapons=%d\n", dev.noAIWeapons);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_4])
|
||||
{
|
||||
dev.noEntityActions = !dev.noEntityActions;
|
||||
app.keyboard[SDL_SCANCODE_4] = 0;
|
||||
printf("DEBUG: dev.noEntityActions=%d\n", dev.noEntityActions);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_5])
|
||||
{
|
||||
dev.allImmortal = !dev.allImmortal;
|
||||
app.keyboard[SDL_SCANCODE_5] = 0;
|
||||
printf("DEBUG: dev.allImmortal=%d\n", dev.allImmortal);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_6])
|
||||
{
|
||||
completeMission();
|
||||
battle.missionFinishedTimer = -FPS;
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_9])
|
||||
{
|
||||
dev.showFPS = !dev.showFPS;
|
||||
app.keyboard[SDL_SCANCODE_9] = 0;
|
||||
printf("DEBUG: dev.showFPS=%d\n", dev.showFPS);
|
||||
}
|
||||
|
||||
|
||||
if (app.keyboard[SDL_SCANCODE_0])
|
||||
{
|
||||
dev.takeScreenshots = !dev.takeScreenshots;
|
||||
|
|
|
@ -28,16 +28,16 @@ void initGraphics(void)
|
|||
{
|
||||
backgroundPoint[0].x = -app.winWidth / 2;
|
||||
backgroundPoint[0].y = -app.winHeight / 2;
|
||||
|
||||
|
||||
backgroundPoint[1].x = app.winWidth / 2;
|
||||
backgroundPoint[1].y = -app.winHeight / 2;
|
||||
|
||||
|
||||
backgroundPoint[2].x = -app.winWidth / 2;
|
||||
backgroundPoint[2].y = app.winHeight / 2;
|
||||
|
||||
|
||||
backgroundPoint[3].x = app.winWidth / 2;
|
||||
backgroundPoint[3].y = app.winHeight / 2;
|
||||
|
||||
|
||||
initColor(&colors.red, 255, 0, 0);
|
||||
initColor(&colors.orange, 255, 128, 0);
|
||||
initColor(&colors.yellow, 255, 255, 0);
|
||||
|
@ -65,7 +65,7 @@ void prepareScene(void)
|
|||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(app.renderer);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(app.renderer);
|
||||
|
@ -74,22 +74,22 @@ void prepareScene(void)
|
|||
void presentScene(void)
|
||||
{
|
||||
SDL_Rect uiDest;
|
||||
|
||||
|
||||
uiDest.w = UI_WIDTH;
|
||||
uiDest.h = UI_HEIGHT;
|
||||
uiDest.x = app.uiOffset.x;
|
||||
uiDest.y = app.uiOffset.y;
|
||||
|
||||
|
||||
if (dev.debug)
|
||||
{
|
||||
drawText(5, app.winHeight - 25, 14, TA_LEFT, colors.white, "DEBUG MODE");
|
||||
|
||||
|
||||
if (dev.showFPS)
|
||||
{
|
||||
drawText(app.winWidth / 2, app.winHeight - 25, 14, TA_CENTER, colors.white, "FPS: %d", dev.fps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, NULL);
|
||||
SDL_RenderCopy(app.renderer, app.backBuffer, NULL, NULL);
|
||||
SDL_RenderCopy(app.renderer, app.uiBuffer, NULL, &uiDest);
|
||||
|
@ -103,7 +103,7 @@ void presentScene(void)
|
|||
void blit(AtlasImage *atlasImage, int x, int y, int center)
|
||||
{
|
||||
SDL_Rect dstRect;
|
||||
|
||||
|
||||
dstRect.x = x;
|
||||
dstRect.y = y;
|
||||
dstRect.w = atlasImage->rect.w;
|
||||
|
@ -114,19 +114,19 @@ void blit(AtlasImage *atlasImage, int x, int y, int center)
|
|||
dstRect.x -= (dstRect.w / 2);
|
||||
dstRect.y -= (dstRect.h / 2);
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderCopy(app.renderer, atlasImage->texture, &atlasImage->rect, &dstRect);
|
||||
}
|
||||
|
||||
void blitScaled(AtlasImage *atlasImage, int x, int y, int w, int h, int center)
|
||||
{
|
||||
SDL_Rect dstRect;
|
||||
|
||||
|
||||
dstRect.x = x;
|
||||
dstRect.y = y;
|
||||
dstRect.w = w;
|
||||
dstRect.h = h;
|
||||
|
||||
|
||||
if (center)
|
||||
{
|
||||
dstRect.x -= (dstRect.w / 2);
|
||||
|
@ -139,12 +139,12 @@ void blitScaled(AtlasImage *atlasImage, int x, int y, int w, int h, int center)
|
|||
void blitRotated(AtlasImage *atlasImage, int x, int y, float angle)
|
||||
{
|
||||
SDL_Rect dstRect;
|
||||
|
||||
|
||||
dstRect.x = x;
|
||||
dstRect.y = y;
|
||||
dstRect.w = atlasImage->rect.w;
|
||||
dstRect.h = atlasImage->rect.h;
|
||||
|
||||
|
||||
dstRect.x -= (dstRect.w / 2);
|
||||
dstRect.y -= (dstRect.h / 2);
|
||||
|
||||
|
@ -192,27 +192,27 @@ void drawCircle(int cx, int cy, int radius, int r, int g, int b, int a)
|
|||
void scrollBackground(float x, float y)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
backgroundPoint[i].x += x;
|
||||
backgroundPoint[i].y += y;
|
||||
|
||||
|
||||
if (backgroundPoint[i].x < 0)
|
||||
{
|
||||
backgroundPoint[i].x += (app.winWidth * 2);
|
||||
}
|
||||
|
||||
|
||||
if (backgroundPoint[i].x >= app.winWidth)
|
||||
{
|
||||
backgroundPoint[i].x -= (app.winWidth * 2);
|
||||
}
|
||||
|
||||
|
||||
if (backgroundPoint[i].y < 0)
|
||||
{
|
||||
backgroundPoint[i].y += (app.winHeight * 2);
|
||||
}
|
||||
|
||||
|
||||
if (backgroundPoint[i].y >= app.winHeight)
|
||||
{
|
||||
backgroundPoint[i].y -= (app.winHeight * 2);
|
||||
|
@ -224,7 +224,7 @@ void drawBackground(SDL_Texture *texture)
|
|||
{
|
||||
int i;
|
||||
SDL_Rect dstRect;
|
||||
|
||||
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
dstRect.x = backgroundPoint[i].x;
|
||||
|
@ -241,17 +241,17 @@ int isOnBattleScreen(int x, int y, int w, int h)
|
|||
x -= (w / 2);
|
||||
x -= (app.winWidth / 2);
|
||||
x -= battle.camera.x;
|
||||
|
||||
|
||||
y -= (h / 2);
|
||||
y -= (app.winHeight / 2);
|
||||
y -= battle.camera.y;
|
||||
|
||||
|
||||
w *= 2;
|
||||
w += app.winWidth;
|
||||
|
||||
|
||||
h *= 2;
|
||||
h += app.winHeight;
|
||||
|
||||
|
||||
return collision(x, y, w, h, 0, 0, app.winWidth, app.winHeight);
|
||||
}
|
||||
|
||||
|
@ -260,14 +260,14 @@ void saveScreenshot(void)
|
|||
static int i = 0;
|
||||
char filename[MAX_NAME_LENGTH];
|
||||
SDL_Surface *sshot;
|
||||
|
||||
|
||||
sprintf(filename, "/tmp/tbftss/%d.bmp", ++i);
|
||||
|
||||
|
||||
sshot = SDL_CreateRGBSurface(0, app.winWidth, app.winHeight, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
||||
SDL_RenderReadPixels(app.renderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);
|
||||
SDL_SaveBMP(sshot, filename);
|
||||
SDL_FreeSurface(sshot);
|
||||
|
||||
|
||||
if (!dev.takeScreenshots)
|
||||
{
|
||||
printf("Saved '%s'\n", filename);
|
||||
|
|
|
@ -77,7 +77,7 @@ void setLanguage(char *applicationName, char *languageCode)
|
|||
{
|
||||
STRNCPY(language, languageCode, MAX_DESCRIPTION_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
strtok(language, ".");
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Locale is %s", language);
|
||||
|
@ -100,9 +100,9 @@ void setLanguage(char *applicationName, char *languageCode)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strtok(language, "_");
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Language is %s", language);
|
||||
|
||||
sprintf(c, "%s/%s/LC_MESSAGES/%s.mo", LOCALE_DIR, language, applicationName);
|
||||
|
|
|
@ -117,7 +117,7 @@ void doInput(void)
|
|||
{
|
||||
SDL_Event event;
|
||||
int x, y;
|
||||
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
|
@ -125,11 +125,11 @@ void doInput(void)
|
|||
case SDL_MOUSEMOTION:
|
||||
doMouseMotion(&event.motion);
|
||||
break;
|
||||
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
doMouseWheel(&event.wheel);
|
||||
break;
|
||||
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
doMouseDown(&event.button);
|
||||
break;
|
||||
|
@ -137,11 +137,11 @@ void doInput(void)
|
|||
case SDL_MOUSEBUTTONUP:
|
||||
doMouseUp(&event.button);
|
||||
break;
|
||||
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
doKeyDown(&event.key);
|
||||
break;
|
||||
|
||||
|
||||
case SDL_KEYUP:
|
||||
doKeyUp(&event.key);
|
||||
break;
|
||||
|
@ -163,12 +163,12 @@ void doInput(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_GetMouseState(&x, &y);
|
||||
|
||||
|
||||
app.mouse.x = x;
|
||||
app.mouse.y = y;
|
||||
|
||||
|
||||
app.uiMouse.x = x - app.uiOffset.x;
|
||||
app.uiMouse.y = y - app.uiOffset.y;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ void doInput(void)
|
|||
void clearInput(void)
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
|
||||
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
||||
memset(app.mouse.button, 0, sizeof(int) * MAX_MOUSE_BUTTONS);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ char *readFile(char *filename)
|
|||
char *buffer;
|
||||
long length;
|
||||
FILE *file;
|
||||
|
||||
|
||||
file = fopen(getFileLocation(filename), "rb");
|
||||
|
||||
if (file)
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static Lookup head;
|
||||
static Lookup *tail;
|
||||
|
||||
static void addLookup(char *name, long value);
|
||||
static void addLookup(char *name, long value);
|
||||
|
||||
void initLookups(void)
|
||||
{
|
||||
|
@ -42,13 +42,13 @@ void initLookups(void)
|
|||
addLookup("CONTROL_NEXT_FIGHTER", CONTROL_NEXT_FIGHTER);
|
||||
addLookup("CONTROL_PREV_FIGHTER", CONTROL_PREV_FIGHTER);
|
||||
addLookup("CONTROL_SCREENSHOT", CONTROL_SCREENSHOT);
|
||||
|
||||
|
||||
addLookup("ET_WAYPOINT", ET_WAYPOINT);
|
||||
addLookup("ET_JUMPGATE", ET_JUMPGATE);
|
||||
addLookup("ET_CAPITAL_SHIP", ET_CAPITAL_SHIP);
|
||||
addLookup("ET_MINE", ET_MINE);
|
||||
addLookup("ET_SHADOW_MINE", ET_SHADOW_MINE);
|
||||
|
||||
|
||||
addLookup("EF_NO_KILL", EF_NO_KILL);
|
||||
addLookup("EF_DISABLED", EF_DISABLED);
|
||||
addLookup("EF_MUST_DISABLE", EF_MUST_DISABLE);
|
||||
|
@ -261,14 +261,14 @@ long flagsToLong(char *in, int *add)
|
|||
{
|
||||
char *flag, *flags;
|
||||
long total;
|
||||
|
||||
|
||||
total = 0;
|
||||
|
||||
if (add)
|
||||
{
|
||||
*add = (in[0] == '+');
|
||||
}
|
||||
|
||||
|
||||
flags = malloc(strlen(in) + 1);
|
||||
STRNCPY(flags, in, strlen(in) + 1);
|
||||
|
||||
|
@ -278,7 +278,7 @@ long flagsToLong(char *in, int *add)
|
|||
total += lookup(flag);
|
||||
flag = strtok(NULL, "+");
|
||||
}
|
||||
|
||||
|
||||
free(flags);
|
||||
|
||||
return total;
|
||||
|
|
|
@ -100,13 +100,13 @@ void doModalDialog(void)
|
|||
void drawModalDialog(void)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
|
||||
app.textWidth = 700;
|
||||
|
||||
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 96);
|
||||
SDL_RenderFillRect(app.renderer, NULL);
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
||||
|
||||
r.w = 800;
|
||||
|
@ -138,6 +138,6 @@ void drawModalDialog(void)
|
|||
}
|
||||
|
||||
app.textWidth = 0;
|
||||
|
||||
|
||||
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ void initResources(void)
|
|||
sprintf(backgrounds[i], "gfx/backgrounds/%s", filenames[i]);
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Adding AUTO %s", filenames[i]);
|
||||
|
||||
|
||||
free(filenames[i]);
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,9 @@ void initResources(void)
|
|||
{
|
||||
planets[i] = malloc(sizeof(char) * MAX_FILENAME_LENGTH);
|
||||
strcpy(planets[i], filenames[i]);
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Adding AUTO %s", filenames[i]);
|
||||
|
||||
|
||||
free(filenames[i]);
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,9 @@ void initResources(void)
|
|||
{
|
||||
musicFiles[i] = malloc(sizeof(char) * MAX_FILENAME_LENGTH);
|
||||
sprintf(musicFiles[i], "music/battle/%s", filenames[i]);
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Adding AUTO %s", filenames[i]);
|
||||
|
||||
|
||||
free(filenames[i]);
|
||||
}
|
||||
|
||||
|
@ -99,17 +99,17 @@ char *getMusicFilename(unsigned long i)
|
|||
void destroyResources(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0 ; i < numBackgrounds ; i++)
|
||||
{
|
||||
free(backgrounds[i]);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < numPlanets ; i++)
|
||||
{
|
||||
free(planets[i]);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < numMusicFiles ; i++)
|
||||
{
|
||||
free(musicFiles[i]);
|
||||
|
|
|
@ -92,7 +92,7 @@ void playBattleSound(int id, int x, int y)
|
|||
if (distance <= MAX_BATTLE_SOUND_DISTANCE)
|
||||
{
|
||||
channel = Mix_PlayChannel(-1, sounds[id], 0);
|
||||
|
||||
|
||||
if (channel != -1)
|
||||
{
|
||||
vol = 255;
|
||||
|
|
|
@ -56,13 +56,13 @@ static SDL_Texture *loadTexture(char *filename)
|
|||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s ...", filename);
|
||||
|
||||
texture = IMG_LoadTexture(app.renderer, getFileLocation(filename));
|
||||
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_CRITICAL, "Failed to load texture '%s'", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
addTextureToCache(filename, texture);
|
||||
|
||||
return texture;
|
||||
|
@ -83,23 +83,23 @@ SDL_Texture *getTexture(char *filename)
|
|||
return t->texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "%s not in texture cache", filename);
|
||||
|
||||
|
||||
return loadTexture(filename);
|
||||
}
|
||||
|
||||
SDL_Texture *toTexture(SDL_Surface *surface, int destroySurface)
|
||||
{
|
||||
SDL_Texture *texture;
|
||||
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(app.renderer, surface);
|
||||
|
||||
|
||||
if (destroySurface)
|
||||
{
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ void startSectionTransition(void)
|
|||
transitionStartTime = SDL_GetTicks();
|
||||
|
||||
prepareScene();
|
||||
|
||||
|
||||
clearInput();
|
||||
|
||||
|
||||
presentScene();
|
||||
}
|
||||
|
||||
|
|
|
@ -109,16 +109,16 @@ char *timeToString(long millis, int showHours)
|
|||
char *timeToDate(long millis)
|
||||
{
|
||||
static char DATE[MAX_NAME_LENGTH];
|
||||
|
||||
|
||||
struct tm *timeinfo;
|
||||
time_t time;
|
||||
|
||||
|
||||
time = millis;
|
||||
|
||||
|
||||
timeinfo = localtime(&time);
|
||||
|
||||
|
||||
strftime(DATE, MAX_NAME_LENGTH, "%d %b %Y, %I:%M%p", timeinfo);
|
||||
|
||||
|
||||
return DATE;
|
||||
}
|
||||
|
||||
|
@ -160,14 +160,14 @@ void *resize(void *array, int oldSize, int newSize)
|
|||
{
|
||||
void **newArray;
|
||||
int copySize;
|
||||
|
||||
|
||||
copySize = newSize > oldSize ? oldSize : newSize;
|
||||
|
||||
|
||||
newArray = malloc(newSize);
|
||||
memset(newArray, 0, newSize);
|
||||
memcpy(newArray, array, copySize);
|
||||
free(array);
|
||||
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ unsigned long hashcode(const char *str)
|
|||
}
|
||||
|
||||
hash = ((hash << 5) + hash);
|
||||
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,17 +59,17 @@ void doWidgets(void)
|
|||
if (drawingWidgets)
|
||||
{
|
||||
updateSelectWidgets();
|
||||
|
||||
|
||||
handleMouse();
|
||||
|
||||
handleKeyboard();
|
||||
|
||||
|
||||
if (app.awaitingWidgetInput)
|
||||
{
|
||||
handleControlWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (hoverWidget != selectedWidget)
|
||||
{
|
||||
selectedWidget = NULL;
|
||||
|
@ -87,12 +87,12 @@ static void updateSelectWidgets(void)
|
|||
if (w->type == WT_SELECT_BUTTON && w->parent)
|
||||
{
|
||||
w->visible = 1;
|
||||
|
||||
|
||||
if (w->value == -1 && w->parent->value == 0)
|
||||
{
|
||||
w->visible = 0;
|
||||
}
|
||||
|
||||
|
||||
if (w->value == 1 && w->parent->value == w->parent->numOptions - 1)
|
||||
{
|
||||
w->visible = 0;
|
||||
|
@ -130,7 +130,7 @@ void drawWidgets(const char *group)
|
|||
|
||||
drawingWidgets = 1;
|
||||
mouseOver = 0;
|
||||
|
||||
|
||||
hoverWidget = NULL;
|
||||
|
||||
for (w = head.next; w != NULL ; w = w->next)
|
||||
|
@ -144,7 +144,7 @@ void drawWidgets(const char *group)
|
|||
if (mouseOver)
|
||||
{
|
||||
hoverWidget = w;
|
||||
|
||||
|
||||
if (selectedWidget != w)
|
||||
{
|
||||
if (w->type == WT_BUTTON || w->type == WT_IMG_BUTTON || w->type == WT_CONTROL_CONFIG)
|
||||
|
@ -160,12 +160,12 @@ void drawWidgets(const char *group)
|
|||
if (w->texture)
|
||||
{
|
||||
setAtlasColor(255, 255, 255, 255);
|
||||
|
||||
|
||||
if (selectedWidget == w)
|
||||
{
|
||||
setAtlasColor(128, 192, 255, 255);
|
||||
}
|
||||
|
||||
|
||||
blit(w->texture , w->rect.x, w->rect.y, 0);
|
||||
}
|
||||
else
|
||||
|
@ -198,10 +198,10 @@ void drawWidgets(const char *group)
|
|||
drawText(w->rect.x + 10, w->rect.y + 2, 20, TA_LEFT, colors.white, w->text);
|
||||
drawText(w->rect.x + w->rect.w - 10, w->rect.y + 2, 20, TA_RIGHT, colors.white, w->options[w->value]);
|
||||
break;
|
||||
|
||||
|
||||
case WT_CONTROL_CONFIG:
|
||||
SDL_RenderDrawRect(app.renderer, &w->rect);
|
||||
|
||||
|
||||
if (!app.awaitingWidgetInput || (app.awaitingWidgetInput && w != selectedWidget))
|
||||
{
|
||||
if (strlen(w->options[0]) && strlen(w->options[1]))
|
||||
|
@ -302,7 +302,7 @@ static void handleMouse(void)
|
|||
changeSelectedValue(selectedWidget->parent, selectedWidget->value);
|
||||
app.mouse.button[SDL_BUTTON_LEFT] = 0;
|
||||
break;
|
||||
|
||||
|
||||
case WT_CONTROL_CONFIG:
|
||||
if (!app.awaitingWidgetInput)
|
||||
{
|
||||
|
@ -320,7 +320,7 @@ static void handleMouse(void)
|
|||
static void handleKeyboard(void)
|
||||
{
|
||||
Widget *old;
|
||||
|
||||
|
||||
if (selectedWidget != NULL)
|
||||
{
|
||||
if (selectedWidget->type == WT_BUTTON)
|
||||
|
@ -347,7 +347,7 @@ static void handleControlWidgets(void)
|
|||
if (app.lastKeyPressed == SDL_SCANCODE_BACKSPACE)
|
||||
{
|
||||
clearControlConfig(selectedWidget->name);
|
||||
|
||||
|
||||
app.awaitingWidgetInput = 0;
|
||||
}
|
||||
else if (app.lastKeyPressed == SDL_SCANCODE_ESCAPE)
|
||||
|
@ -360,23 +360,23 @@ static void handleControlWidgets(void)
|
|||
if (app.lastKeyPressed != -1)
|
||||
{
|
||||
updateControlKey(selectedWidget->name);
|
||||
|
||||
|
||||
app.awaitingWidgetInput = 0;
|
||||
}
|
||||
|
||||
|
||||
if (app.lastButtonPressed != -1)
|
||||
{
|
||||
updateControlButton(selectedWidget->name);
|
||||
|
||||
|
||||
app.awaitingWidgetInput = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!app.awaitingWidgetInput)
|
||||
{
|
||||
clearInput();
|
||||
}
|
||||
|
||||
|
||||
app.lastKeyPressed = app.lastButtonPressed = -1;
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ static void loadWidgetSet(char *filename)
|
|||
|
||||
text = readFile(filename);
|
||||
root = cJSON_Parse(text);
|
||||
|
||||
|
||||
if (root)
|
||||
{
|
||||
for (node = root->child ; node != NULL ; node = node->next)
|
||||
|
@ -456,12 +456,12 @@ static void loadWidgetSet(char *filename)
|
|||
createSelectButtons(w);
|
||||
createOptions(w, cJSON_GetObjectItem(node, "options")->valuestring);
|
||||
break;
|
||||
|
||||
|
||||
case WT_CONTROL_CONFIG:
|
||||
w->rect.w = cJSON_GetObjectItem(node, "w")->valueint;
|
||||
w->rect.h = cJSON_GetObjectItem(node, "h")->valueint;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("Widget type %d not handled\n", w->type);
|
||||
exit(1);
|
||||
|
@ -478,7 +478,7 @@ static void loadWidgetSet(char *filename)
|
|||
{
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Failed to load '%s'", filename);
|
||||
}
|
||||
|
||||
|
||||
free(text);
|
||||
}
|
||||
|
||||
|
@ -504,7 +504,7 @@ static void createOptions(Widget *w, char *options)
|
|||
while (option)
|
||||
{
|
||||
option = _(option);
|
||||
|
||||
|
||||
w->options[i] = malloc(strlen(option) + 1);
|
||||
strcpy(w->options[i], option);
|
||||
|
||||
|
@ -552,25 +552,25 @@ void autoSizeWidgetButtons(char *group, int recenter)
|
|||
{
|
||||
int width, height, maxWidth;
|
||||
Widget *w;
|
||||
|
||||
|
||||
maxWidth = 0;
|
||||
|
||||
|
||||
for (w = head.next; w != NULL ; w = w->next)
|
||||
{
|
||||
if (strcmp(w->group, group) == 0 && w->type == WT_BUTTON)
|
||||
{
|
||||
calcTextDimensions(w->text, 20, &width, &height);
|
||||
|
||||
|
||||
maxWidth = MAX(MAX(w->rect.w, width), maxWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (w = head.next; w != NULL ; w = w->next)
|
||||
{
|
||||
if (strcmp(w->group, group) == 0 && w->type == WT_BUTTON)
|
||||
{
|
||||
w->rect.w = maxWidth + 20;
|
||||
|
||||
|
||||
if (recenter)
|
||||
{
|
||||
w->rect.x = (UI_WIDTH / 2) - (w->rect.w / 2);
|
||||
|
@ -591,7 +591,7 @@ void destroyWidgets(void)
|
|||
{
|
||||
free(w->options[i]);
|
||||
}
|
||||
|
||||
|
||||
free(w->options);
|
||||
|
||||
next = w->next;
|
||||
|
|
|
@ -23,8 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
void loadTestMission(char *filename)
|
||||
{
|
||||
game.currentMission = loadMissionMeta(filename);
|
||||
|
||||
|
||||
initBattle();
|
||||
|
||||
|
||||
loadMission(filename);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue