2011-08-24 14:14:44 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2003 Parallel Realities
|
2015-03-01 21:37:32 +01:00
|
|
|
Copyright (C) 2011, 2012, 2013 Guus Sliepen
|
|
|
|
Copyright (C) 2012, 2014, 2015 Julian Marchant
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
as published by the Free Software Foundation; either version 3
|
2011-08-24 14:14:44 +02:00
|
|
|
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
|
2015-02-26 17:20:36 +01:00
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-08-24 14:14:44 +02:00
|
|
|
*/
|
|
|
|
|
2011-08-26 21:29:04 +02:00
|
|
|
#include "Starfighter.h"
|
|
|
|
|
|
|
|
Game currentGame;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
void newGame()
|
|
|
|
{
|
|
|
|
currentGame.system = 0;
|
|
|
|
currentGame.area = 0;
|
|
|
|
currentGame.sfxVolume = 0;
|
|
|
|
currentGame.musicVolume = 0;
|
|
|
|
|
|
|
|
if (!engine.useAudio)
|
|
|
|
{
|
2011-08-26 22:48:52 +02:00
|
|
|
engine.useSound = false;
|
|
|
|
engine.useMusic = false;
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
currentGame.cash = 0;
|
|
|
|
currentGame.cashEarned = 0;
|
|
|
|
currentGame.shots = 0;
|
|
|
|
currentGame.hits = 0;
|
|
|
|
currentGame.accuracy = 0;
|
|
|
|
currentGame.totalKills = currentGame.wingMate1Kills = currentGame.wingMate2Kills = 0;
|
|
|
|
currentGame.totalOtherKills = 0;
|
|
|
|
currentGame.hasWingMate1 = currentGame.hasWingMate2 = 0;
|
|
|
|
currentGame.wingMate1Ejects = currentGame.wingMate2Ejects = 0;
|
|
|
|
currentGame.secondaryMissions = currentGame.secondaryMissionsCompleted = 0;
|
|
|
|
currentGame.shieldPickups = currentGame.rocketPickups = currentGame.cellPickups = 0;
|
|
|
|
currentGame.powerups = currentGame.minesKilled = currentGame.cargoPickups = 0;
|
|
|
|
|
|
|
|
currentGame.slavesRescued = 0;
|
|
|
|
currentGame.experimentalShield = 1000;
|
|
|
|
|
|
|
|
currentGame.timeTaken = 0;
|
|
|
|
|
|
|
|
currentGame.stationedPlanet = -1;
|
|
|
|
currentGame.destinationPlanet = -1;
|
|
|
|
for (int i = 0 ; i < 10 ; i++)
|
|
|
|
currentGame.missionCompleted[i] = 0;
|
|
|
|
currentGame.distanceCovered = 0;
|
|
|
|
|
2011-09-11 21:57:57 +02:00
|
|
|
currentGame.minPlasmaRate = 1;
|
|
|
|
currentGame.minPlasmaOutput = 1;
|
|
|
|
currentGame.minPlasmaDamage = 1;
|
|
|
|
currentGame.maxPlasmaRate = 2;
|
2011-08-24 14:14:44 +02:00
|
|
|
currentGame.maxPlasmaOutput = 2;
|
|
|
|
currentGame.maxPlasmaDamage = 2;
|
|
|
|
currentGame.maxPlasmaAmmo = 100;
|
|
|
|
currentGame.maxRocketAmmo = 10;
|
|
|
|
|
2015-02-27 02:51:30 +01:00
|
|
|
switch (currentGame.difficulty)
|
2014-03-12 20:18:41 +01:00
|
|
|
{
|
2015-02-27 02:51:30 +01:00
|
|
|
case DIFFICULTY_EASY:
|
|
|
|
player.maxShield = 100;
|
2015-02-28 00:11:59 +01:00
|
|
|
currentGame.minPlasmaRate = 2;
|
|
|
|
currentGame.minPlasmaOutput = 2;
|
|
|
|
currentGame.minPlasmaDamage = 2;
|
|
|
|
currentGame.maxPlasmaRate = 3;
|
|
|
|
currentGame.maxPlasmaOutput = 3;
|
|
|
|
currentGame.maxPlasmaDamage = 3;
|
2015-02-27 02:51:30 +01:00
|
|
|
break;
|
|
|
|
case DIFFICULTY_HARD:
|
|
|
|
player.maxShield = 25;
|
|
|
|
break;
|
|
|
|
case DIFFICULTY_NIGHTMARE:
|
|
|
|
player.maxShield = 1;
|
2015-02-28 00:11:59 +01:00
|
|
|
currentGame.maxPlasmaRate = 1;
|
|
|
|
currentGame.maxPlasmaOutput = 1;
|
|
|
|
currentGame.maxPlasmaDamage = 1;
|
|
|
|
currentGame.maxRocketAmmo = 5;
|
2015-02-27 02:51:30 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
player.maxShield = 50;
|
2014-03-12 19:35:24 +01:00
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2015-02-27 02:51:30 +01:00
|
|
|
player.shield = player.maxShield;
|
2011-08-24 14:14:44 +02:00
|
|
|
player.ammo[0] = 0;
|
|
|
|
player.ammo[1] = 5;
|
|
|
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
|
|
|
player.weaponType[1] = W_ROCKETS;
|
|
|
|
|
|
|
|
initWeapons();
|
|
|
|
initMissions();
|
|
|
|
initPlanetMissions(currentGame.system);
|
|
|
|
}
|
|
|
|
|
|
|
|
int mainGameLoop()
|
|
|
|
{
|
|
|
|
resetLists();
|
|
|
|
|
|
|
|
setMission(currentGame.area);
|
|
|
|
missionBriefScreen();
|
|
|
|
|
|
|
|
initCargo();
|
|
|
|
initPlayer();
|
|
|
|
initAliens();
|
|
|
|
clearInfoLines();
|
|
|
|
|
|
|
|
loadScriptEvents();
|
|
|
|
|
|
|
|
engine.ssx = 0;
|
|
|
|
engine.ssy = 0;
|
2015-02-27 05:23:08 +01:00
|
|
|
engine.smx = 0;
|
|
|
|
engine.smy = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
engine.done = 0;
|
|
|
|
|
|
|
|
engine.counter = (SDL_GetTicks() + 1000);
|
|
|
|
engine.counter2 = (SDL_GetTicks() + 1000);
|
|
|
|
|
|
|
|
engine.missionCompleteTimer = 0;
|
|
|
|
engine.musicVolume = 100;
|
|
|
|
|
|
|
|
int rtn = 0;
|
|
|
|
|
|
|
|
int allowableAliens = 999999999;
|
|
|
|
|
|
|
|
for (int i = 0 ; i < 3 ; i++)
|
|
|
|
{
|
|
|
|
if ((currentMission.primaryType[i] == M_DESTROY_TARGET_TYPE) && (currentMission.target1[i] == CD_ANY))
|
|
|
|
allowableAliens = currentMission.targetValue1[i];
|
|
|
|
|
|
|
|
if (currentMission.primaryType[i] == M_DESTROY_ALL_TARGETS)
|
|
|
|
allowableAliens = 999999999;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0 ; i < MAX_ALIENS ; i++)
|
|
|
|
{
|
|
|
|
if ((enemy[i].active) && (enemy[i].flags & FL_WEAPCO))
|
|
|
|
{
|
|
|
|
allowableAliens--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
drawBackGround();
|
|
|
|
flushBuffer();
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
// Default to no aliens dead...
|
|
|
|
engine.allAliensDead = 0;
|
|
|
|
|
2013-09-30 16:52:43 +02:00
|
|
|
engine.keyState[KEY_FIRE] = engine.keyState[KEY_ALTFIRE] = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
flushInput();
|
|
|
|
|
|
|
|
while (engine.done != 1)
|
|
|
|
{
|
2011-08-26 23:53:46 +02:00
|
|
|
updateScreen();
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
if ((allMissionsCompleted()) && (engine.missionCompleteTimer == 0))
|
|
|
|
{
|
|
|
|
engine.missionCompleteTimer = SDL_GetTicks() + 4000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((missionFailed()) && (engine.missionCompleteTimer == 0))
|
|
|
|
{
|
|
|
|
if (currentGame.area != 5)
|
|
|
|
engine.missionCompleteTimer = SDL_GetTicks() + 4000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (engine.missionCompleteTimer != 0)
|
|
|
|
{
|
|
|
|
engine.gameSection = SECTION_INTERMISSION;
|
|
|
|
if (player.shield > 0)
|
|
|
|
{
|
|
|
|
if (SDL_GetTicks() >= engine.missionCompleteTimer)
|
|
|
|
{
|
|
|
|
if ((!missionFailed()) && (currentGame.area != 26))
|
|
|
|
{
|
|
|
|
leaveSector();
|
|
|
|
if ((engine.done == 2) && (currentGame.area != 10) && (currentGame.area != 15))
|
|
|
|
{
|
|
|
|
if ((enemy[FR_PHOEBE].shield > 0) && (currentGame.area != 25))
|
|
|
|
{
|
|
|
|
enemy[FR_PHOEBE].x = player.x - 40;
|
|
|
|
enemy[FR_PHOEBE].y = player.y - 35;
|
|
|
|
enemy[FR_PHOEBE].face = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((enemy[FR_URSULA].shield > 0) && (currentGame.area != 25))
|
|
|
|
{
|
|
|
|
enemy[FR_URSULA].x = player.x - 40;
|
|
|
|
enemy[FR_URSULA].y = player.y + 45;
|
|
|
|
enemy[FR_URSULA].face = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.area == 9) || (currentGame.area == 17))
|
|
|
|
{
|
|
|
|
enemy[FR_SID].x = player.x - 100;
|
|
|
|
enemy[FR_SID].y = player.y;
|
|
|
|
enemy[FR_SID].face = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((currentGame.area == 26) && (engine.musicVolume > 0))
|
|
|
|
{
|
2011-08-26 23:27:16 +02:00
|
|
|
limitFloat(&(engine.musicVolume -= 0.2), 0, 100);
|
2011-08-24 14:14:44 +02:00
|
|
|
Mix_VolumeMusic((int)engine.musicVolume);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
engine.done = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getPlayerInput();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-08-26 23:27:16 +02:00
|
|
|
limitFloat(&(engine.musicVolume -= 0.2), 0, 100);
|
2011-08-24 14:14:44 +02:00
|
|
|
Mix_VolumeMusic((int)engine.musicVolume);
|
|
|
|
if (SDL_GetTicks() >= engine.missionCompleteTimer)
|
|
|
|
{
|
|
|
|
engine.done = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getPlayerInput();
|
|
|
|
}
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
unBuffer();
|
2011-08-24 14:14:44 +02:00
|
|
|
doStarfield();
|
|
|
|
doCollectables();
|
|
|
|
doBullets();
|
|
|
|
doAliens();
|
|
|
|
doPlayer();
|
|
|
|
doCargo();
|
|
|
|
doDebris();
|
|
|
|
doExplosions();
|
|
|
|
doInfo();
|
|
|
|
|
2011-08-26 23:27:16 +02:00
|
|
|
wrapChar(&(--engine.eventTimer), 0, 60);
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2011-09-05 11:40:35 +02:00
|
|
|
if (engine.paused)
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2012-03-14 16:54:48 +01:00
|
|
|
textSurface(22, "PAUSED", -1, screen->h / 2, FONT_WHITE);
|
2011-09-05 11:40:35 +02:00
|
|
|
blitText(22);
|
|
|
|
updateScreen();
|
|
|
|
|
|
|
|
while (engine.paused)
|
|
|
|
{
|
|
|
|
engine.done = checkPauseRequest();
|
|
|
|
delayFrame();
|
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.area == 24) && (engine.addAliens > -1))
|
|
|
|
{
|
|
|
|
if ((rand() % 10) == 0)
|
2011-08-26 23:27:16 +02:00
|
|
|
addCollectable(rrand(800, 100), player.y, P_MINE, 25, 180 + rand() % 60);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (engine.addAliens > -1)
|
|
|
|
{
|
2011-08-26 23:27:16 +02:00
|
|
|
wrapInt(&(--engine.addAliens), 0, currentMission.addAliens);
|
2011-08-24 14:14:44 +02:00
|
|
|
if ((engine.addAliens == 0) && (allowableAliens > 0))
|
|
|
|
{
|
|
|
|
allowableAliens -= addAlien();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((player.shield <= 0) && (engine.missionCompleteTimer == 0))
|
|
|
|
engine.missionCompleteTimer = SDL_GetTicks() + 7000;
|
|
|
|
|
|
|
|
// specific to Boss 1
|
|
|
|
if ((currentGame.area == 5) && (enemy[WC_BOSS].flags & FL_ESCAPED))
|
|
|
|
{
|
2012-03-02 23:00:35 +01:00
|
|
|
playSound(SFX_DEATH, enemy[WC_BOSS].x);
|
2011-08-26 23:53:46 +02:00
|
|
|
clearScreen(white);
|
|
|
|
updateScreen();
|
2011-08-24 14:14:44 +02:00
|
|
|
for (int i = 0 ; i < 300 ; i++)
|
|
|
|
{
|
|
|
|
SDL_Delay(10);
|
|
|
|
if ((rand() % 25) == 0)
|
2012-03-02 23:00:35 +01:00
|
|
|
playSound(SFX_EXPLOSION, enemy[WC_BOSS].x);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
SDL_Delay(1000);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
delayFrame();
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
flushBuffer();
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
if ((player.shield > 0) && (!missionFailed()))
|
|
|
|
{
|
|
|
|
if (currentGame.area < 26)
|
|
|
|
missionFinishedScreen();
|
|
|
|
|
|
|
|
switch (currentGame.area)
|
|
|
|
{
|
|
|
|
case 5:
|
|
|
|
doCutscene(1);
|
|
|
|
doCutscene(2);
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
doCutscene(3);
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
doCutscene(4);
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
doCutscene(5);
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
doCutscene(6);
|
|
|
|
break;
|
|
|
|
case 26:
|
2015-02-27 23:59:25 +01:00
|
|
|
doCredits(true);
|
2011-08-24 14:14:44 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentGame.area < 26)
|
|
|
|
{
|
|
|
|
updateSystemStatus();
|
|
|
|
|
2015-03-03 05:32:48 +01:00
|
|
|
saveGame(0);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
rtn = 1;
|
|
|
|
|
|
|
|
if (currentGame.area == 26)
|
|
|
|
rtn = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gameover();
|
|
|
|
rtn = 0;
|
|
|
|
}
|
|
|
|
|
2011-08-29 09:10:50 +02:00
|
|
|
exitPlayer();
|
|
|
|
|
2011-08-24 14:14:44 +02:00
|
|
|
return rtn;
|
|
|
|
}
|