2015-10-20 13:51:49 +02:00
|
|
|
/*
|
2019-01-01 17:14:11 +01:00
|
|
|
Copyright (C) 2015-2019 Parallel Realities
|
2015-10-20 13:51:49 +02:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "battle.h"
|
|
|
|
|
|
|
|
static void logic(void);
|
|
|
|
static void draw(void);
|
|
|
|
static void handleKeyboard(void);
|
|
|
|
static void postBattle(void);
|
|
|
|
void destroyBattle(void);
|
|
|
|
static void doBattle(void);
|
2016-06-03 14:57:24 +02:00
|
|
|
static void optQuitBattle(void);
|
2015-10-20 13:51:49 +02:00
|
|
|
static void quitBattle(void);
|
|
|
|
static void drawMenu(void);
|
|
|
|
static void continueGame(void);
|
|
|
|
static void resume(void);
|
2016-06-03 14:57:24 +02:00
|
|
|
static void restart(void);
|
2015-10-20 13:51:49 +02:00
|
|
|
static void retry(void);
|
|
|
|
static void start(void);
|
|
|
|
static void options(void);
|
|
|
|
static void returnFromOptions(void);
|
2016-05-20 11:51:35 +02:00
|
|
|
static void checkSuspicionLevel(void);
|
2016-05-30 12:58:16 +02:00
|
|
|
static void doTorelliFireStorm(void);
|
2016-06-01 10:55:28 +02:00
|
|
|
static void endCampaign(void);
|
2015-10-20 13:51:49 +02:00
|
|
|
|
|
|
|
static int show;
|
2015-11-01 00:09:43 +01:00
|
|
|
static float ssx, ssy;
|
2015-10-20 13:51:49 +02:00
|
|
|
|
|
|
|
void initBattle(void)
|
|
|
|
{
|
|
|
|
memset(&battle, 0, sizeof(Battle));
|
|
|
|
battle.bulletTail = &battle.bulletHead;
|
2015-12-13 15:50:54 +01:00
|
|
|
battle.debrisTail = &battle.debrisHead;
|
2015-10-26 18:27:43 +01:00
|
|
|
battle.entityTail = &battle.entityHead;
|
2015-10-20 13:51:49 +02:00
|
|
|
battle.effectTail = &battle.effectHead;
|
|
|
|
battle.objectiveTail = &battle.objectiveHead;
|
2015-12-22 13:42:04 +01:00
|
|
|
battle.locationTail = &battle.locationHead;
|
2016-03-27 12:21:23 +02:00
|
|
|
battle.spawnerTail = &battle.spawnerHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
app.delegate.logic = &logic;
|
|
|
|
app.delegate.draw = &draw;
|
|
|
|
memset(&app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
|
2016-05-15 18:28:17 +02:00
|
|
|
|
|
|
|
battle.hasThreats = 1;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-02-21 08:48:22 +01:00
|
|
|
initQuadtree(&battle.quadtree);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-11 20:06:16 +01:00
|
|
|
initBullets();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-10 11:15:27 +01:00
|
|
|
initEntities();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
initStars();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-18 17:04:12 +01:00
|
|
|
initEffects();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
initHud();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-02 11:11:47 +01:00
|
|
|
initRadar();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-28 11:11:20 +01:00
|
|
|
initMessageBox();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-13 15:50:54 +01:00
|
|
|
initDebris();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-28 20:12:58 +01:00
|
|
|
resetWaypoints();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
show = SHOW_BATTLE;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
getWidget("ok", "startBattle")->action = start;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
getWidget("resume", "inBattle")->action = resume;
|
|
|
|
getWidget("options", "inBattle")->action = options;
|
2016-06-03 14:57:24 +02:00
|
|
|
getWidget("restart", "inBattle")->action = restart;
|
|
|
|
getWidget("quit", "inBattle")->action = optQuitBattle;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
getWidget("continue", "battleWon")->action = continueGame;
|
|
|
|
getWidget("retry", "battleWon")->action = retry;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
getWidget("retry", "battleLost")->action = retry;
|
|
|
|
getWidget("quit", "battleLost")->action = quitBattle;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
selectWidget("ok", "startBattle");
|
2017-02-25 17:30:17 +01:00
|
|
|
|
|
|
|
SDL_SetWindowGrab(app.window, 1);
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void logic(void)
|
|
|
|
{
|
2016-03-05 16:34:37 +01:00
|
|
|
if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE || battle.status == MS_FAILED || battle.status == MS_TIME_UP)
|
2015-10-20 13:51:49 +02:00
|
|
|
{
|
|
|
|
handleKeyboard();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
if (show == SHOW_BATTLE)
|
|
|
|
{
|
2016-02-28 14:02:57 +01:00
|
|
|
if (!battle.isEpic || (battle.isEpic && !battle.playerSelect))
|
2015-10-31 11:00:46 +01:00
|
|
|
{
|
|
|
|
doBattle();
|
|
|
|
}
|
2016-02-28 14:02:57 +01:00
|
|
|
else if (battle.isEpic && battle.playerSelect)
|
2015-10-31 11:00:46 +01:00
|
|
|
{
|
|
|
|
doPlayerSelect();
|
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
2016-05-15 09:19:26 +02:00
|
|
|
|
2016-05-31 10:37:46 +02:00
|
|
|
app.doTrophyAlerts = (battle.status != MS_IN_PROGRESS && battle.missionFinishedTimer <= -FPS * 2);
|
2016-06-01 10:55:28 +02:00
|
|
|
|
|
|
|
if (battle.campaignFinished)
|
|
|
|
{
|
|
|
|
endCampaign();
|
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
doWidgets();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void doBattle(void)
|
|
|
|
{
|
2016-05-15 09:19:26 +02:00
|
|
|
if (player->alive == ALIVE_ALIVE)
|
2015-10-20 13:51:49 +02:00
|
|
|
{
|
2015-11-01 00:09:43 +01:00
|
|
|
ssx = player->dx;
|
|
|
|
ssy = player->dy;
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-11-01 00:09:43 +01:00
|
|
|
ssx = ssy = 0;
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-01 00:09:43 +01:00
|
|
|
scrollBackground(-ssx * 0.1, -ssy * 0.1);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2018-12-31 17:46:13 +01:00
|
|
|
battle.planet.x -= ssx * 0.15;
|
|
|
|
battle.planet.y -= ssy * 0.15;
|
2016-03-09 12:51:26 +01:00
|
|
|
|
2016-02-25 11:52:01 +01:00
|
|
|
doObjectives();
|
2016-03-09 12:51:26 +01:00
|
|
|
|
2016-02-28 14:02:57 +01:00
|
|
|
doChallenges();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-01 00:09:43 +01:00
|
|
|
doHud();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-01 00:09:43 +01:00
|
|
|
doStars(ssx, ssy);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
doBullets();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-26 18:27:43 +01:00
|
|
|
doEntities();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
doEffects();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-13 15:50:54 +01:00
|
|
|
doDebris();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
doPlayer();
|
2016-05-20 11:51:35 +02:00
|
|
|
|
|
|
|
checkSuspicionLevel();
|
2016-05-30 12:58:16 +02:00
|
|
|
|
|
|
|
doTorelliFireStorm();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-05-15 09:19:26 +02:00
|
|
|
if (player->alive == ALIVE_ALIVE)
|
2015-12-19 09:56:52 +01:00
|
|
|
{
|
2016-03-27 12:21:23 +02:00
|
|
|
doSpawners();
|
2016-03-15 13:19:32 +01:00
|
|
|
|
2015-12-22 13:42:04 +01:00
|
|
|
doLocations();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-19 09:56:52 +01:00
|
|
|
doMessageBox();
|
2016-05-19 10:30:15 +02:00
|
|
|
|
|
|
|
if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE)
|
|
|
|
{
|
|
|
|
doScript();
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-22 13:42:04 +01:00
|
|
|
if (battle.status == MS_IN_PROGRESS)
|
2015-12-19 09:56:52 +01:00
|
|
|
{
|
2016-03-12 19:22:48 +01:00
|
|
|
if (battle.stats[STAT_TIME]++ % FPS == 0)
|
2016-02-27 13:14:29 +01:00
|
|
|
{
|
2016-03-27 12:21:23 +02:00
|
|
|
runScriptFunction("TIME %d", battle.stats[STAT_TIME] / FPS);
|
2016-04-03 15:04:56 +02:00
|
|
|
|
|
|
|
if (game.currentMission->challengeData.timeLimit && game.currentMission->challengeData.timeLimit - battle.stats[STAT_TIME] < 11 * FPS)
|
|
|
|
{
|
|
|
|
playSound(SND_TIME_WARNING);
|
|
|
|
}
|
2016-02-27 13:14:29 +01:00
|
|
|
}
|
2015-12-19 09:56:52 +01:00
|
|
|
}
|
2015-11-28 11:11:20 +01:00
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-22 13:42:04 +01:00
|
|
|
if (battle.status != MS_IN_PROGRESS)
|
2015-10-20 13:51:49 +02:00
|
|
|
{
|
|
|
|
battle.missionFinishedTimer--;
|
2016-05-15 09:19:26 +02:00
|
|
|
|
|
|
|
if (battle.unwinnable && battle.missionFinishedTimer <= -FPS * 6)
|
|
|
|
{
|
2016-07-29 10:17:29 +02:00
|
|
|
battle.status = MS_COMPLETE;
|
|
|
|
|
2016-05-15 09:19:26 +02:00
|
|
|
postBattle();
|
2016-01-25 15:58:07 +01:00
|
|
|
|
2016-05-15 09:19:26 +02:00
|
|
|
destroyBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-05-15 09:19:26 +02:00
|
|
|
initGalacticMap();
|
|
|
|
}
|
2016-01-25 15:58:07 +01:00
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void draw(void)
|
|
|
|
{
|
2016-05-15 09:19:26 +02:00
|
|
|
if (player->alive == ALIVE_ALIVE)
|
2015-11-01 17:11:56 +01:00
|
|
|
{
|
2018-12-14 09:00:16 +01:00
|
|
|
battle.camera.x = player->x - (app.winWidth / 2);
|
|
|
|
battle.camera.y = player->y - (app.winHeight / 2);
|
2015-11-01 17:11:56 +01:00
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
drawBackground(battle.background);
|
2018-12-06 17:52:13 +01:00
|
|
|
|
|
|
|
setAtlasColor(255, 255, 255, 255);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-07-22 12:07:35 +02:00
|
|
|
blitScaled(battle.planetTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight, 0);
|
|
|
|
|
2016-05-30 12:58:16 +02:00
|
|
|
if (battle.destroyTorelli)
|
|
|
|
{
|
|
|
|
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
|
2018-12-06 09:37:19 +01:00
|
|
|
SDL_SetTextureAlphaMod(battle.fireStormTexture->texture, battle.torelliFireStormAlpha);
|
2016-07-22 12:07:35 +02:00
|
|
|
blitScaled(battle.fireStormTexture, battle.planet.x, battle.planet.y, battle.planetWidth, battle.planetHeight, 0);
|
2016-05-30 12:58:16 +02:00
|
|
|
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-02-14 12:08:03 +01:00
|
|
|
drawStars();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-26 18:27:43 +01:00
|
|
|
drawEntities();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-07 20:19:41 +01:00
|
|
|
drawBullets();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-13 15:50:54 +01:00
|
|
|
drawDebris();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
drawEffects();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-22 13:42:04 +01:00
|
|
|
if (dev.debug)
|
|
|
|
{
|
|
|
|
drawLocations();
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
drawHud();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-05-15 09:19:26 +02:00
|
|
|
if (player->alive == ALIVE_ALIVE)
|
2015-12-19 09:56:52 +01:00
|
|
|
{
|
|
|
|
drawMessageBox();
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
drawMissionInfo();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
switch (show)
|
|
|
|
{
|
|
|
|
case SHOW_MENU:
|
|
|
|
drawMenu();
|
|
|
|
break;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
case SHOW_OPTIONS:
|
|
|
|
drawOptions();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawMenu(void)
|
|
|
|
{
|
|
|
|
SDL_Rect r;
|
2018-12-11 09:24:25 +01:00
|
|
|
|
|
|
|
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);
|
2018-12-17 09:30:47 +01:00
|
|
|
|
|
|
|
SDL_SetRenderTarget(app.renderer, app.uiBuffer);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2018-12-11 09:24:25 +01:00
|
|
|
r.w = 400;
|
|
|
|
r.h = 400;
|
2018-12-13 08:59:31 +01:00
|
|
|
r.x = (UI_WIDTH / 2) - r.w / 2;
|
|
|
|
r.y = (UI_HEIGHT / 2) - r.h / 2;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2018-12-11 09:24:25 +01:00
|
|
|
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);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2018-12-11 09:24:25 +01:00
|
|
|
drawWidgets("inBattle");
|
2018-12-13 08:59:31 +01:00
|
|
|
|
|
|
|
SDL_SetRenderTarget(app.renderer, app.backBuffer);
|
2018-12-11 09:24:25 +01:00
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handleKeyboard(void)
|
|
|
|
{
|
2016-08-29 13:50:57 +02:00
|
|
|
if (app.keyboard[SDL_SCANCODE_ESCAPE] && !app.awaitingWidgetInput && battle.status == MS_IN_PROGRESS)
|
2015-10-20 13:51:49 +02:00
|
|
|
{
|
|
|
|
switch (show)
|
|
|
|
{
|
|
|
|
case SHOW_BATTLE:
|
|
|
|
case SHOW_OPTIONS:
|
|
|
|
selectWidget("resume", "inBattle");
|
|
|
|
show = SHOW_MENU;
|
2016-08-11 23:47:51 +02:00
|
|
|
SDL_SetWindowGrab(app.window, 0);
|
2015-10-20 13:51:49 +02:00
|
|
|
break;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
case SHOW_MENU:
|
|
|
|
show = SHOW_BATTLE;
|
2016-08-11 23:47:51 +02:00
|
|
|
SDL_SetWindowGrab(app.window, 1);
|
2015-10-20 13:51:49 +02:00
|
|
|
break;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
case SHOW_OBJECTIVES:
|
|
|
|
show = SHOW_BATTLE;
|
2016-08-11 23:47:51 +02:00
|
|
|
SDL_SetWindowGrab(app.window, 1);
|
2015-10-20 13:51:49 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-05 16:34:37 +01:00
|
|
|
clearInput();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
playSound(SND_GUI_CLOSE);
|
|
|
|
}
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-05 16:34:37 +01:00
|
|
|
if (battle.status == MS_IN_PROGRESS && app.keyboard[SDL_SCANCODE_TAB])
|
2015-10-20 13:51:49 +02:00
|
|
|
{
|
|
|
|
battle.status = MS_PAUSED;
|
2016-04-16 12:07:26 +02:00
|
|
|
|
|
|
|
selectWidget("ok", "startBattle");
|
2016-08-11 23:47:51 +02:00
|
|
|
|
|
|
|
SDL_SetWindowGrab(app.window, 0);
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void start(void)
|
|
|
|
{
|
|
|
|
battle.status = MS_IN_PROGRESS;
|
2016-08-11 23:47:51 +02:00
|
|
|
|
|
|
|
SDL_SetWindowGrab(app.window, 1);
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void resume(void)
|
|
|
|
{
|
|
|
|
show = SHOW_BATTLE;
|
2016-08-11 23:47:51 +02:00
|
|
|
|
|
|
|
SDL_SetWindowGrab(app.window, 1);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-05 16:34:37 +01:00
|
|
|
clearInput();
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void continueGame(void)
|
|
|
|
{
|
|
|
|
postBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
destroyBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-02 07:46:13 +01:00
|
|
|
if (!game.currentMission->challengeData.isChallenge)
|
2016-02-27 17:16:21 +01:00
|
|
|
{
|
|
|
|
initGalacticMap();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
initChallengeHome();
|
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void options(void)
|
|
|
|
{
|
|
|
|
show = SHOW_OPTIONS;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
initOptions(returnFromOptions);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void returnFromOptions(void)
|
|
|
|
{
|
|
|
|
show = SHOW_MENU;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
selectWidget("resume", "inBattle");
|
|
|
|
}
|
|
|
|
|
2016-06-03 14:57:24 +02:00
|
|
|
static void ignoreRestartQuit(void)
|
|
|
|
{
|
|
|
|
app.modalDialog.type = MD_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void restart(void)
|
|
|
|
{
|
|
|
|
showOKCancelDialog(&retry, &ignoreRestartQuit, _("Are you sure you want to restart? You will lose your current progress."));
|
|
|
|
}
|
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
static void retry(void)
|
|
|
|
{
|
2016-06-03 14:57:24 +02:00
|
|
|
app.modalDialog.type = MD_NONE;
|
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
postBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
destroyBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
initBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
loadMission(game.currentMission->filename);
|
|
|
|
}
|
|
|
|
|
2016-06-03 14:57:24 +02:00
|
|
|
static void optQuitBattle(void)
|
|
|
|
{
|
|
|
|
showOKCancelDialog(&quitBattle, &ignoreRestartQuit, _("Are you sure you want to quit? You will lose your current progress."));
|
|
|
|
}
|
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
static void quitBattle(void)
|
|
|
|
{
|
2016-06-03 14:57:24 +02:00
|
|
|
app.modalDialog.type = MD_NONE;
|
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
postBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
destroyBattle();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-02 07:46:13 +01:00
|
|
|
if (!game.currentMission->challengeData.isChallenge)
|
2016-02-27 17:16:21 +01:00
|
|
|
{
|
|
|
|
initGalacticMap();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
initChallengeHome();
|
|
|
|
}
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void postBattle(void)
|
|
|
|
{
|
2015-10-25 01:01:46 +02:00
|
|
|
int i;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-17 08:23:50 +01:00
|
|
|
for (i = 0 ; i < STAT_MAX ; i++)
|
2015-10-25 01:01:46 +02:00
|
|
|
{
|
2015-11-17 08:23:50 +01:00
|
|
|
if (i != STAT_TIME && i != STAT_EPIC_KILL_STREAK)
|
|
|
|
{
|
|
|
|
game.stats[i] += battle.stats[i];
|
|
|
|
}
|
2015-10-25 01:01:46 +02:00
|
|
|
}
|
2016-05-15 09:19:26 +02:00
|
|
|
|
|
|
|
game.stats[STAT_EPIC_KILL_STREAK] = MAX(game.stats[STAT_EPIC_KILL_STREAK], battle.stats[STAT_EPIC_KILL_STREAK]);
|
2016-03-09 12:51:26 +01:00
|
|
|
|
2016-03-03 10:12:08 +01:00
|
|
|
updateAccuracyStats(game.stats);
|
2016-05-15 09:19:26 +02:00
|
|
|
|
2016-08-12 09:56:18 +02:00
|
|
|
game.currentMission->completed = (game.currentMission->completed || battle.status == MS_COMPLETE || !battle.numObjectivesTotal);
|
2016-05-15 09:19:26 +02:00
|
|
|
|
|
|
|
app.saveGame = 1;
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|
|
|
|
|
2016-05-20 11:51:35 +02:00
|
|
|
static void checkSuspicionLevel(void)
|
|
|
|
{
|
|
|
|
if (battle.hasSuspicionLevel && battle.suspicionLevel >= MAX_SUSPICION_LEVEL)
|
|
|
|
{
|
|
|
|
cancelScript();
|
|
|
|
|
|
|
|
resetMessageBox();
|
|
|
|
|
|
|
|
runScriptFunction("MAX_SUSPICION_LEVEL");
|
|
|
|
|
|
|
|
battle.hasSuspicionLevel = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 12:58:16 +02:00
|
|
|
static void doTorelliFireStorm(void)
|
|
|
|
{
|
|
|
|
if (battle.destroyTorelli)
|
|
|
|
{
|
|
|
|
battle.torelliFireStormAlpha = MIN(battle.torelliFireStormAlpha + 0.25, 255);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-01 10:55:28 +02:00
|
|
|
static void endCampaign(void)
|
2016-05-31 10:12:14 +02:00
|
|
|
{
|
|
|
|
awardTrophy("CAMPAIGN_COMPLETE");
|
|
|
|
|
|
|
|
postBattle();
|
|
|
|
|
|
|
|
destroyBattle();
|
|
|
|
|
|
|
|
initCredits();
|
|
|
|
}
|
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
void destroyBattle(void)
|
|
|
|
{
|
2015-10-26 18:27:43 +01:00
|
|
|
Entity *ent;
|
2015-10-20 13:51:49 +02:00
|
|
|
Bullet *b;
|
2015-12-13 15:50:54 +01:00
|
|
|
Debris *d;
|
2015-10-20 13:51:49 +02:00
|
|
|
Effect *e;
|
|
|
|
Objective *o;
|
2015-12-22 13:42:04 +01:00
|
|
|
Location *l;
|
2016-03-27 12:21:23 +02:00
|
|
|
Spawner *s;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-26 18:27:43 +01:00
|
|
|
while (battle.entityHead.next)
|
|
|
|
{
|
|
|
|
ent = battle.entityHead.next;
|
|
|
|
battle.entityHead.next = ent->next;
|
|
|
|
free(ent);
|
|
|
|
}
|
|
|
|
battle.entityTail = &battle.entityHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
while (battle.bulletHead.next)
|
|
|
|
{
|
|
|
|
b = battle.bulletHead.next;
|
|
|
|
battle.bulletHead.next = b->next;
|
|
|
|
free(b);
|
|
|
|
}
|
|
|
|
battle.bulletTail = &battle.bulletHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-13 15:50:54 +01:00
|
|
|
while (battle.debrisHead.next)
|
|
|
|
{
|
|
|
|
d = battle.debrisHead.next;
|
|
|
|
battle.debrisHead.next = d->next;
|
|
|
|
free(d);
|
|
|
|
}
|
|
|
|
battle.debrisTail = &battle.debrisHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
while (battle.effectHead.next)
|
|
|
|
{
|
|
|
|
e = battle.effectHead.next;
|
|
|
|
battle.effectHead.next = e->next;
|
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
battle.effectTail = &battle.effectHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-10-20 13:51:49 +02:00
|
|
|
while (battle.objectiveHead.next)
|
|
|
|
{
|
|
|
|
o = battle.objectiveHead.next;
|
|
|
|
battle.objectiveHead.next = o->next;
|
|
|
|
free(o);
|
|
|
|
}
|
|
|
|
battle.objectiveTail = &battle.objectiveHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-22 13:42:04 +01:00
|
|
|
while (battle.locationHead.next)
|
|
|
|
{
|
|
|
|
l = battle.locationHead.next;
|
|
|
|
battle.locationHead.next = l->next;
|
|
|
|
free(l);
|
|
|
|
}
|
|
|
|
battle.locationTail = &battle.locationHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-03-27 12:21:23 +02:00
|
|
|
while (battle.spawnerHead.next)
|
|
|
|
{
|
|
|
|
s = battle.spawnerHead.next;
|
|
|
|
battle.spawnerHead.next = s->next;
|
|
|
|
free(s);
|
|
|
|
}
|
|
|
|
battle.spawnerTail = &battle.spawnerHead;
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-28 11:11:20 +01:00
|
|
|
cJSON_Delete(battle.missionJSON);
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-28 11:11:20 +01:00
|
|
|
resetHud();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-28 11:11:20 +01:00
|
|
|
resetMessageBox();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-12-10 11:15:27 +01:00
|
|
|
destroyEntities();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2015-11-28 11:11:20 +01:00
|
|
|
destroyScript();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
2016-02-21 08:48:22 +01:00
|
|
|
destroyQuadtree();
|
2016-02-24 16:02:51 +01:00
|
|
|
|
|
|
|
destroyDebris();
|
|
|
|
|
|
|
|
destroyBullets();
|
|
|
|
|
|
|
|
destroyEffects();
|
2016-05-22 15:18:41 +02:00
|
|
|
|
|
|
|
memset(&battle, 0, sizeof(Battle));
|
2016-05-24 10:10:36 +02:00
|
|
|
battle.bulletTail = &battle.bulletHead;
|
|
|
|
battle.debrisTail = &battle.debrisHead;
|
|
|
|
battle.entityTail = &battle.entityHead;
|
|
|
|
battle.effectTail = &battle.effectHead;
|
|
|
|
battle.objectiveTail = &battle.objectiveHead;
|
|
|
|
battle.locationTail = &battle.locationHead;
|
|
|
|
battle.spawnerTail = &battle.spawnerHead;
|
2015-10-20 13:51:49 +02:00
|
|
|
}
|