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;
|
2015-03-29 19:11:12 +02:00
|
|
|
currentGame.area = MISN_START;
|
2011-08-24 14:14:44 +02:00
|
|
|
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-03-06 18:36:02 +01:00
|
|
|
currentGame.minPlasmaRateLimit = 2;
|
2015-03-06 22:25:12 +01:00
|
|
|
currentGame.minPlasmaDamageLimit = 2;
|
|
|
|
currentGame.minPlasmaOutputLimit = 2;
|
|
|
|
currentGame.maxPlasmaRateLimit = 3;
|
|
|
|
currentGame.maxPlasmaDamageLimit = 3;
|
2015-03-06 18:36:02 +01:00
|
|
|
currentGame.maxPlasmaOutputLimit = 3;
|
|
|
|
currentGame.maxPlasmaAmmoLimit = 250;
|
|
|
|
currentGame.maxRocketAmmoLimit = 50;
|
|
|
|
|
2015-03-20 18:05:14 +01:00
|
|
|
player.maxShield = 50;
|
|
|
|
|
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-03-06 18:36:02 +01:00
|
|
|
|
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;
|
Several adjustments for difficulty purposes.
Started out adjusting prices, then ended up doing other things
while testing. Committing this now before I start doing other
random stuff!
But all of the changes are related to balancing difficulty, mostly
with prices, except for a couple bugfixes in the shop. Most notably:
* Ammo now costs $10, not $50. You no longer have to worry about
saving ammo quite as much as a result.
* Plasma upgrades' cost is now calculated differently, and the result
is slightly lower prices than before.
* Easy mode now grants the player more max ammo than other difficulties.
* Increasing max plasma ammo now costs less at the start, and increases
in cost faster.
* You increase max plasma ammo by 25 at a time, not 10. (10 was just too
small of a number.)
* Destroying enemy ships no longer gives you money. I found that, even
in hard mode, I had *way* too much money coming in, and this cuts it
down substantially. It also makes the shield bonus at the end of missions
much more significant. To compensate for the loss of massive bonuses
bosses used to give, these bosses now drop a lot more stuff.
* Kline has decreased health in his first encounter, and increased health
in his last two encounters (the numbers have been reversed).
2015-03-07 18:19:35 +01:00
|
|
|
currentGame.maxPlasmaAmmo = 150;
|
|
|
|
currentGame.maxRocketAmmo = 20;
|
2015-03-06 18:36:02 +01:00
|
|
|
|
|
|
|
currentGame.minPlasmaRateLimit = 3;
|
|
|
|
currentGame.minPlasmaDamageLimit = 3;
|
|
|
|
currentGame.minPlasmaOutputLimit = 3;
|
|
|
|
currentGame.maxPlasmaRateLimit = 5;
|
|
|
|
currentGame.maxPlasmaDamageLimit = 5;
|
|
|
|
currentGame.maxPlasmaOutputLimit = 5;
|
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.maxRocketAmmo = 5;
|
2015-02-27 02:51:30 +01:00
|
|
|
break;
|
2015-03-28 14:51:49 +01:00
|
|
|
case DIFFICULTY_ORIGINAL:
|
|
|
|
player.maxShield = 25;
|
|
|
|
|
|
|
|
currentGame.minPlasmaRateLimit = 3;
|
|
|
|
currentGame.minPlasmaDamageLimit = 3;
|
|
|
|
currentGame.minPlasmaOutputLimit = 3;
|
|
|
|
currentGame.maxPlasmaRateLimit = 5;
|
|
|
|
currentGame.maxPlasmaDamageLimit = 5;
|
|
|
|
currentGame.maxPlasmaOutputLimit = 5;
|
|
|
|
break;
|
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;
|
Several adjustments for difficulty purposes.
Started out adjusting prices, then ended up doing other things
while testing. Committing this now before I start doing other
random stuff!
But all of the changes are related to balancing difficulty, mostly
with prices, except for a couple bugfixes in the shop. Most notably:
* Ammo now costs $10, not $50. You no longer have to worry about
saving ammo quite as much as a result.
* Plasma upgrades' cost is now calculated differently, and the result
is slightly lower prices than before.
* Easy mode now grants the player more max ammo than other difficulties.
* Increasing max plasma ammo now costs less at the start, and increases
in cost faster.
* You increase max plasma ammo by 25 at a time, not 10. (10 was just too
small of a number.)
* Destroying enemy ships no longer gives you money. I found that, even
in hard mode, I had *way* too much money coming in, and this cuts it
down substantially. It also makes the shield bonus at the end of missions
much more significant. To compensate for the loss of massive bonuses
bosses used to give, these bosses now drop a lot more stuff.
* Kline has decreased health in his first encounter, and increased health
in his last two encounters (the numbers have been reversed).
2015-03-07 18:19:35 +01:00
|
|
|
player.ammo[1] = currentGame.maxRocketAmmo / 2;
|
2011-08-24 14:14:44 +02:00
|
|
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
|
|
|
player.weaponType[1] = W_ROCKETS;
|
|
|
|
|
|
|
|
initWeapons();
|
|
|
|
initMissions();
|
|
|
|
initPlanetMissions(currentGame.system);
|
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
static void game_addDebris(int x, int y, int amount)
|
|
|
|
{
|
|
|
|
if ((rand() % 2) == 0)
|
|
|
|
audio_playSound(SFX_DEBRIS, x);
|
|
|
|
else
|
|
|
|
audio_playSound(SFX_DEBRIS2, x);
|
|
|
|
|
|
|
|
object *debris;
|
|
|
|
|
2015-04-14 23:15:06 +02:00
|
|
|
amount = RANDRANGE(3, amount);
|
2015-04-08 01:16:46 +02:00
|
|
|
LIMIT(amount, 3, 8);
|
|
|
|
|
|
|
|
for (int i = 0 ; i < amount ; i++)
|
|
|
|
{
|
|
|
|
debris = new object;
|
|
|
|
|
|
|
|
debris->next = NULL;
|
|
|
|
debris->x = x;
|
|
|
|
debris->y = y;
|
|
|
|
|
|
|
|
debris->thinktime = RANDRANGE(60, 180);
|
|
|
|
|
|
|
|
debris->dx = RANDRANGE(-500, 500);
|
|
|
|
debris->dy = RANDRANGE(-500, 500);
|
|
|
|
|
|
|
|
if (debris->dx != 0)
|
|
|
|
debris->dx /= 100;
|
|
|
|
|
|
|
|
if (debris->dy != 0)
|
|
|
|
debris->dy /= 100;
|
|
|
|
|
|
|
|
engine.debrisTail->next = debris;
|
|
|
|
engine.debrisTail = debris;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Loops through the currently active collectables (in a linked list). The collectable
|
|
|
|
will travel in the direction that was defined when it was made. Its life will decreased
|
|
|
|
whilst it remains active. It will be removed if the player touches it or if its life
|
|
|
|
reaches 0. When it is picked up, depending on the type of collectable it is, mission requirements
|
|
|
|
will be updated. Information will be displayed and appropriate player variables altered.
|
|
|
|
*/
|
|
|
|
static void game_doCollectables()
|
|
|
|
{
|
|
|
|
collectables *collectable = engine.collectableHead;
|
|
|
|
collectables *prevCollectable = engine.collectableHead;
|
|
|
|
engine.collectableTail = engine.collectableHead;
|
|
|
|
char temp[40];
|
|
|
|
|
|
|
|
while (collectable->next != NULL)
|
|
|
|
{
|
|
|
|
collectable = collectable->next;
|
|
|
|
|
|
|
|
if (collectable->active)
|
|
|
|
{
|
|
|
|
if ((collectable->x + collectable->image->w > 0) &&
|
|
|
|
(collectable->x < screen->w) &&
|
|
|
|
(collectable->y + collectable->image->h > 0) &&
|
|
|
|
(collectable->y < screen->h))
|
|
|
|
blit(collectable->image, (int)collectable->x, (int)collectable->y);
|
|
|
|
|
|
|
|
collectable->x += engine.ssx + engine.smx;
|
|
|
|
collectable->y += engine.ssy + engine.smy;
|
|
|
|
collectable->x += collectable->dx;
|
|
|
|
collectable->y += collectable->dy;
|
|
|
|
|
|
|
|
collectable->life--;
|
|
|
|
|
|
|
|
if ((player.shield > 0) && (collision(collectable, &player)))
|
|
|
|
{
|
|
|
|
switch(collectable->type)
|
|
|
|
{
|
|
|
|
case P_CASH:
|
|
|
|
currentGame.cash += collectable->value;
|
|
|
|
currentGame.cashEarned += collectable->value;
|
|
|
|
sprintf(temp, "Got $%d ", collectable->value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_ROCKET:
|
|
|
|
LIMIT_ADD(player.ammo[1], collectable->value, 0,
|
|
|
|
currentGame.maxRocketAmmo);
|
|
|
|
if (player.ammo[1] == currentGame.maxRocketAmmo)
|
|
|
|
sprintf(temp, "Rocket Ammo at Maximum");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (collectable->value > 1)
|
|
|
|
sprintf(temp, "Got %d rockets", collectable->value);
|
|
|
|
else
|
|
|
|
sprintf(temp, "Got a rocket");
|
|
|
|
}
|
|
|
|
currentGame.rocketPickups += collectable->value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_SHIELD:
|
|
|
|
LIMIT_ADD(player.shield, 10, 0, player.maxShield);
|
|
|
|
currentGame.shieldPickups ++;
|
|
|
|
sprintf(temp, "Restored 10 shield points");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_PLASMA_RATE:
|
|
|
|
currentGame.powerups++;
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL) ||
|
|
|
|
(player.ammo[0] > 0))
|
|
|
|
{
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL))
|
|
|
|
LIMIT_ADD(player.ammo[0], collectable->value,
|
|
|
|
0, currentGame.maxPlasmaAmmo);
|
|
|
|
|
|
|
|
if (weapon[W_PLAYER_WEAPON].reload[0] <= rate2reload[currentGame.maxPlasmaRate])
|
|
|
|
sprintf(temp, "Firing rate already at maximum");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
weapon[W_PLAYER_WEAPON].reload[0] -= 2;
|
|
|
|
sprintf(temp, "Firing rate increased");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(temp, "Upgrade failed (no plasma ammo)");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_PLASMA_SHOT:
|
|
|
|
currentGame.powerups++;
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL) ||
|
|
|
|
(player.ammo[0] > 0))
|
|
|
|
{
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL))
|
|
|
|
LIMIT_ADD(player.ammo[0], collectable->value,
|
|
|
|
0, currentGame.maxPlasmaAmmo);
|
|
|
|
|
|
|
|
if (weapon[W_PLAYER_WEAPON].ammo[0] >= currentGame.maxPlasmaOutput)
|
|
|
|
sprintf(temp, "Plasma output already at maximum");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
weapon[W_PLAYER_WEAPON].ammo[0]++;
|
|
|
|
sprintf(temp, "Plasma output increased");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(temp, "Upgrade failed (no plasma ammo)");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_PLASMA_DAMAGE:
|
|
|
|
currentGame.powerups++;
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL) ||
|
|
|
|
(player.ammo[0] > 0))
|
|
|
|
{
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL))
|
|
|
|
LIMIT_ADD(player.ammo[0], collectable->value,
|
|
|
|
0, currentGame.maxPlasmaAmmo);
|
|
|
|
|
|
|
|
if (weapon[W_PLAYER_WEAPON].damage >= currentGame.maxPlasmaDamage)
|
|
|
|
sprintf(temp, "Plasma damage already at maximum");
|
2015-04-09 02:26:59 +02:00
|
|
|
else {
|
2015-04-08 01:16:46 +02:00
|
|
|
weapon[W_PLAYER_WEAPON].damage++;
|
|
|
|
sprintf(temp, "Plasma damage increased");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(temp, "Upgrade failed (no plasma ammo)");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_SUPER:
|
|
|
|
currentGame.powerups++;
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL) ||
|
|
|
|
(player.ammo[0] > 0))
|
|
|
|
{
|
|
|
|
if ((currentGame.area != MISN_INTERCEPTION) ||
|
|
|
|
(currentGame.difficulty == DIFFICULTY_ORIGINAL))
|
|
|
|
LIMIT_ADD(player.ammo[0], collectable->value,
|
|
|
|
0, currentGame.maxPlasmaAmmo);
|
|
|
|
|
|
|
|
weapon[W_PLAYER_WEAPON].ammo[0] = 5;
|
|
|
|
weapon[W_PLAYER_WEAPON].damage = 5;
|
|
|
|
weapon[W_PLAYER_WEAPON].reload[0] = rate2reload[5];
|
|
|
|
weapon[W_PLAYER_WEAPON].flags |= WF_SPREAD;
|
|
|
|
|
|
|
|
sprintf(temp, "Picked up a Super Charge!!");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(temp, "Damn! Upgrade failed (no plasma ammo)");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_PLASMA_AMMO:
|
|
|
|
if (player.ammo[0] >= currentGame.maxPlasmaAmmo)
|
|
|
|
sprintf(temp, "Plasma cells already at Maximum");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LIMIT_ADD(player.ammo[0], collectable->value,
|
|
|
|
0, currentGame.maxPlasmaAmmo);
|
|
|
|
if (collectable->value > 1)
|
|
|
|
{
|
|
|
|
sprintf(temp, "Got %d plasma cells", collectable->value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(temp, "Got a plasma cell");
|
|
|
|
if ((rand() % 25) == 0)
|
|
|
|
sprintf(temp, "Got one whole plasma cell (wahoo!)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
currentGame.cellPickups += collectable->value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_CARGO:
|
|
|
|
strcpy(temp, "Picked up some Cargo");
|
|
|
|
currentGame.cargoPickups++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_SLAVES:
|
|
|
|
sprintf(temp, "Rescued %d slaves", collectable->value);
|
|
|
|
currentGame.slavesRescued += collectable->value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_ESCAPEPOD:
|
|
|
|
sprintf(temp, "Picked up an Escape Pod");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case P_ORE:
|
|
|
|
sprintf(temp, "Picked up some Ore");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateMissionRequirements(M_COLLECT, collectable->type,
|
|
|
|
collectable->value);
|
|
|
|
|
|
|
|
collectable->active = false;
|
|
|
|
if (collectable->type != P_MINE)
|
|
|
|
{
|
|
|
|
setInfoLine(temp, FONT_WHITE);
|
|
|
|
if (collectable->type == P_SHIELD)
|
|
|
|
audio_playSound(SFX_SHIELDUP, player.x);
|
|
|
|
else
|
|
|
|
audio_playSound(SFX_PICKUP, player.x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// stop people from exploiting a weapon check condition
|
|
|
|
if (player.ammo[0] == 0)
|
|
|
|
{
|
|
|
|
weapon[W_PLAYER_WEAPON].ammo[0] = currentGame.minPlasmaOutput;
|
|
|
|
weapon[W_PLAYER_WEAPON].damage = currentGame.minPlasmaDamage;
|
|
|
|
weapon[W_PLAYER_WEAPON].reload[0] = rate2reload[currentGame.minPlasmaRate];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (collectable->life < 1)
|
|
|
|
{
|
|
|
|
collectable->active = false;
|
|
|
|
if ((collectable->type == P_CARGO) ||
|
|
|
|
(collectable->type == P_ESCAPEPOD) ||
|
|
|
|
(collectable->type == P_SLAVES))
|
|
|
|
updateMissionRequirements(M_PROTECT_PICKUP, collectable->type, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (collectable->active)
|
|
|
|
{
|
|
|
|
prevCollectable = collectable;
|
|
|
|
engine.collectableTail = collectable;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (collectable->type == P_MINE)
|
2015-04-24 22:27:07 +02:00
|
|
|
collectable_explode(collectable);
|
2015-04-08 01:16:46 +02:00
|
|
|
prevCollectable->next = collectable->next;
|
|
|
|
delete collectable;
|
|
|
|
collectable = prevCollectable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-07 22:09:17 +02:00
|
|
|
/*
|
|
|
|
This handles active bullets in a linked list. The current bullet and
|
|
|
|
previous bullet pointers are first assigned to the main header bullet
|
|
|
|
and each successive bullet is pulled out. Bullets are moved in their
|
|
|
|
delta coordinates, with rockets having fire trails added to them. Seperate
|
|
|
|
collision checks are done for a bullet that belongs to the enemy and one
|
|
|
|
that belongs to a player. However rockets can hit anyone. Upon an enemy
|
|
|
|
being killed, mission requirements are checked and collectables are randomly
|
|
|
|
spawned.
|
|
|
|
*/
|
|
|
|
static void game_doBullets()
|
|
|
|
{
|
|
|
|
object *bullet = engine.bulletHead;
|
|
|
|
object *prevBullet = engine.bulletHead;
|
|
|
|
|
2015-04-24 22:37:55 +02:00
|
|
|
collectables *collectable;
|
|
|
|
collectables *prevCollectable;
|
2015-04-07 22:09:17 +02:00
|
|
|
|
|
|
|
bool okayToHit = false;
|
|
|
|
int old_shield;
|
|
|
|
float homingMissileSpeed = 0;
|
|
|
|
|
2015-04-24 22:37:55 +02:00
|
|
|
bullet = engine.bulletHead;
|
|
|
|
prevBullet = engine.bulletHead;
|
2015-04-24 22:27:07 +02:00
|
|
|
engine.bulletTail = engine.bulletHead;
|
|
|
|
|
2015-04-07 22:09:17 +02:00
|
|
|
while (bullet->next != NULL)
|
|
|
|
{
|
|
|
|
bullet = bullet->next;
|
|
|
|
|
|
|
|
if (bullet->active)
|
|
|
|
{
|
|
|
|
if (bullet->flags & WF_HOMING)
|
|
|
|
{
|
|
|
|
if (bullet->target == NULL)
|
|
|
|
bullet->target = bullet_getTarget(bullet);
|
|
|
|
|
|
|
|
if (bullet->owner->flags & FL_FRIEND)
|
|
|
|
homingMissileSpeed = 0.25;
|
|
|
|
else
|
|
|
|
homingMissileSpeed = 0.05;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->id == WT_ROCKET)
|
|
|
|
{
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
else if (bullet->id == WT_MICROROCKET)
|
|
|
|
{
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_TINY_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((bullet->flags & WF_AIMED))
|
|
|
|
{
|
|
|
|
blit(bullet->image[0], (int)(bullet->x - bullet->dx),
|
|
|
|
(int)(bullet->y - bullet->dy));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->id == WT_CHARGER)
|
|
|
|
{
|
|
|
|
for (int i = 0 ; i < bullet->damage * 2 ; i++)
|
|
|
|
blit(bullet->image[0],
|
|
|
|
(int)(bullet->x - RANDRANGE(-(bullet->damage * 2 / 3), 0)),
|
|
|
|
(int)(bullet->y + RANDRANGE(-3, 3)));
|
|
|
|
}
|
|
|
|
|
|
|
|
blit(bullet->image[0], (int)bullet->x, (int)bullet->y);
|
|
|
|
bullet->x += bullet->dx;
|
|
|
|
bullet->y += bullet->dy;
|
|
|
|
|
|
|
|
if (bullet->target != NULL)
|
|
|
|
{
|
|
|
|
if (bullet->x < bullet->target->x)
|
|
|
|
LIMIT_ADD(bullet->dx, homingMissileSpeed, -15, 15);
|
|
|
|
else if (bullet->x > bullet->target->x)
|
|
|
|
LIMIT_ADD(bullet->dx, -homingMissileSpeed, -15, 15);
|
|
|
|
|
|
|
|
//Rocket is (more or less) inline with target. Fly straight
|
|
|
|
if ((bullet->x > bullet->target->x - 1) && (bullet->x < bullet->target->x + 5))
|
|
|
|
bullet->dx = 0;
|
|
|
|
|
|
|
|
if (bullet->y < bullet->target->y)
|
|
|
|
LIMIT_ADD(bullet->dy, homingMissileSpeed, -15, 15);
|
|
|
|
else if (bullet->y > bullet->target->y)
|
|
|
|
LIMIT_ADD(bullet->dy, -homingMissileSpeed, -15, 15);
|
|
|
|
|
|
|
|
//Rocket is (more or less) inline with target. Fly straight
|
|
|
|
if ((bullet->y > bullet->target->y - 1) && (bullet->y < bullet->target->y + 5))
|
|
|
|
bullet->dy = 0;
|
|
|
|
|
|
|
|
if ((bullet->target->shield < 1) || (bullet->target->flags & FL_ISCLOAKED))
|
|
|
|
bullet->target = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bullet->x += engine.ssx + engine.smx;
|
|
|
|
bullet->y += engine.ssy + engine.smy;
|
|
|
|
|
|
|
|
for (int i = 0 ; i < ALIEN_MAX ; i++)
|
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
if ((aliens[i].shield < 1) || (!aliens[i].active))
|
2015-04-07 22:09:17 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
okayToHit = false;
|
|
|
|
|
2015-04-24 22:27:07 +02:00
|
|
|
if ((bullet->flags & WF_FRIEND) && (aliens[i].flags & FL_WEAPCO))
|
2015-04-07 22:09:17 +02:00
|
|
|
okayToHit = true;
|
2015-04-24 22:27:07 +02:00
|
|
|
if ((bullet->flags & WF_WEAPCO) && (aliens[i].flags & FL_FRIEND))
|
2015-04-07 22:09:17 +02:00
|
|
|
okayToHit = true;
|
|
|
|
if ((bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) ||
|
|
|
|
(bullet->id == WT_CHARGER))
|
|
|
|
okayToHit = true;
|
|
|
|
|
2015-04-24 22:27:07 +02:00
|
|
|
if (bullet->owner == aliens[i].owner)
|
2015-04-07 22:09:17 +02:00
|
|
|
okayToHit = false;
|
|
|
|
|
|
|
|
if (okayToHit)
|
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
if ((bullet->active) && (collision(bullet, &aliens[i])))
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
old_shield = aliens[i].shield;
|
2015-04-07 22:09:17 +02:00
|
|
|
|
|
|
|
if (bullet->owner == &player)
|
|
|
|
{
|
|
|
|
currentGame.hits++;
|
2015-04-24 22:27:07 +02:00
|
|
|
if ((aliens[i].classDef == CD_PHOEBE) ||
|
|
|
|
(aliens[i].classDef == CD_URSULA))
|
|
|
|
getMissFireMessage(&aliens[i]);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
|
2015-04-24 22:27:07 +02:00
|
|
|
if (!(aliens[i].flags & FL_IMMORTAL))
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
alien_hurt(&aliens[i], bullet->owner,
|
|
|
|
bullet->damage, (bullet->flags & WF_DISABLE));
|
2015-04-07 22:09:17 +02:00
|
|
|
|
2015-04-24 22:27:07 +02:00
|
|
|
aliens[i].hit = 5;
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->id == WT_CHARGER)
|
|
|
|
{
|
|
|
|
bullet->damage -= old_shield;
|
|
|
|
if (bullet->damage <= 0)
|
|
|
|
{
|
|
|
|
bullet->active = false;
|
|
|
|
bullet->shield = 0;
|
|
|
|
audio_playSound(SFX_EXPLOSION, bullet->x);
|
|
|
|
for (int i = 0 ; i < 10 ; i++)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x + RANDRANGE(-35, 35),
|
2015-04-07 22:09:17 +02:00
|
|
|
bullet->y + RANDRANGE(-35, 35),
|
|
|
|
E_BIG_EXPLOSION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bullet->active = false;
|
|
|
|
bullet->shield = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->id == WT_ROCKET)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_BIG_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
else
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for bullets hitting player
|
|
|
|
if ((bullet->flags & WF_WEAPCO) || (bullet->id == WT_ROCKET) ||
|
|
|
|
(bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
|
|
|
|
{
|
|
|
|
if (bullet->active && (player.shield > 0) &&
|
|
|
|
(bullet->owner != &player) && collision(bullet, &player))
|
|
|
|
{
|
|
|
|
old_shield = player.shield;
|
|
|
|
|
|
|
|
if ((!engine.cheatShield) || (engine.missionCompleteTimer != 0))
|
|
|
|
{
|
|
|
|
if ((player.shield > engine.lowShield) &&
|
|
|
|
(player.shield - bullet->damage <= engine.lowShield))
|
|
|
|
setInfoLine("!!! WARNING: SHIELD LOW !!!", FONT_RED);
|
|
|
|
|
|
|
|
player.shield -= bullet->damage;
|
|
|
|
LIMIT(player.shield, 0, player.maxShield);
|
|
|
|
player.hit = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((bullet->owner->classDef == CD_PHOEBE) ||
|
|
|
|
(bullet->owner->classDef == CD_URSULA))
|
|
|
|
getPlayerHitMessage(bullet->owner);
|
|
|
|
|
|
|
|
if (bullet->id == WT_CHARGER)
|
|
|
|
{
|
|
|
|
bullet->damage -= old_shield;
|
|
|
|
if (bullet->damage <= 0)
|
|
|
|
{
|
|
|
|
bullet->active = false;
|
|
|
|
bullet->shield = 0;
|
|
|
|
audio_playSound(SFX_EXPLOSION, bullet->x);
|
|
|
|
for (int i = 0 ; i < 10 ; i++)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x + RANDRANGE(-35, 35),
|
2015-04-07 22:09:17 +02:00
|
|
|
bullet->y + RANDRANGE(-35, 35), E_BIG_EXPLOSION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bullet->active = false;
|
|
|
|
bullet->shield = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_playSound(SFX_HIT, player.x);
|
|
|
|
|
|
|
|
if (bullet->id == WT_ROCKET)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_BIG_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
else
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.difficulty != DIFFICULTY_EASY) &&
|
|
|
|
((bullet->owner == &player) || (bullet->id == WT_ROCKET)))
|
|
|
|
{
|
|
|
|
for (int j = 0 ; j < 20 ; j++)
|
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
if (cargo[j].active)
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
if (collision(bullet, &cargo[j]))
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
|
|
|
bullet->active = false;
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
2015-04-24 22:27:07 +02:00
|
|
|
audio_playSound(SFX_HIT, cargo[j].x);
|
|
|
|
if (cargo[j].collectType != P_PHOEBE)
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
2015-04-24 22:27:07 +02:00
|
|
|
cargo[j].active = false;
|
|
|
|
audio_playSound(SFX_EXPLOSION, cargo[j].x);
|
2015-04-07 22:09:17 +02:00
|
|
|
for (int i = 0 ; i < 10 ; i++)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(cargo[j].x + RANDRANGE(-15, 15),
|
2015-04-24 22:27:07 +02:00
|
|
|
cargo[j].y + RANDRANGE(-15, 15),
|
2015-04-07 22:09:17 +02:00
|
|
|
E_BIG_EXPLOSION);
|
|
|
|
updateMissionRequirements(M_PROTECT_PICKUP,
|
|
|
|
P_CARGO, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// check to see if a bullet (on any side) hits a mine
|
2015-04-24 22:37:55 +02:00
|
|
|
collectable = engine.collectableHead;
|
|
|
|
prevCollectable = engine.collectableHead;
|
2015-04-24 22:27:07 +02:00
|
|
|
engine.collectableTail = engine.collectableHead;
|
|
|
|
while (collectable->next != NULL)
|
|
|
|
{
|
|
|
|
collectable = collectable->next;
|
|
|
|
|
|
|
|
if (collectable->type == P_MINE)
|
|
|
|
{
|
|
|
|
if (collision(collectable, bullet))
|
|
|
|
{
|
|
|
|
collectable->active = false;
|
|
|
|
|
|
|
|
if (bullet->id != WT_CHARGER)
|
|
|
|
{
|
|
|
|
bullet->active = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bullet->shield--;
|
|
|
|
if (bullet->shield < 0)
|
|
|
|
bullet->active = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->owner == &player)
|
|
|
|
{
|
|
|
|
currentGame.minesKilled++;
|
|
|
|
currentGame.hits++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (collectable->active)
|
|
|
|
{
|
|
|
|
prevCollectable = collectable;
|
|
|
|
engine.collectableTail = collectable;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
collectable_explode(collectable);
|
|
|
|
prevCollectable->next = collectable->next;
|
|
|
|
delete collectable;
|
|
|
|
collectable = prevCollectable;
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 22:09:17 +02:00
|
|
|
|
|
|
|
bullet->shield--;
|
|
|
|
|
|
|
|
if (bullet->shield < 1)
|
|
|
|
{
|
|
|
|
if (bullet->flags & WF_TIMEDEXPLOSION)
|
|
|
|
{
|
|
|
|
audio_playSound(SFX_EXPLOSION, bullet->x);
|
|
|
|
for (int i = 0 ; i < 10 ; i++)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(bullet->x + RANDRANGE(-35, 35),
|
2015-04-07 22:09:17 +02:00
|
|
|
bullet->y + RANDRANGE(-35, 35), E_BIG_EXPLOSION);
|
|
|
|
|
2015-04-24 22:37:55 +02:00
|
|
|
player_checkShockDamage(bullet->x, bullet->y);
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
bullet->active = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bullet->active)
|
|
|
|
{
|
|
|
|
prevBullet = bullet;
|
|
|
|
engine.bulletTail = bullet;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prevBullet->next = bullet->next;
|
|
|
|
delete bullet;
|
|
|
|
bullet = prevBullet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void game_doAliens()
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-07 05:18:31 +01:00
|
|
|
static float barrierLoop = 0;
|
|
|
|
|
|
|
|
int shapeToUse;
|
2015-04-07 22:09:17 +02:00
|
|
|
bool canFire;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
barrierLoop += 0.2;
|
|
|
|
|
|
|
|
// A global variable for checking if all the aliens are dead
|
|
|
|
engine.allAliensDead = 1;
|
|
|
|
|
|
|
|
for (int i = 0 ; i < ALIEN_MAX ; i++)
|
|
|
|
{
|
|
|
|
if (aliens[i].active)
|
|
|
|
{
|
|
|
|
if (aliens[i].shield > 0)
|
|
|
|
{
|
|
|
|
if ((aliens[i].flags & FL_WEAPCO) && (!(aliens[i].flags & FL_DISABLED)))
|
|
|
|
engine.allAliensDead = 0;
|
|
|
|
|
|
|
|
// Set part attributes
|
|
|
|
if (aliens[i].owner != &aliens[i])
|
|
|
|
{
|
|
|
|
aliens[i].face = aliens[i].owner->face;
|
|
|
|
|
|
|
|
if (aliens[i].face == 0)
|
|
|
|
aliens[i].x = aliens[i].owner->x - aliens[i].dx;
|
|
|
|
else
|
|
|
|
aliens[i].x = aliens[i].owner->x + aliens[i].owner->image[0]->w + aliens[i].dx - aliens[i].image[0]->w;
|
|
|
|
|
|
|
|
aliens[i].y = (aliens[i].owner->y + aliens[i].dy);
|
|
|
|
|
|
|
|
if (aliens[i].owner->shield < 1)
|
|
|
|
{
|
|
|
|
if ((aliens[i].classDef != CD_URANUSBOSSWING1) &&
|
|
|
|
(aliens[i].classDef != CD_URANUSBOSSWING2))
|
|
|
|
{
|
|
|
|
aliens[i].shield = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aliens[i].flags &= ~FL_IMMORTAL;
|
|
|
|
aliens[i].owner = &aliens[i];
|
|
|
|
aliens[i].chance[0] = 25;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
canFire = true; // The alien is allowed to fire
|
|
|
|
|
|
|
|
LIMIT_ADD(aliens[i].thinktime, -1, 0, 250);
|
|
|
|
|
|
|
|
if (aliens[i].target->shield < 1)
|
|
|
|
aliens[i].target = &aliens[i];
|
|
|
|
|
|
|
|
// Specific to Sid to stop him pissing about(!)
|
|
|
|
if ((aliens[i].classDef == CD_SID) &&
|
|
|
|
(aliens[i].target->flags & FL_DISABLED))
|
|
|
|
aliens[i].target = &aliens[i];
|
|
|
|
|
|
|
|
if (aliens[i].target == &aliens[i])
|
|
|
|
{
|
|
|
|
if (engine.missionCompleteTimer == 0)
|
|
|
|
{
|
|
|
|
alien_searchForTarget(&aliens[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (aliens[i].flags & FL_FRIEND)
|
|
|
|
{
|
|
|
|
aliens[i].target = &player;
|
|
|
|
aliens[i].thinktime = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!(aliens[i].flags & FL_DISABLED)) &&
|
|
|
|
(aliens[i].thinktime == 0) && (aliens[i].target != &aliens[i]) &&
|
|
|
|
(aliens[i].owner == &aliens[i]))
|
|
|
|
{
|
|
|
|
if (aliens[i].classDef == CD_KLINE)
|
|
|
|
alien_setKlineAI(&aliens[i]);
|
|
|
|
else
|
|
|
|
alien_setAI(&aliens[i]);
|
|
|
|
|
|
|
|
aliens[i].thinktime = (rand() % 25) * 10;
|
|
|
|
|
|
|
|
// Face direction of movement unless you always face
|
|
|
|
// your target(!)
|
|
|
|
if (!(aliens[i].flags & FL_ALWAYSFACE))
|
|
|
|
{
|
|
|
|
aliens[i].face = (aliens[i].dx > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
LIMIT(aliens[i].dx, -aliens[i].speed, aliens[i].speed);
|
|
|
|
LIMIT(aliens[i].dy, -aliens[i].speed, aliens[i].speed);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].flags & FL_ALWAYSFACE)
|
|
|
|
{
|
|
|
|
aliens[i].face = 0;
|
|
|
|
if (aliens[i].x > aliens[i].target->x) aliens[i].face = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.area == MISN_ELLESH) &&
|
|
|
|
(aliens[i].classDef == CD_BOSS))
|
|
|
|
aliens[i].face = 0;
|
|
|
|
|
|
|
|
if ((aliens[i].flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0))
|
|
|
|
alien_addDrone(&aliens[i]);
|
|
|
|
|
|
|
|
if (aliens[i].flags & FL_LEAVESECTOR)
|
|
|
|
{
|
|
|
|
// Note: The original version of this line incorrectly
|
|
|
|
// specified -15 as the *maximum* instead of the
|
|
|
|
// *minimum*, which at the time was equivalent to
|
|
|
|
// ``aliens[i].dx = -15``.
|
|
|
|
LIMIT_ADD(aliens[i].dx, -0.5, -15, 0);
|
|
|
|
aliens[i].dy = 0;
|
|
|
|
aliens[i].thinktime = 999;
|
|
|
|
aliens[i].face = 0;
|
|
|
|
|
|
|
|
if (aliens[i].x >= 5000)
|
|
|
|
{
|
|
|
|
aliens[i].flags -= FL_LEAVESECTOR;
|
|
|
|
aliens[i].flags += FL_ESCAPED;
|
|
|
|
aliens[i].active = false;
|
|
|
|
|
|
|
|
if (aliens[i].classDef == CD_CLOAKFIGHTER)
|
|
|
|
{
|
|
|
|
currentGame.experimentalShield = aliens[i].shield;
|
|
|
|
setInfoLine("Experimental Fighter has fled",
|
|
|
|
FONT_CYAN);
|
|
|
|
}
|
|
|
|
|
|
|
|
aliens[i].shield = 0;
|
|
|
|
updateMissionRequirements(M_ESCAPE_TARGET,
|
|
|
|
aliens[i].classDef, 1);
|
|
|
|
|
|
|
|
if (aliens[i].classDef != CD_CLOAKFIGHTER)
|
|
|
|
updateMissionRequirements(M_DESTROY_TARGET_TYPE,
|
|
|
|
aliens[i].classDef, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This deals with the Experimental Fighter in Mordor
|
|
|
|
// (and Kline on the final mission)
|
|
|
|
// It can cloak and uncloak at random. When cloaked,
|
|
|
|
// its sprite is not displayed. However the engine
|
|
|
|
// trail is still visible!
|
|
|
|
if ((aliens[i].flags & FL_CANCLOAK) && ((rand() % 500) == 0))
|
|
|
|
{
|
|
|
|
if (aliens[i].flags & FL_ISCLOAKED)
|
|
|
|
aliens[i].flags -= FL_ISCLOAKED;
|
|
|
|
else
|
|
|
|
aliens[i].flags += FL_ISCLOAKED;
|
|
|
|
audio_playSound(SFX_CLOAK, aliens[i].x);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].classDef == CD_BARRIER)
|
|
|
|
{
|
|
|
|
aliens[i].dx = -10 + (sinf(barrierLoop + aliens[i].speed) * 60);
|
|
|
|
aliens[i].dy = 20 + (cosf(barrierLoop + aliens[i].speed) * 40);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].classDef == CD_MOBILESHIELD)
|
|
|
|
{
|
|
|
|
LIMIT_ADD(aliens[ALIEN_BOSS].shield, 1, 0,
|
|
|
|
aliens[ALIEN_BOSS].maxShield);
|
|
|
|
}
|
|
|
|
|
|
|
|
LIMIT_ADD(aliens[i].reload[0], -1, 0, 999);
|
|
|
|
LIMIT_ADD(aliens[i].reload[1], -1, 0, 999);
|
|
|
|
|
|
|
|
if ((!(aliens[i].flags & FL_DISABLED)) &&
|
|
|
|
(!(aliens[i].flags & FL_NOFIRE)))
|
|
|
|
{
|
|
|
|
if ((aliens[i].target->shield > 0))
|
|
|
|
canFire = alien_checkTarget(&aliens[i]);
|
|
|
|
|
|
|
|
if (((aliens[i].thinktime % 2) == 0) &&
|
|
|
|
(aliens[i].flags & FL_FRIEND))
|
|
|
|
canFire = alien_enemiesInFront(&aliens[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
canFire = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((canFire) && (dev.fireAliens))
|
|
|
|
{
|
|
|
|
if ((aliens[i].reload[0] == 0) &&
|
|
|
|
((rand() % 1000 < aliens[i].chance[0]) ||
|
|
|
|
(aliens[i].flags & FL_CONTINUOUS_FIRE)))
|
|
|
|
{
|
|
|
|
ship_fireBullet(&aliens[i], 0);
|
|
|
|
}
|
|
|
|
if ((aliens[i].reload[1] == 0) &&
|
|
|
|
((rand() % 1000 < aliens[i].chance[1]) ||
|
|
|
|
(aliens[i].flags & FL_CONTINUOUS_FIRE)))
|
|
|
|
{
|
|
|
|
if ((aliens[i].weaponType[1] != W_ENERGYRAY) &&
|
|
|
|
(aliens[i].weaponType[1] != W_LASER))
|
|
|
|
{
|
|
|
|
if (aliens[i].weaponType[1] == W_CHARGER)
|
|
|
|
aliens[i].ammo[1] = 50 + rand() % 150;
|
|
|
|
ship_fireBullet(&aliens[i], 1);
|
|
|
|
}
|
|
|
|
else if (aliens[i].weaponType[1] == W_LASER)
|
|
|
|
{
|
|
|
|
aliens[i].flags += FL_FIRELASER;
|
|
|
|
}
|
|
|
|
else if ((aliens[i].weaponType[1] == W_ENERGYRAY) &&
|
|
|
|
(aliens[i].ammo[0] == 250))
|
|
|
|
{
|
|
|
|
aliens[i].flags += FL_FIRERAY;
|
|
|
|
audio_playSound(SFX_ENERGYRAY, aliens[i].x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].flags & FL_FIRERAY)
|
|
|
|
{
|
|
|
|
ship_fireRay(&aliens[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LIMIT_ADD(aliens[i].ammo[0], 1, 0, 250);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].flags & FL_FIRELASER)
|
|
|
|
{
|
|
|
|
ship_fireBullet(&aliens[i], 1);
|
|
|
|
if ((rand() % 25) == 0)
|
|
|
|
aliens[i].flags -= FL_FIRELASER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aliens[i].flags & FL_DROPMINES)
|
|
|
|
{
|
|
|
|
if ((rand() % 150) == 0)
|
2015-04-24 22:27:07 +02:00
|
|
|
collectable_add(aliens[i].x, aliens[i].y, P_MINE, 25,
|
2015-04-07 22:09:17 +02:00
|
|
|
600 + rand() % 2400);
|
|
|
|
|
|
|
|
// Kline drops mines a lot more often
|
|
|
|
if ((&aliens[i] == &aliens[ALIEN_KLINE]))
|
|
|
|
{
|
|
|
|
if ((rand() % 10) == 0)
|
2015-04-24 22:27:07 +02:00
|
|
|
collectable_add(aliens[i].x, aliens[i].y, P_MINE, 25,
|
2015-04-07 22:09:17 +02:00
|
|
|
600 + rand() % 2400);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shapeToUse = aliens[i].imageIndex[aliens[i].face];
|
|
|
|
|
|
|
|
if (aliens[i].hit)
|
|
|
|
shapeToUse += SHIP_HIT_INDEX;
|
|
|
|
|
|
|
|
LIMIT_ADD(aliens[i].hit, -1, 0, 100);
|
|
|
|
|
|
|
|
if ((aliens[i].x + aliens[i].image[0]->w > 0) &&
|
|
|
|
(aliens[i].x < screen->w) &&
|
|
|
|
(aliens[i].y + aliens[i].image[0]->h > 0) &&
|
|
|
|
(aliens[i].y < screen->h))
|
|
|
|
{
|
|
|
|
if ((!(aliens[i].flags & FL_DISABLED)) &&
|
|
|
|
(aliens[i].classDef != CD_ASTEROID) &&
|
|
|
|
(aliens[i].classDef != CD_ASTEROID2))
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_addEngine(&aliens[i]);
|
2015-04-07 22:09:17 +02:00
|
|
|
if ((!(aliens[i].flags & FL_ISCLOAKED)) || (aliens[i].hit > 0))
|
|
|
|
blit(shipShape[shapeToUse], (int)aliens[i].x,
|
|
|
|
(int)aliens[i].y);
|
|
|
|
if (aliens[i].flags & FL_DISABLED)
|
|
|
|
{
|
|
|
|
if ((rand() % 10) == 0)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(aliens[i].x + (rand() % aliens[i].image[0]->w),
|
2015-04-07 22:09:17 +02:00
|
|
|
aliens[i].y + (rand() % aliens[i].image[0]->h),
|
|
|
|
E_ELECTRICAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.area == MISN_MARS) && (aliens[i].x < -60))
|
|
|
|
aliens[i].active = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aliens[i].shield--;
|
|
|
|
if ((aliens[i].x > 0) && (aliens[i].x < screen->w) &&
|
|
|
|
(aliens[i].y > 0) && (aliens[i].y < screen->h))
|
|
|
|
{
|
|
|
|
blit(aliens[i].image[aliens[i].face], (int)aliens[i].x,
|
|
|
|
(int)aliens[i].y);
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(aliens[i].x + (rand() % aliens[i].image[0]->w),
|
2015-04-07 22:09:17 +02:00
|
|
|
aliens[i].y + (rand() % aliens[i].image[0]->h),
|
|
|
|
E_BIG_EXPLOSION);
|
|
|
|
}
|
|
|
|
if (aliens[i].shield < aliens[i].deathCounter)
|
|
|
|
{
|
|
|
|
aliens[i].active = false;
|
|
|
|
if ((aliens[i].classDef == CD_BOSS) ||
|
|
|
|
(aliens[i].owner == &aliens[ALIEN_BOSS]) ||
|
|
|
|
(aliens[i].flags & FL_FRIEND) ||
|
|
|
|
(aliens[i].classDef == CD_ASTEROID) ||
|
|
|
|
(aliens[i].classDef == CD_KLINE))
|
2015-04-08 01:16:46 +02:00
|
|
|
game_addDebris((int)aliens[i].x, (int)aliens[i].y,
|
2015-04-07 22:09:17 +02:00
|
|
|
aliens[i].maxShield);
|
|
|
|
|
|
|
|
if (aliens[i].classDef == CD_ASTEROID)
|
|
|
|
{
|
|
|
|
n = 1 + (rand() % 3);
|
2015-04-15 00:50:07 +02:00
|
|
|
for (int j = 0 ; j < n ; j++)
|
|
|
|
{
|
2015-04-07 22:09:17 +02:00
|
|
|
alien_addSmallAsteroid(&aliens[i]);
|
2015-04-15 00:50:07 +02:00
|
|
|
}
|
2015-04-07 22:09:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adjust the movement even whilst exploding
|
|
|
|
if ((dev.moveAliens) && (!(aliens[i].flags & FL_NOMOVE)) &&
|
|
|
|
(!(aliens[i].flags & FL_DISABLED)))
|
|
|
|
alien_move(&aliens[i]);
|
|
|
|
|
|
|
|
if ((currentGame.area != MISN_ELLESH) || (aliens[i].shield < 0))
|
|
|
|
aliens[i].x += engine.ssx;
|
|
|
|
|
|
|
|
aliens[i].x += engine.smx;
|
|
|
|
aliens[i].y += engine.ssy + engine.smy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
static void game_doPlayer()
|
2015-04-07 22:09:17 +02:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
// This causes the motion to slow
|
|
|
|
engine.ssx *= 0.99;
|
|
|
|
engine.ssy *= 0.99;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
engine.smx = 0;
|
|
|
|
engine.smy = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
int shapeToUse;
|
|
|
|
float cd;
|
|
|
|
float cc;
|
|
|
|
bool xmoved = false;
|
|
|
|
bool ymoved = false;
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (player.shield > -100)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
if (player.shield > 0)
|
|
|
|
{
|
|
|
|
if ((engine.keyState[KEY_FIRE]))
|
|
|
|
ship_fireBullet(&player, 0);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((engine.keyState[KEY_ALTFIRE]) && (player.weaponType[1] != W_NONE))
|
|
|
|
{
|
|
|
|
if ((player.weaponType[1] != W_CHARGER) &&
|
|
|
|
(player.weaponType[1] != W_LASER) && (player.ammo[1] > 0))
|
|
|
|
{
|
|
|
|
ship_fireBullet(&player, 1);
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (player.weaponType[1] == W_LASER)
|
|
|
|
{
|
|
|
|
if (player.ammo[1] < 100)
|
|
|
|
{
|
|
|
|
ship_fireBullet(&player, 1);
|
|
|
|
player.ammo[1] += 2;
|
|
|
|
if (player.ammo[1] >= 100)
|
|
|
|
{
|
|
|
|
player.ammo[1] = 200;
|
|
|
|
setInfoLine("Laser Overheat!!", FONT_WHITE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (player.weaponType[1] == W_CHARGER)
|
|
|
|
{
|
|
|
|
if (engine.keyState[KEY_ALTFIRE] &&
|
|
|
|
((currentGame.difficulty == DIFFICULTY_ORIGINAL) ||
|
|
|
|
!(engine.keyState[KEY_FIRE])))
|
|
|
|
{
|
|
|
|
if (!player_chargerFired)
|
|
|
|
{
|
|
|
|
if (currentGame.difficulty == DIFFICULTY_ORIGINAL)
|
|
|
|
{
|
|
|
|
LIMIT_ADD(player.ammo[1], 1, 0, 200);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LIMIT_ADD(player.ammo[1], 1, 0, 150);
|
|
|
|
if (player.ammo[1] >= 150)
|
|
|
|
{
|
|
|
|
ship_fireBullet(&player, 1);
|
|
|
|
player.ammo[1] = 0;
|
|
|
|
player_chargerFired = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (player.ammo[1] > 0)
|
|
|
|
ship_fireBullet(&player, 1);
|
|
|
|
player.ammo[1] = 0;
|
|
|
|
player_chargerFired = false;
|
|
|
|
}
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((engine.keyState[KEY_SWITCH]))
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((weapon[W_PLAYER_WEAPON].ammo[0] >= 3) &&
|
|
|
|
(weapon[W_PLAYER_WEAPON].ammo[0] <= currentGame.maxPlasmaOutput))
|
|
|
|
{
|
|
|
|
weapon[W_PLAYER_WEAPON].flags ^= WF_SPREAD;
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (weapon[W_PLAYER_WEAPON].flags & WF_SPREAD)
|
|
|
|
{
|
|
|
|
setInfoLine("Weapon set to Spread", FONT_WHITE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setInfoLine("Weapon set to Concentrate", FONT_WHITE);
|
|
|
|
}
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
engine.keyState[KEY_SWITCH] = 0;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
LIMIT_ADD(player.reload[0], -1, 0, 999);
|
|
|
|
LIMIT_ADD(player.reload[1], -1, 0, 999);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_UP])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
player.y -= player.speed;
|
|
|
|
engine.ssy += 0.1;
|
|
|
|
ymoved = true;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_DOWN])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
player.y += player.speed;
|
|
|
|
engine.ssy -= 0.1;
|
|
|
|
ymoved = true;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_LEFT])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
player.x -= player.speed;
|
|
|
|
engine.ssx += 0.1;
|
|
|
|
player.face = 1;
|
|
|
|
xmoved = true;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_RIGHT])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
player.x += player.speed;
|
|
|
|
engine.ssx -= 0.1;
|
|
|
|
player.face = 0;
|
|
|
|
xmoved = true;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_ESCAPE])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((engine.done == 0) && (engine.gameSection == SECTION_GAME) &&
|
|
|
|
(currentMission.remainingObjectives1 == 0))
|
|
|
|
{
|
|
|
|
audio_playSound(SFX_FLY, screen->w / 2);
|
|
|
|
engine.done = 2;
|
|
|
|
engine.missionCompleteTimer = (SDL_GetTicks() - 1);
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.keyState[KEY_PAUSE])
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
engine.paused = true;
|
|
|
|
engine.keyState[KEY_PAUSE] = 0;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (((currentGame.area == MISN_ELLESH) &&
|
|
|
|
(aliens[ALIEN_BOSS].shield > 0)) ||
|
|
|
|
(currentGame.area == MISN_MARS))
|
|
|
|
{
|
|
|
|
player.face = 0;
|
|
|
|
xmoved = true;
|
|
|
|
ymoved = true;
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (engine.done == 0)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
if (xmoved)
|
|
|
|
{
|
|
|
|
if (player.x < xViewBorder)
|
|
|
|
{
|
|
|
|
engine.smx += xViewBorder - player.x;
|
|
|
|
player.x = xViewBorder;
|
|
|
|
}
|
|
|
|
else if (player.x > screen->w - xViewBorder)
|
|
|
|
{
|
|
|
|
engine.smx += (screen->w - xViewBorder) - player.x;
|
|
|
|
player.x = screen->w - xViewBorder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (currentGame.difficulty != DIFFICULTY_ORIGINAL)
|
|
|
|
{
|
|
|
|
cd = player.x - screen->w / 2;
|
|
|
|
if (cd < 0)
|
|
|
|
{
|
|
|
|
cc = MAX(cd / 10, MAX(0, engine.ssx) - cameraMaxSpeed);
|
|
|
|
player.x -= cc;
|
|
|
|
engine.smx -= cc;
|
|
|
|
}
|
|
|
|
else if (cd > 0)
|
|
|
|
{
|
|
|
|
cc = MIN(cd / 10, cameraMaxSpeed + MIN(0, engine.ssx));
|
|
|
|
player.x -= cc;
|
|
|
|
engine.smx -= cc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ymoved)
|
|
|
|
{
|
|
|
|
if (player.y < yViewBorder)
|
|
|
|
{
|
|
|
|
engine.smy += yViewBorder - player.y;
|
|
|
|
player.y = yViewBorder;
|
|
|
|
}
|
|
|
|
else if (player.y > screen->h - yViewBorder)
|
|
|
|
{
|
|
|
|
engine.smy += (screen->h - yViewBorder) - player.y;
|
|
|
|
player.y = screen->h - yViewBorder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (currentGame.difficulty != DIFFICULTY_ORIGINAL)
|
|
|
|
{
|
|
|
|
cd = player.y - screen->h / 2;
|
|
|
|
if (cd < 0)
|
|
|
|
{
|
|
|
|
cc = MAX(cd / 10, MAX(0, engine.ssy) - cameraMaxSpeed);
|
|
|
|
player.y -= cc;
|
|
|
|
engine.smy -= cc;
|
|
|
|
}
|
|
|
|
else if (cd > 0)
|
|
|
|
{
|
|
|
|
cc = MIN(cd / 10, cameraMaxSpeed + MIN(0, engine.ssy));
|
|
|
|
player.y -= cc;
|
|
|
|
engine.smy -= cc;
|
|
|
|
}
|
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((player.maxShield <= 1) || (player.shield > engine.lowShield))
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_addEngine(&player);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
shapeToUse = player.face;
|
|
|
|
|
|
|
|
if (player.hit)
|
|
|
|
shapeToUse += SHIP_HIT_INDEX;
|
|
|
|
|
|
|
|
LIMIT_ADD(player.hit, -1, 0, 100);
|
|
|
|
|
|
|
|
blit(shipShape[shapeToUse], (int)player.x, (int)player.y);
|
|
|
|
if ((player.maxShield > 1) && (player.shield <= engine.lowShield) &&
|
|
|
|
(rand() % 5 < 1))
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(player.x + RANDRANGE(-10, 10),
|
2015-04-08 01:16:46 +02:00
|
|
|
player.y + RANDRANGE(-10, 20), E_SMOKE);
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
2015-04-08 01:16:46 +02:00
|
|
|
else
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
player.active = false;
|
|
|
|
player.shield--;
|
|
|
|
if (player.shield == -1)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
if ((currentGame.hasWingMate1) || (aliens[ALIEN_KLINE].active))
|
|
|
|
getPlayerDeathMessage();
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
// Make it look like the ships are all still moving...
|
|
|
|
if (currentGame.area == MISN_ELLESH)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
for (int i = 0 ; i < ALIEN_MAX ; i++)
|
|
|
|
aliens[i].flags |= FL_LEAVESECTOR;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
2015-04-08 01:16:46 +02:00
|
|
|
|
|
|
|
audio_playSound(SFX_DEATH, player.x);
|
|
|
|
audio_playSound(SFX_EXPLOSION, player.x);
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.keyState[KEY_UP] = engine.keyState[KEY_DOWN] = engine.keyState[KEY_LEFT] = engine.keyState[KEY_RIGHT] = 0;
|
|
|
|
if ((rand() % 3) == 0)
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(player.x + RANDRANGE(-10, 10),
|
2015-04-08 01:16:46 +02:00
|
|
|
player.y + RANDRANGE(-10, 10), E_BIG_EXPLOSION);
|
|
|
|
if (player.shield == -99)
|
|
|
|
game_addDebris((int)player.x, (int)player.y, player.maxShield);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LIMIT(engine.ssx, -cameraMaxSpeed, cameraMaxSpeed);
|
|
|
|
LIMIT(engine.ssy, -cameraMaxSpeed, cameraMaxSpeed);
|
|
|
|
|
|
|
|
// Specific for the mission were you have to chase the Executive Transport
|
|
|
|
if ((currentGame.area == MISN_ELLESH) && (aliens[ALIEN_BOSS].shield > 0) &&
|
|
|
|
(player.shield > 0))
|
|
|
|
{
|
|
|
|
engine.ssx = -6;
|
|
|
|
engine.ssy = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentGame.area == MISN_MARS)
|
|
|
|
{
|
|
|
|
engine.ssx = -6;
|
|
|
|
engine.ssy = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
player.dx = engine.ssx;
|
|
|
|
player.dy = engine.ssy;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void game_doCargo()
|
|
|
|
{
|
|
|
|
float dx, dy, chainX, chainY;
|
|
|
|
|
|
|
|
for (int i = 0 ; i < MAX_CARGO ; i++)
|
|
|
|
{
|
|
|
|
if (cargo[i].active)
|
|
|
|
{
|
|
|
|
if (!cargo[i].owner->active)
|
|
|
|
{
|
|
|
|
cargo_becomeCollectable(i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
blit(cargo[i].image[0], (int)cargo[i].x, (int)cargo[i].y);
|
|
|
|
|
|
|
|
cargo[i].x += engine.ssx + engine.smx;
|
|
|
|
cargo[i].y += engine.ssy + engine.smy;
|
|
|
|
|
|
|
|
LIMIT(cargo[i].x, cargo[i].owner->x - 50, cargo[i].owner->x + 50);
|
|
|
|
LIMIT(cargo[i].y, cargo[i].owner->y - 50, cargo[i].owner->y + 50);
|
|
|
|
|
|
|
|
dx = (cargo[i].x - cargo[i].owner->x) / 10;
|
|
|
|
dy = (cargo[i].y - cargo[i].owner->y) / 10;
|
|
|
|
chainX = cargo[i].x - cargo[i].dx;
|
|
|
|
chainY = cargo[i].y - cargo[i].dy;
|
|
|
|
|
|
|
|
// draw the chain link line
|
|
|
|
for (int j = 0 ; j < 10 ; j++)
|
|
|
|
{
|
|
|
|
blit(shape[30], (int)chainX, (int)chainY);
|
|
|
|
chainX -= dx;
|
|
|
|
chainY -= dy;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
}
|
2015-04-08 01:16:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void game_doDebris()
|
|
|
|
{
|
|
|
|
object *prevDebris = engine.debrisHead;
|
|
|
|
object *debris = engine.debrisHead;
|
|
|
|
engine.debrisTail = engine.debrisHead;
|
|
|
|
|
|
|
|
while (debris->next != NULL)
|
|
|
|
{
|
|
|
|
debris = debris->next;
|
|
|
|
|
|
|
|
if (debris->thinktime > 0)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-04-08 01:16:46 +02:00
|
|
|
debris->thinktime--;
|
|
|
|
|
|
|
|
debris->x += engine.ssx + engine.smx;
|
|
|
|
debris->y += engine.ssy + engine.smy;
|
|
|
|
debris->x += debris->dx;
|
|
|
|
debris->y += debris->dy;
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-05-01 00:51:26 +02:00
|
|
|
explosion_add(debris->x + RANDRANGE(-10, 10), debris->y + RANDRANGE(-10, 10), E_BIG_EXPLOSION);
|
2015-04-08 01:16:46 +02:00
|
|
|
}
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
if (debris->thinktime < 1)
|
|
|
|
{
|
|
|
|
prevDebris->next = debris->next;
|
|
|
|
delete debris;
|
|
|
|
debris = prevDebris;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prevDebris = debris;
|
|
|
|
engine.debrisTail = debris;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
2015-04-08 01:16:46 +02:00
|
|
|
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
2015-04-08 01:16:46 +02:00
|
|
|
}
|
|
|
|
|
2015-05-01 00:51:26 +02:00
|
|
|
/*
|
|
|
|
Loops through active explosions and decrements their think time.
|
|
|
|
If their thinktime is divisable by 5, then the frame is changed to
|
|
|
|
the next one up (for example 0->1->2-3). When their think time is 0,
|
|
|
|
the explosion is killed off.
|
|
|
|
*/
|
|
|
|
void game_doExplosions()
|
|
|
|
{
|
|
|
|
object *prevExplosion = engine.explosionHead;
|
|
|
|
object *explosion = engine.explosionHead;
|
|
|
|
engine.explosionTail = engine.explosionHead;
|
|
|
|
|
|
|
|
while (explosion->next != NULL)
|
|
|
|
{
|
|
|
|
explosion = explosion->next;
|
|
|
|
|
|
|
|
if (explosion->active)
|
|
|
|
{
|
|
|
|
explosion->x += engine.ssx + engine.smx;
|
|
|
|
explosion->y += engine.ssy + engine.smy;
|
|
|
|
|
|
|
|
blit(explosion->image[0], (int)explosion->x, (int)explosion->y);
|
|
|
|
|
|
|
|
if(rand() % 7 == 0)
|
|
|
|
{
|
|
|
|
explosion->thinktime -= 7;
|
|
|
|
|
|
|
|
if(explosion->thinktime < 1)
|
|
|
|
{
|
|
|
|
explosion->active = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
explosion->face++;
|
|
|
|
explosion->image[0] = shape[explosion->face];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (explosion->active)
|
|
|
|
{
|
|
|
|
prevExplosion = explosion;
|
|
|
|
engine.explosionTail = explosion;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prevExplosion->next = explosion->next;
|
|
|
|
delete explosion;
|
|
|
|
explosion = prevExplosion;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-26 13:36:25 +02:00
|
|
|
/*
|
|
|
|
Checked during the main game loop. When the game is paused
|
|
|
|
it goes into a constant loop checking this routine. If escape is
|
|
|
|
pressed, the game automatically ends and goes back to the title screen
|
|
|
|
*/
|
|
|
|
static bool game_checkPauseRequest()
|
|
|
|
{
|
|
|
|
getPlayerInput();
|
|
|
|
|
|
|
|
if (engine.keyState[KEY_ESCAPE])
|
|
|
|
{
|
|
|
|
engine.paused = false;
|
|
|
|
engine.done = 1;
|
|
|
|
player.shield = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (engine.keyState[KEY_PAUSE])
|
|
|
|
{
|
|
|
|
engine.paused = false;
|
|
|
|
engine.keyState[KEY_PAUSE] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-08 01:16:46 +02:00
|
|
|
int mainGameLoop()
|
|
|
|
{
|
|
|
|
resetLists();
|
|
|
|
|
|
|
|
setMission(currentGame.area);
|
|
|
|
missionBriefScreen();
|
|
|
|
|
2015-04-24 22:27:07 +02:00
|
|
|
cargo_init();
|
2015-04-08 01:16:46 +02:00
|
|
|
initPlayer();
|
|
|
|
aliens_init();
|
2015-03-07 05:18:31 +01:00
|
|
|
|
|
|
|
// specific for Phoebe being captured!
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_NEROD)
|
2015-03-07 05:18:31 +01:00
|
|
|
currentGame.hasWingMate1 = 1;
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_ELAMALE)
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_KLINE].active = false;
|
2015-03-07 05:18:31 +01:00
|
|
|
|
|
|
|
for (int i = 0 ; i < engine.maxAliens ; i++)
|
|
|
|
alien_add();
|
|
|
|
|
|
|
|
if (currentGame.hasWingMate1)
|
2015-03-09 01:59:33 +01:00
|
|
|
alien_addFriendly(ALIEN_PHOEBE);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
|
|
|
if (currentGame.hasWingMate2)
|
2015-03-09 01:59:33 +01:00
|
|
|
alien_addFriendly(ALIEN_URSULA);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((currentGame.area == MISN_URUSOR) ||
|
|
|
|
(currentGame.area == MISN_POSWIC) ||
|
|
|
|
(currentGame.area == MISN_EARTH))
|
2015-03-09 01:59:33 +01:00
|
|
|
alien_addFriendly(ALIEN_SID);
|
2015-03-07 05:18:31 +01:00
|
|
|
|
|
|
|
// Disable Wingmates for certain missions
|
|
|
|
switch (currentGame.area)
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_NEROD:
|
|
|
|
case MISN_URUSOR:
|
|
|
|
case MISN_DORIM:
|
|
|
|
case MISN_SIVEDI:
|
|
|
|
case MISN_ALMARTHA:
|
|
|
|
case MISN_ELLESH:
|
|
|
|
case MISN_MARS:
|
|
|
|
case MISN_VENUS:
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_PHOEBE].active = false;
|
|
|
|
aliens[ALIEN_URSULA].active = false;
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_DORIM)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-03-07 15:42:24 +01:00
|
|
|
aliens[0].collectChance = 100;
|
|
|
|
aliens[0].collectType = P_ESCAPEPOD;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Some specifics for interception missions
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_INTERCEPTION)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
|
|
|
if ((currentGame.system > 1) && ((rand() % 5) == 0))
|
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_KLINE] = alien_defs[CD_KLINE];
|
|
|
|
aliens[ALIEN_KLINE].owner = &aliens[ALIEN_KLINE];
|
|
|
|
aliens[ALIEN_KLINE].target = &player;
|
|
|
|
aliens[ALIEN_KLINE].active = true;
|
|
|
|
aliens[ALIEN_KLINE].x = player.x + 1000;
|
|
|
|
aliens[ALIEN_KLINE].y = player.y;
|
|
|
|
player_setTarget(ALIEN_KLINE);
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((currentGame.system == 2) && (currentGame.experimentalShield > 0))
|
|
|
|
{
|
2015-03-18 03:09:00 +01:00
|
|
|
if ((rand() % 5) > 0)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-03-07 15:42:24 +01:00
|
|
|
aliens[10] = alien_defs[CD_CLOAKFIGHTER];
|
|
|
|
aliens[10].owner = &aliens[10];
|
|
|
|
aliens[10].target = &aliens[10];
|
|
|
|
aliens[10].shield = 1000;
|
|
|
|
aliens[10].active = true;
|
|
|
|
aliens[10].x = player.x - 1000;
|
|
|
|
aliens[10].y = player.y;
|
2015-03-07 05:18:31 +01:00
|
|
|
player_setTarget(10);
|
2015-03-07 15:42:24 +01:00
|
|
|
aliens[10].shield = currentGame.experimentalShield;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_VENUS)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_KLINE].x = player.x + 1000;
|
|
|
|
aliens[ALIEN_KLINE].y = player.y;
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
2015-03-09 01:59:33 +01:00
|
|
|
for (int i = 0 ; i < ALIEN_MAX ; i++)
|
2015-03-07 05:18:31 +01:00
|
|
|
{
|
2015-03-07 15:42:24 +01:00
|
|
|
aliens[i].systemPower = aliens[i].maxShield;
|
|
|
|
aliens[i].deathCounter = 0 - (aliens[i].maxShield * 3);
|
2015-03-18 00:00:13 +01:00
|
|
|
LIMIT(aliens[i].deathCounter, -350, 0);
|
2015-03-07 05:18:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set target energy meter
|
|
|
|
switch (currentGame.area)
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_MOEBO:
|
|
|
|
case MISN_ELAMALE:
|
|
|
|
case MISN_ODEON:
|
|
|
|
case MISN_FELLON:
|
|
|
|
case MISN_POSWIC:
|
|
|
|
case MISN_ELLESH:
|
|
|
|
case MISN_PLUTO:
|
|
|
|
case MISN_NEPTUNE:
|
|
|
|
case MISN_URANUS:
|
|
|
|
case MISN_JUPITER:
|
2015-03-09 01:59:33 +01:00
|
|
|
player_setTarget(ALIEN_BOSS);
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_NEROD:
|
2015-03-09 01:59:33 +01:00
|
|
|
player_setTarget(ALIEN_PHOEBE);
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_ALLEZ:
|
2015-03-09 01:59:33 +01:00
|
|
|
player_setTarget(ALIEN_GOODTRANSPORT);
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_URUSOR:
|
2015-03-09 01:59:33 +01:00
|
|
|
player_setTarget(ALIEN_SID);
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_EARTH:
|
|
|
|
case MISN_VENUS:
|
2015-03-09 01:59:33 +01:00
|
|
|
player_setTarget(ALIEN_KLINE);
|
2015-03-07 05:18:31 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-08-24 14:14:44 +02:00
|
|
|
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++)
|
|
|
|
{
|
2015-03-07 15:42:24 +01:00
|
|
|
if ((currentMission.primaryType[i] == M_DESTROY_TARGET_TYPE) &&
|
|
|
|
(currentMission.target1[i] == CD_ANY))
|
2011-08-24 14:14:44 +02:00
|
|
|
allowableAliens = currentMission.targetValue1[i];
|
|
|
|
|
|
|
|
if (currentMission.primaryType[i] == M_DESTROY_ALL_TARGETS)
|
|
|
|
allowableAliens = 999999999;
|
|
|
|
}
|
|
|
|
|
2015-03-09 01:59:33 +01:00
|
|
|
for (int i = 0 ; i < ALIEN_MAX ; i++)
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-07 15:42:24 +01:00
|
|
|
if ((aliens[i].active) && (aliens[i].flags & FL_WEAPCO))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2015-03-07 05:18:31 +01:00
|
|
|
engine.keyState[KEY_FIRE] = 0;
|
|
|
|
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))
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area != MISN_MOEBO)
|
2011-08-24 14:14:44 +02:00
|
|
|
engine.missionCompleteTimer = SDL_GetTicks() + 4000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (engine.missionCompleteTimer != 0)
|
|
|
|
{
|
|
|
|
engine.gameSection = SECTION_INTERMISSION;
|
|
|
|
if (player.shield > 0)
|
|
|
|
{
|
|
|
|
if (SDL_GetTicks() >= engine.missionCompleteTimer)
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((!missionFailed()) && (currentGame.area != MISN_VENUS))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
|
|
|
leaveSector();
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((engine.done == 2) &&
|
|
|
|
(currentGame.area != MISN_DORIM) &&
|
|
|
|
(currentGame.area != MISN_SIVEDI))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
if ((aliens[ALIEN_PHOEBE].shield > 0) &&
|
2015-03-29 19:11:12 +02:00
|
|
|
(currentGame.area != MISN_EARTH))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_PHOEBE].x = player.x - 40;
|
|
|
|
aliens[ALIEN_PHOEBE].y = player.y - 35;
|
|
|
|
aliens[ALIEN_PHOEBE].face = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
2015-03-09 01:59:33 +01:00
|
|
|
if ((aliens[ALIEN_URSULA].shield > 0) &&
|
2015-03-29 19:11:12 +02:00
|
|
|
(currentGame.area != MISN_EARTH))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_URSULA].x = player.x - 40;
|
|
|
|
aliens[ALIEN_URSULA].y = player.y + 45;
|
|
|
|
aliens[ALIEN_URSULA].face = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((currentGame.area == MISN_URUSOR) ||
|
|
|
|
(currentGame.area == MISN_POSWIC))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
aliens[ALIEN_SID].x = player.x - 100;
|
|
|
|
aliens[ALIEN_SID].y = player.y;
|
|
|
|
aliens[ALIEN_SID].face = 0;
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-03-29 19:11:12 +02:00
|
|
|
else if ((currentGame.area == MISN_VENUS) &&
|
|
|
|
(engine.musicVolume > 0))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-29 22:49:33 +02:00
|
|
|
engine.keyState[KEY_UP] = 0;
|
|
|
|
engine.keyState[KEY_DOWN] = 0;
|
|
|
|
engine.keyState[KEY_LEFT] = 0;
|
|
|
|
engine.keyState[KEY_RIGHT] = 0;
|
|
|
|
engine.keyState[KEY_FIRE] = 0;
|
|
|
|
engine.keyState[KEY_ALTFIRE] = 0;
|
2015-03-18 00:00:13 +01:00
|
|
|
LIMIT_ADD(engine.musicVolume, -0.2, 0, 100);
|
2015-03-31 21:23:17 +02:00
|
|
|
audio_setMusicVolume(engine.musicVolume);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
engine.done = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getPlayerInput();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-18 00:00:13 +01:00
|
|
|
LIMIT_ADD(engine.musicVolume, -0.2, 0, 100);
|
2015-03-31 21:23:17 +02:00
|
|
|
audio_setMusicVolume(engine.musicVolume);
|
2011-08-24 14:14:44 +02:00
|
|
|
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();
|
2015-04-08 01:16:46 +02:00
|
|
|
game_doCollectables();
|
2015-04-07 22:09:17 +02:00
|
|
|
game_doBullets();
|
|
|
|
game_doAliens();
|
2015-04-08 01:16:46 +02:00
|
|
|
game_doPlayer();
|
|
|
|
game_doCargo();
|
|
|
|
game_doDebris();
|
2015-05-01 00:51:26 +02:00
|
|
|
game_doExplosions();
|
2011-08-24 14:14:44 +02:00
|
|
|
doInfo();
|
|
|
|
|
2015-03-24 23:51:12 +01:00
|
|
|
WRAP_ADD(engine.eventTimer, -1, 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();
|
2015-04-26 13:45:58 +02:00
|
|
|
audio_pauseMusic();
|
2011-09-05 11:40:35 +02:00
|
|
|
|
|
|
|
while (engine.paused)
|
|
|
|
{
|
2015-04-26 13:36:25 +02:00
|
|
|
engine.done = game_checkPauseRequest();
|
2011-09-05 11:40:35 +02:00
|
|
|
delayFrame();
|
|
|
|
}
|
2015-04-26 13:45:58 +02:00
|
|
|
|
|
|
|
audio_resumeMusic();
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((currentGame.area == MISN_MARS) && (engine.addAliens > -1))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-29 20:27:29 +02:00
|
|
|
if ((rand() % 5) == 0)
|
2015-03-29 16:19:53 +02:00
|
|
|
// XXX: The originally specified range for x was [800, 100],
|
|
|
|
// which with the original rrand function caused the result
|
|
|
|
// returned to be `800 + rand() % -699`. Clearly a mistake,
|
|
|
|
// but I'm not entirely sure what the original intention was.
|
|
|
|
// For now, I've set the range to [800, 1500], which
|
|
|
|
// approximately replicates the original's results.
|
2015-04-24 22:27:07 +02:00
|
|
|
collectable_add(RANDRANGE(800, 1500),
|
2015-03-29 20:27:29 +02:00
|
|
|
RANDRANGE(-screen->h / 3, (4 * screen->h) / 3), P_MINE, 25,
|
2015-03-07 05:18:31 +01:00
|
|
|
180 + rand() % 60);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (engine.addAliens > -1)
|
|
|
|
{
|
2015-03-28 18:18:37 +01:00
|
|
|
WRAP_ADD(engine.addAliens, -1, 0, currentMission.addAliens);
|
2011-08-24 14:14:44 +02:00
|
|
|
if ((engine.addAliens == 0) && (allowableAliens > 0))
|
|
|
|
{
|
2015-03-05 03:30:23 +01:00
|
|
|
allowableAliens -= alien_add();
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((player.shield <= 0) && (engine.missionCompleteTimer == 0))
|
|
|
|
engine.missionCompleteTimer = SDL_GetTicks() + 7000;
|
|
|
|
|
|
|
|
// specific to Boss 1
|
2015-03-29 19:11:12 +02:00
|
|
|
if ((currentGame.area == MISN_MOEBO) &&
|
|
|
|
(aliens[ALIEN_BOSS].flags & FL_ESCAPED))
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2015-03-09 01:59:33 +01:00
|
|
|
audio_playSound(SFX_DEATH, aliens[ALIEN_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)
|
2015-03-09 01:59:33 +01:00
|
|
|
audio_playSound(SFX_EXPLOSION, aliens[ALIEN_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()))
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area < MISN_VENUS)
|
2011-08-24 14:14:44 +02:00
|
|
|
missionFinishedScreen();
|
|
|
|
|
|
|
|
switch (currentGame.area)
|
|
|
|
{
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_MOEBO:
|
2011-08-24 14:14:44 +02:00
|
|
|
doCutscene(1);
|
|
|
|
doCutscene(2);
|
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_NEROD:
|
2011-08-24 14:14:44 +02:00
|
|
|
doCutscene(3);
|
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_ELAMALE:
|
2011-08-24 14:14:44 +02:00
|
|
|
doCutscene(4);
|
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_ODEON:
|
2011-08-24 14:14:44 +02:00
|
|
|
doCutscene(5);
|
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_ELLESH:
|
2011-08-24 14:14:44 +02:00
|
|
|
doCutscene(6);
|
|
|
|
break;
|
2015-03-29 19:11:12 +02:00
|
|
|
case MISN_VENUS:
|
2015-03-04 14:20:11 +01:00
|
|
|
doCredits();
|
2011-08-24 14:14:44 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area < MISN_VENUS)
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
|
|
|
updateSystemStatus();
|
2015-03-03 05:32:48 +01:00
|
|
|
saveGame(0);
|
2011-08-24 14:14:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
rtn = 1;
|
|
|
|
|
2015-03-29 19:11:12 +02:00
|
|
|
if (currentGame.area == MISN_VENUS)
|
2011-08-24 14:14:44 +02:00
|
|
|
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;
|
|
|
|
}
|