tbftss/src/battle/battle.c

376 lines
6.7 KiB
C
Raw Normal View History

2015-10-20 13:51:49 +02:00
/*
Copyright (C) 2015 Parallel Realities
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);
static void quitBattle(void);
static void drawMenu(void);
static void continueGame(void);
static void resume(void);
static void retry(void);
static void start(void);
static void options(void);
static void returnFromOptions(void);
static int show;
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-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-10-26 09:10:13 +01:00
battle.triggerTail = &battle.triggerHead;
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);
initStars();
initBackground();
initHud();
initRadar();
2015-10-20 13:51:49 +02:00
initMissionInfo();
resetWaypoints();
2015-10-20 13:51:49 +02:00
show = SHOW_BATTLE;
getWidget("ok", "startBattle")->action = start;
getWidget("resume", "inBattle")->action = resume;
getWidget("options", "inBattle")->action = options;
getWidget("restart", "inBattle")->action = retry;
getWidget("quit", "inBattle")->action = quitBattle;
getWidget("continue", "battleWon")->action = continueGame;
getWidget("retry", "battleWon")->action = retry;
getWidget("retry", "battleLost")->action = retry;
getWidget("quit", "battleLost")->action = quitBattle;
selectWidget("ok", "startBattle");
}
static void logic(void)
{
if (battle.status == MS_IN_PROGRESS || battle.status == MS_COMPLETE || battle.status == MS_FAILED)
{
handleKeyboard();
if (show == SHOW_BATTLE)
{
if (!battle.epic || (battle.epic && !battle.playerSelect))
{
doBattle();
}
else if (battle.epic && battle.playerSelect)
{
doPlayerSelect();
}
2015-10-20 13:51:49 +02:00
}
}
doWidgets();
}
static void doBattle(void)
{
if (player != NULL)
{
ssx = player->dx;
ssy = player->dy;
2015-10-20 13:51:49 +02:00
}
else
{
ssx = ssy = 0;
2015-10-20 13:51:49 +02:00
}
scrollBackground(-ssx * 0.1, -ssy * 0.1);
doHud();
doObjectives();
2015-10-20 13:51:49 +02:00
doStars(ssx, ssy);
2015-10-20 13:51:49 +02:00
doBullets();
2015-10-26 18:27:43 +01:00
doEntities();
2015-10-20 13:51:49 +02:00
doEffects();
doPlayer();
if (battle.status != MS_IN_PROGRESS)
{
battle.missionFinishedTimer--;
}
2015-10-26 09:10:13 +01:00
battle.stats[STAT_TIME]++;
if (battle.stats[STAT_TIME] % FPS == 0)
{
checkTrigger("TIME", TRIGGER_TIME);
}
2015-10-20 13:51:49 +02:00
}
static void draw(void)
{
prepareScene();
if (player != NULL)
{
battle.camera.x = player->x - (SCREEN_WIDTH / 2);
battle.camera.y = player->y - (SCREEN_HEIGHT / 2);
}
2015-10-20 13:51:49 +02:00
drawBackground(battle.background);
drawStars();
blit(battle.planetTexture, battle.planet.x - battle.camera.x, battle.planet.y - battle.camera.y, 1);
2015-10-20 13:51:49 +02:00
drawBullets();
2015-10-26 18:27:43 +01:00
drawEntities();
2015-10-20 13:51:49 +02:00
drawEffects();
drawHud();
drawMissionInfo();
switch (show)
{
case SHOW_MENU:
drawMenu();
break;
case SHOW_OPTIONS:
drawOptions();
break;
}
presentScene();
}
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);
r.w = 400;
r.h = 400;
r.x = (SCREEN_WIDTH / 2) - r.w / 2;
r.y = (SCREEN_HEIGHT / 2) - r.h / 2;
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0);
SDL_RenderFillRect(app.renderer, &r);
SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255);
SDL_RenderDrawRect(app.renderer, &r);
drawWidgets("inBattle");
}
static void handleKeyboard(void)
{
if (app.keyboard[SDL_SCANCODE_ESCAPE])
{
switch (show)
{
case SHOW_BATTLE:
case SHOW_OPTIONS:
selectWidget("resume", "inBattle");
show = SHOW_MENU;
break;
case SHOW_MENU:
show = SHOW_BATTLE;
break;
case SHOW_OBJECTIVES:
show = SHOW_BATTLE;
break;
}
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
playSound(SND_GUI_CLOSE);
}
if (app.keyboard[SDL_SCANCODE_TAB])
{
battle.status = MS_PAUSED;
}
#if DEBUG
if (app.keyboard[SDL_SCANCODE_F10])
{
completeMission();
battle.missionFinishedTimer = -FPS;
}
#endif
2015-10-20 13:51:49 +02:00
}
static void start(void)
{
battle.status = MS_IN_PROGRESS;
}
static void resume(void)
{
show = SHOW_BATTLE;
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
}
static void continueGame(void)
{
postBattle();
destroyBattle();
resetHud();
initGalacticMap();
}
static void options(void)
{
show = SHOW_OPTIONS;
initOptions(returnFromOptions);
}
static void returnFromOptions(void)
{
show = SHOW_MENU;
selectWidget("resume", "inBattle");
}
static void retry(void)
{
postBattle();
destroyBattle();
resetHud();
initBattle();
loadMission(game.currentMission->filename);
}
static void quitBattle(void)
{
postBattle();
destroyBattle();
resetHud();
initGalacticMap();
}
static void postBattle(void)
{
int i;
2015-10-26 09:10:13 +01:00
/* we don't want to count the time when adding up stats */
for (i = 0 ; i < STAT_TIME ; i++)
{
game.stats[i] += battle.stats[i];
}
2015-10-20 13:51:49 +02:00
if (game.currentMission && !game.currentMission->completed)
{
game.currentMission->completed = (battle.status == MS_COMPLETE || !battle.numObjectivesTotal);
}
}
void destroyBattle(void)
{
2015-10-26 18:27:43 +01:00
Entity *ent;
2015-10-20 13:51:49 +02:00
Bullet *b;
Effect *e;
Objective *o;
2015-10-26 09:10:13 +01:00
Trigger *t;
2015-10-20 13:51:49 +02: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;
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;
while (battle.effectHead.next)
{
e = battle.effectHead.next;
battle.effectHead.next = e->next;
free(e);
}
battle.effectTail = &battle.effectHead;
while (battle.objectiveHead.next)
{
o = battle.objectiveHead.next;
battle.objectiveHead.next = o->next;
free(o);
}
battle.objectiveTail = &battle.objectiveHead;
2015-10-26 09:10:13 +01:00
while (battle.triggerHead.next)
{
t = battle.triggerHead.next;
battle.triggerHead.next = t->next;
free(t);
}
battle.triggerTail = &battle.triggerHead;
2015-11-01 23:19:39 +01:00
destroyGrid();
2015-10-20 13:51:49 +02:00
}