Don't restrict enemies from passing through other enemies.

This was inconsistent and had no particular benefits. The only minor
benefit I can see is that it prevents smaller enemies from hiding
inside bigger enemies, and in my test run through Spirit, this only
happened once. Not at all significant compared to how incredibly
awkward the aliens look when they're acting as if they can't move
through other ships.

This commit also includes more function name changes and other minor
style fixes.
This commit is contained in:
onpon4 2015-03-06 09:37:21 -05:00
parent 7ed2d1a991
commit 8a8da04560
5 changed files with 383 additions and 414 deletions

View File

@ -25,29 +25,29 @@ Aliens are assigned various AI types and this routine makes use of them.
Levels of aggression, defence and evasion are all here. Levels of aggression, defence and evasion are all here.
*/ */
void alien_setAI(object *theEnemy) void alien_setAI(object *alien)
{ {
// Make friendly craft generally concentrate on smaller fighters // Make friendly craft generally concentrate on smaller fighters
if ((theEnemy->flags & FL_FRIEND) && (theEnemy->target == &enemy[WC_BOSS])) if ((alien->flags & FL_FRIEND) && (alien->target == &enemy[WC_BOSS]))
{ {
if ((rand() % 5) == 0) if ((rand() % 5) == 0)
{ {
theEnemy->target = theEnemy; alien->target = alien;
theEnemy->thinktime = 0; alien->thinktime = 0;
return; return;
} }
} }
int i = rand() % 10; int i = rand() % 10;
float tx = theEnemy->target->x; float tx = alien->target->x;
float ty = theEnemy->target->y; float ty = alien->target->y;
int chase = 0; // Chance in 10 of chasing player int chase = 0; // Chance in 10 of chasing player
int area = 0; // Chance in 10 of moving to an area around the player int area = 0; // Chance in 10 of moving to an area around the player
int stop = 0; // Chance in 10 of hanging back int stop = 0; // Chance in 10 of hanging back
int point = 0; // Size of area alien will move into int point = 0; // Size of area alien will move into
switch (theEnemy->AIType) switch (alien->AIType)
{ {
case AI_NORMAL: case AI_NORMAL:
chase = 3; chase = 3;
@ -84,8 +84,8 @@ void alien_setAI(object *theEnemy)
if (i <= chase) if (i <= chase)
{ {
// Chase the target // Chase the target
theEnemy->dx = ((theEnemy->x - tx) / ((300 / theEnemy->speed) + rand() % 100)); alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
theEnemy->dy = ((theEnemy->y - ty) / ((300 / theEnemy->speed) + rand() % 100)); alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
return; return;
} }
else if ((i >= point) && (i <= stop)) else if ((i >= point) && (i <= stop))
@ -93,100 +93,100 @@ void alien_setAI(object *theEnemy)
// Fly to a random point around the target // Fly to a random point around the target
tx += (rand() % area - (rand() % area * 2)); tx += (rand() % area - (rand() % area * 2));
ty += (rand() % area - (rand() % area * 2)); ty += (rand() % area - (rand() % area * 2));
theEnemy->dx = ((theEnemy->x - tx) / ((300 / theEnemy->speed) + rand() % 100)); alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
theEnemy->dy = ((theEnemy->y - ty) / ((300 / theEnemy->speed) + rand() % 100)); alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
return; return;
} }
else else
{ {
// Hang back // Hang back
theEnemy->dx = 0; alien->dx = 0;
theEnemy->dy = 0; alien->dy = 0;
return; return;
} }
} }
void alien_setKlineAttackMethod(object *theEnemy) void alien_setKlineAttackMethod(object *alien)
{ {
theEnemy->maxShield -= 500; alien->maxShield -= 500;
if (theEnemy->maxShield == 0) if (alien->maxShield == 0)
theEnemy->flags &= ~FL_CANNOTDIE; alien->flags &= ~FL_CANNOTDIE;
if (theEnemy->maxShield == 1000) if (alien->maxShield == 1000)
{ {
setRadioMessage(FACE_KLINE, "Very good, Bainfield. Now let's get a little more serious...", 1); setRadioMessage(FACE_KLINE, "Very good, Bainfield. Now let's get a little more serious...", 1);
theEnemy->weaponType[0] = W_SPREADSHOT; alien->weaponType[0] = W_SPREADSHOT;
theEnemy->chance[1] = 40; alien->chance[1] = 40;
} }
else if (theEnemy->maxShield == 500) else if (alien->maxShield == 500)
{ {
setRadioMessage(FACE_KLINE, "Your ability to stay alive irritates me!! Try dodging some of these!!", 1); setRadioMessage(FACE_KLINE, "Your ability to stay alive irritates me!! Try dodging some of these!!", 1);
theEnemy->weaponType[0] = W_DIRSHOCKMISSILE; alien->weaponType[0] = W_DIRSHOCKMISSILE;
theEnemy->weaponType[1] = W_DIRSHOCKMISSILE; alien->weaponType[1] = W_DIRSHOCKMISSILE;
theEnemy->chance[0] = 2; alien->chance[0] = 2;
theEnemy->chance[1] = 2; alien->chance[1] = 2;
theEnemy->flags |= FL_AIMS; alien->flags |= FL_AIMS;
} }
else if (theEnemy->maxShield == 0) else if (alien->maxShield == 0)
{ {
setRadioMessage(FACE_KLINE, "ENOUGH!! THIS ENDS NOW!!!", 1); setRadioMessage(FACE_KLINE, "ENOUGH!! THIS ENDS NOW!!!", 1);
theEnemy->weaponType[0] = W_AIMED_SHOT; alien->weaponType[0] = W_AIMED_SHOT;
theEnemy->weaponType[1] = W_MICRO_HOMING_MISSILES; alien->weaponType[1] = W_MICRO_HOMING_MISSILES;
theEnemy->flags |= FL_CANCLOAK; alien->flags |= FL_CANCLOAK;
theEnemy->chance[0] = 100; alien->chance[0] = 100;
theEnemy->chance[1] = 2; alien->chance[1] = 2;
} }
theEnemy->shield = 500; alien->shield = 500;
} }
/* /*
This AI is exclusively for Kline. This AI is exclusively for Kline.
*/ */
void alien_setKlineAI(object *theEnemy) void alien_setKlineAI(object *alien)
{ {
// Weapon type change // Weapon type change
if ((rand() % 3) == 0) if ((rand() % 3) == 0)
{ {
if (currentGame.area != 26) if (currentGame.area != 26)
{ {
theEnemy->flags &= ~FL_AIMS; alien->flags &= ~FL_AIMS;
switch(rand() % 2) switch(rand() % 2)
{ {
case 0: case 0:
theEnemy->weaponType[0] = W_TRIPLE_SHOT; alien->weaponType[0] = W_TRIPLE_SHOT;
break; break;
case 1: case 1:
theEnemy->weaponType[0] = W_AIMED_SHOT; alien->weaponType[0] = W_AIMED_SHOT;
theEnemy->flags |= FL_AIMS; alien->flags |= FL_AIMS;
break; break;
} }
} }
} }
theEnemy->flags &= ~(FL_CIRCLES | FL_CONTINUOUS_FIRE | FL_DROPMINES); alien->flags &= ~(FL_CIRCLES | FL_CONTINUOUS_FIRE | FL_DROPMINES);
switch(rand() % 10) switch(rand() % 10)
{ {
case 0: case 0:
if ((theEnemy->weaponType[0] != W_DIRSHOCKMISSILE) && (theEnemy->weaponType[1] != W_MICRO_HOMING_MISSILES)) if ((alien->weaponType[0] != W_DIRSHOCKMISSILE) && (alien->weaponType[1] != W_MICRO_HOMING_MISSILES))
theEnemy->flags |= FL_CONTINUOUS_FIRE; alien->flags |= FL_CONTINUOUS_FIRE;
theEnemy->dx = ((theEnemy->x - theEnemy->target->x) / ((300 / theEnemy->speed) + rand() % 100)); alien->dx = ((alien->x - alien->target->x) / ((300 / alien->speed) + rand() % 100));
theEnemy->dy = ((theEnemy->y - theEnemy->target->y) / ((300 / theEnemy->speed) + rand() % 100)); alien->dy = ((alien->y - alien->target->y) / ((300 / alien->speed) + rand() % 100));
break; break;
case 1: case 1:
case 2: case 2:
// Kline only attacks then he is ready! // Kline only attacks then he is ready!
if ((!(theEnemy->flags & FL_NOFIRE)) && (currentGame.area == 11)) if ((!(alien->flags & FL_NOFIRE)) && (currentGame.area == 11))
theEnemy->flags |= FL_DROPMINES; alien->flags |= FL_DROPMINES;
break; break;
case 3: case 3:
case 4: case 4:
theEnemy->flags |= FL_CIRCLES; alien->flags |= FL_CIRCLES;
break; break;
default: default:
alien_setAI(theEnemy); alien_setAI(alien);
break; break;
} }
} }

View File

@ -20,8 +20,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef AI_H #ifndef AI_H
#define AI_H #define AI_H
void alien_setAI(object *theEnemy); void alien_setAI(object *alien);
void alien_setKlineAttackMethod(object *theEnemy); void alien_setKlineAttackMethod(object *alien);
void alien_setKlineAI(object *theEnemy); void alien_setKlineAI(object *alien);
#endif #endif

View File

@ -40,29 +40,29 @@ static int alien_getFreeIndex()
return -1; return -1;
} }
static bool alien_place(object *theEnemy) static bool alien_place(object *alien)
{ {
if (rand() % 2 == 0) if (rand() % 2 == 0)
theEnemy->x = rrand(screen->w, screen->w * 2); alien->x = rrand(screen->w, screen->w * 2);
else else
theEnemy->x = rrand(-screen->w, 0); alien->x = rrand(-screen->w, 0);
if (rand() % 2 == 0) if (rand() % 2 == 0)
theEnemy->y = rrand(screen->h, screen->h * 2); alien->y = rrand(screen->h, screen->h * 2);
else else
theEnemy->y = rrand(-screen->h, 0); alien->y = rrand(-screen->h, 0);
if (currentGame.area == 24) if (currentGame.area == 24)
{ {
theEnemy->x = screen->w; alien->x = screen->w;
theEnemy->y = rrand(screen->h / 3, (2 * screen->h) / 3); alien->y = rrand(screen->h / 3, (2 * screen->h) / 3);
} }
for (int i = 0 ; i < MAX_ALIENS ; i++) for (int i = 0 ; i < MAX_ALIENS ; i++)
{ {
if ((enemy[i].owner != theEnemy) && (enemy[i].shield > 0)) if ((enemy[i].owner != alien) && (enemy[i].shield > 0))
{ {
if (collision(theEnemy->x, theEnemy->y, theEnemy->image[0]->w, theEnemy->image[0]->h, enemy[i].x, enemy[i].y, enemy[i].image[0]->w, enemy[i].image[0]->h)) if (collision(alien->x, alien->y, alien->image[0]->w, alien->image[0]->h, enemy[i].x, enemy[i].y, enemy[i].image[0]->w, enemy[i].image[0]->h))
return false; return false;
} }
} }
@ -653,17 +653,17 @@ void initAliens()
"Looks" for an enemy by picking a randomly active enemy and using them "Looks" for an enemy by picking a randomly active enemy and using them
as a target. If the target is too far away, it will be ignored. as a target. If the target is too far away, it will be ignored.
*/ */
static void alien_searchForTarget(object *theEnemy) static void alien_searchForTarget(object *alien)
{ {
int i; int i;
if (theEnemy->flags & FL_WEAPCO) if (alien->flags & FL_WEAPCO)
{ {
i = (rand() % 10); i = (rand() % 10);
if (i == 0) if (i == 0)
{ {
theEnemy->target = &player; alien->target = &player;
return; return;
} }
} }
@ -674,7 +674,7 @@ static void alien_searchForTarget(object *theEnemy)
// Tell Sid not to attack craft that are already disabled or can // Tell Sid not to attack craft that are already disabled or can
// return fire. This will save him from messing about (unless we're on the last mission) // return fire. This will save him from messing about (unless we're on the last mission)
if ((theEnemy->classDef == CD_SID) && (currentGame.area != 25)) if ((alien->classDef == CD_SID) && (currentGame.area != 25))
{ {
if ((targetEnemy->flags & FL_DISABLED) || (!(targetEnemy->flags & FL_NOFIRE))) if ((targetEnemy->flags & FL_DISABLED) || (!(targetEnemy->flags & FL_NOFIRE)))
return; return;
@ -683,7 +683,7 @@ static void alien_searchForTarget(object *theEnemy)
// Tell Phoebe and Ursula not to attack ships that cannot fire or are disabled (unless we're on the last mission) // Tell Phoebe and Ursula not to attack ships that cannot fire or are disabled (unless we're on the last mission)
if (currentGame.area != 25) if (currentGame.area != 25)
{ {
if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA)) if ((alien->classDef == CD_PHOEBE) || (alien->classDef == CD_URSULA))
{ {
// Don't attack the boss or we could be here all day(!) // Don't attack the boss or we could be here all day(!)
if (targetEnemy->classDef == CD_BOSS) if (targetEnemy->classDef == CD_BOSS)
@ -697,55 +697,55 @@ static void alien_searchForTarget(object *theEnemy)
if ((targetEnemy->shield < 1) || (!targetEnemy->active)) if ((targetEnemy->shield < 1) || (!targetEnemy->active))
return; return;
if ((targetEnemy->flags & FL_WEAPCO) && (theEnemy->flags & FL_WEAPCO)) if ((targetEnemy->flags & FL_WEAPCO) && (alien->flags & FL_WEAPCO))
return; return;
if ((targetEnemy->flags & FL_FRIEND) && (theEnemy->flags & FL_FRIEND)) if ((targetEnemy->flags & FL_FRIEND) && (alien->flags & FL_FRIEND))
return; return;
if (abs((int)theEnemy->x - (int)theEnemy->target->x) > 550) if (abs((int)alien->x - (int)alien->target->x) > 550)
return; return;
if (abs((int)theEnemy->y - (int)theEnemy->target->y) > 400) if (abs((int)alien->y - (int)alien->target->y) > 400)
return; return;
theEnemy->target = targetEnemy; alien->target = targetEnemy;
} }
static int alien_checkTarget(object *theEnemy) static int alien_checkTarget(object *alien)
{ {
// Do various checks to see if the alien can fire at // Do various checks to see if the alien can fire at
// the target. Start with the most obvious checks. // the target. Start with the most obvious checks.
// No target // No target
if (theEnemy->target == theEnemy) if (alien->target == alien)
return 0; return 0;
// Whilst firing a Ray, no other weapons can be fired! // Whilst firing a Ray, no other weapons can be fired!
if (theEnemy->flags & FL_FIRERAY) if (alien->flags & FL_FIRERAY)
return 0; return 0;
// The target is on the same side as you! // The target is on the same side as you!
if ((theEnemy->flags & FL_WEAPCO) && (theEnemy->target->flags & FL_WEAPCO)) if ((alien->flags & FL_WEAPCO) && (alien->target->flags & FL_WEAPCO))
return 0; return 0;
if ((theEnemy->flags & FL_FRIEND) && (theEnemy->target->flags & FL_FRIEND)) if ((alien->flags & FL_FRIEND) && (alien->target->flags & FL_FRIEND))
return 0; return 0;
// You're facing the wrong way // You're facing the wrong way
if ((theEnemy->face == 0) && (theEnemy->target->x < theEnemy->x)) if ((alien->face == 0) && (alien->target->x < alien->x))
return 0; return 0;
if ((theEnemy->face == 1) && (theEnemy->target->x > theEnemy->x)) if ((alien->face == 1) && (alien->target->x > alien->x))
return 0; return 0;
// Slightly more than half a screen away from you // Slightly more than half a screen away from you
if (abs((int)theEnemy->x - (int)theEnemy->target->x) > 550) if (abs((int)alien->x - (int)alien->target->x) > 550)
return 0; return 0;
if ((theEnemy->flags & FL_AIMS) || (theEnemy->flags & FL_CONTINUOUS_FIRE)) if ((alien->flags & FL_AIMS) || (alien->flags & FL_CONTINUOUS_FIRE))
return 1; return 1;
// Not at the correct vertical height // Not at the correct vertical height
if ((theEnemy->y < theEnemy->target->y - 15) || (theEnemy->y > theEnemy->target->y + theEnemy->target->image[0]->h + 15)) if ((alien->y < alien->target->y - 15) || (alien->y > alien->target->y + alien->target->image[0]->h + 15))
return 0; return 0;
return 1; return 1;
@ -755,19 +755,19 @@ static int alien_checkTarget(object *theEnemy)
Currently only used for the allies. Whilst flying around, the allies will fire on Currently only used for the allies. Whilst flying around, the allies will fire on
any enemy craft that enter their line of sight. any enemy craft that enter their line of sight.
*/ */
static int alien_enemiesInFront(object *theEnemy) static int alien_enemiesInFront(object *alien)
{ {
object *anEnemy = enemy; object *anEnemy = enemy;
for (int i = 0 ; i < MAX_ALIENS ; i++) for (int i = 0 ; i < MAX_ALIENS ; i++)
{ {
if ((theEnemy != anEnemy) && (anEnemy->flags & FL_WEAPCO) && (anEnemy->shield > 0)) if ((alien != anEnemy) && (anEnemy->flags & FL_WEAPCO) && (anEnemy->shield > 0))
{ {
if ((theEnemy->y > anEnemy->y - 15) && (theEnemy->y < anEnemy->y + anEnemy->image[0]->h + 15)) if ((alien->y > anEnemy->y - 15) && (alien->y < anEnemy->y + anEnemy->image[0]->h + 15))
{ {
if ((theEnemy->face == 1) && (anEnemy->x < theEnemy->x)) if ((alien->face == 1) && (anEnemy->x < alien->x))
return 1; return 1;
if ((theEnemy->face == 0) && (anEnemy->x > theEnemy->x)) if ((alien->face == 0) && (anEnemy->x > alien->x))
return 1; return 1;
} }
} }
@ -778,40 +778,37 @@ static int alien_enemiesInFront(object *theEnemy)
return 0; return 0;
} }
static void moveAndSeparate(object *theEnemy) static void alien_move(object *alien)
{ {
bool checkCollisions = true; bool checkCollisions;
bool hasCollided = false;
// don't worry about bumping into other craft if ((alien->flags & FL_LEAVESECTOR) || (alien->shield < 1))
if ((theEnemy->flags & FL_LEAVESECTOR) || (theEnemy->classDef == CD_DRONE) || (currentGame.area == 18))
checkCollisions = false; checkCollisions = false;
else
checkCollisions = true;
if (theEnemy->shield < 1) if (alien->owner == alien)
checkCollisions = false;
if (theEnemy->owner == theEnemy)
{ {
if (theEnemy->flags & FL_CIRCLES) if (alien->flags & FL_CIRCLES)
{ {
if (theEnemy->face == 0) if (alien->face == 0)
{ {
theEnemy->dx += 0.02; alien->dx += 0.02;
theEnemy->dy += 0.02; alien->dy += 0.02;
} }
else else
{ {
theEnemy->dx -= 0.02; alien->dx -= 0.02;
theEnemy->dy -= 0.02; alien->dy -= 0.02;
} }
theEnemy->x -= (sinf(theEnemy->dx) * 4); alien->x -= (sinf(alien->dx) * 4);
theEnemy->y -= (cosf(theEnemy->dy) * 4); alien->y -= (cosf(alien->dy) * 4);
} }
else else
{ {
theEnemy->x -= theEnemy->dx; alien->x -= alien->dx;
theEnemy->y -= theEnemy->dy; alien->y -= alien->dy;
} }
} }
@ -821,25 +818,22 @@ static void moveAndSeparate(object *theEnemy)
{ {
for (int i = 0 ; i < MAX_ALIENS ; i++) for (int i = 0 ; i < MAX_ALIENS ; i++)
{ {
if ((theEnemy->flags & FL_LEAVESECTOR) || (theEnemy->classDef == CD_DRONE) || (theEnemy->classDef == CD_ASTEROID2) || (theEnemy->owner == anEnemy->owner) || (theEnemy->owner->owner == anEnemy->owner) || (anEnemy->shield < 1)) if ((alien->flags & FL_LEAVESECTOR) || (alien->classDef == CD_DRONE) || (alien->classDef == CD_ASTEROID2) || (alien->owner == anEnemy->owner) || (alien->owner->owner == anEnemy->owner) || (anEnemy->shield < 1))
{ {
anEnemy++; anEnemy++;
continue; continue;
} }
if (collision(theEnemy, anEnemy)) if (collision(alien, anEnemy))
{ {
if ((anEnemy->classDef == CD_BARRIER) && (anEnemy->owner != theEnemy)) if ((anEnemy->classDef == CD_BARRIER) && (anEnemy->owner != alien))
{ {
theEnemy->shield--; alien->shield--;
theEnemy->hit = 3; alien->hit = 3;
theEnemy->dx *= -1; alien->dx *= -1;
theEnemy->dy *= -1; alien->dy *= -1;
playSound(SFX_HIT, theEnemy->x); playSound(SFX_HIT, alien->x);
} }
if (anEnemy->owner == anEnemy)
hasCollided = true;
} }
anEnemy++; anEnemy++;
@ -847,35 +841,33 @@ static void moveAndSeparate(object *theEnemy)
} }
// Handle a collision with the player // Handle a collision with the player
if ((player.shield > 0) && (theEnemy->shield > 0) && (checkCollisions)) if ((player.shield > 0) && (alien->shield > 0) && (checkCollisions))
{ {
if (collision(theEnemy, &player)) if (collision(alien, &player))
{ {
hasCollided = true; if (alien->classDef == CD_ASTEROID)
if (theEnemy->classDef == CD_ASTEROID)
{ {
if (!engine.cheatShield) if (!engine.cheatShield)
player.shield -= theEnemy->shield; player.shield -= alien->shield;
theEnemy->shield = 0; alien->shield = 0;
playSound(SFX_EXPLOSION, theEnemy->x); playSound(SFX_EXPLOSION, alien->x);
setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED); setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED);
player.hit = 5; player.hit = 5;
playSound(SFX_HIT, player.x); playSound(SFX_HIT, player.x);
} }
if (theEnemy->classDef == CD_ASTEROID2) if (alien->classDef == CD_ASTEROID2)
{ {
if (!engine.cheatShield) if (!engine.cheatShield)
player.shield -= theEnemy->shield; player.shield -= alien->shield;
theEnemy->shield = 0; alien->shield = 0;
playSound(SFX_EXPLOSION, theEnemy->x); playSound(SFX_EXPLOSION, alien->x);
setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED); setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED);
player.hit = 5; player.hit = 5;
playSound(SFX_HIT, player.x); playSound(SFX_HIT, player.x);
} }
if (theEnemy->classDef == CD_BARRIER) if (alien->classDef == CD_BARRIER)
{ {
if (!engine.cheatShield) if (!engine.cheatShield)
player.shield--; player.shield--;
@ -884,45 +876,6 @@ static void moveAndSeparate(object *theEnemy)
} }
} }
} }
// Got back to where you originally were...
if (theEnemy->owner == theEnemy)
{
if (hasCollided)
{
if (theEnemy->flags & FL_CIRCLES)
{
if (theEnemy->face == 0)
{
theEnemy->dx -= 0.02;
theEnemy->dy -= 0.02;
}
else
{
theEnemy->dx += 0.02;
theEnemy->dy += 0.02;
}
theEnemy->x += (sinf(theEnemy->dx) * 4);
theEnemy->y += (cosf(theEnemy->dy) * 4);
theEnemy->thinktime = 0;
}
else
{
theEnemy->x += theEnemy->dx;
theEnemy->y += theEnemy->dy;
theEnemy->dx *= -1;
theEnemy->dy *= -1;
theEnemy->dx *= 0.2;
theEnemy->dy *= 0.2;
limitInt(&theEnemy->thinktime, 0, 15);
}
}
}
} }
/* /*
@ -938,6 +891,8 @@ void mission_killAllEnemies()
} }
} }
// XXX: This function is used in only one place, the main game loop.
// Should probably be moved to there.
void doAliens() void doAliens()
{ {
static float barrierLoop = 0; static float barrierLoop = 0;
@ -950,130 +905,130 @@ void doAliens()
bool canFire; bool canFire;
int shapeToUse; int shapeToUse;
object *theEnemy = enemy; object *alien = enemy;
for (int i = 0 ; i < MAX_ALIENS ; i++) for (int i = 0 ; i < MAX_ALIENS ; i++)
{ {
if (theEnemy->active) if (alien->active)
{ {
if (theEnemy->shield > 0) if (alien->shield > 0)
{ {
if ((theEnemy->flags & FL_WEAPCO) && (!(theEnemy->flags & FL_DISABLED))) if ((alien->flags & FL_WEAPCO) && (!(alien->flags & FL_DISABLED)))
engine.allAliensDead = 0; engine.allAliensDead = 0;
// Set part attributes // Set part attributes
if (theEnemy->owner != theEnemy) if (alien->owner != alien)
{ {
theEnemy->face = theEnemy->owner->face; alien->face = alien->owner->face;
if (theEnemy->face == 0) if (alien->face == 0)
theEnemy->x = theEnemy->owner->x - theEnemy->dx; alien->x = alien->owner->x - alien->dx;
else else
theEnemy->x = theEnemy->owner->x + theEnemy->owner->image[0]->w + theEnemy->dx - theEnemy->image[0]->w; alien->x = alien->owner->x + alien->owner->image[0]->w + alien->dx - alien->image[0]->w;
theEnemy->y = (theEnemy->owner->y + theEnemy->dy); alien->y = (alien->owner->y + alien->dy);
if (theEnemy->owner->shield < 1) if (alien->owner->shield < 1)
{ {
if ((theEnemy->classDef != CD_URANUSBOSSWING1) && (theEnemy->classDef != CD_URANUSBOSSWING2)) if ((alien->classDef != CD_URANUSBOSSWING1) && (alien->classDef != CD_URANUSBOSSWING2))
{ {
theEnemy->shield = 0; alien->shield = 0;
} }
else else
{ {
theEnemy->flags &= ~FL_IMMORTAL; alien->flags &= ~FL_IMMORTAL;
theEnemy->owner = theEnemy; alien->owner = alien;
theEnemy->chance[0] = 25; alien->chance[0] = 25;
} }
} }
} }
canFire = true; // The alien is allowed to fire canFire = true; // The alien is allowed to fire
limitInt(&--theEnemy->thinktime, 0, 250); limitInt(&--alien->thinktime, 0, 250);
if (theEnemy->target->shield < 1) if (alien->target->shield < 1)
theEnemy->target = theEnemy; alien->target = alien;
// Specific to Sid to stop him pissing about(!) // Specific to Sid to stop him pissing about(!)
if ((theEnemy->classDef == CD_SID) && if ((alien->classDef == CD_SID) &&
(theEnemy->target->flags & FL_DISABLED)) (alien->target->flags & FL_DISABLED))
theEnemy->target = theEnemy; alien->target = alien;
if (theEnemy->target == theEnemy) if (alien->target == alien)
{ {
if (engine.missionCompleteTimer == 0) if (engine.missionCompleteTimer == 0)
{ {
alien_searchForTarget(theEnemy); alien_searchForTarget(alien);
} }
else else
{ {
if (theEnemy->flags & FL_FRIEND) if (alien->flags & FL_FRIEND)
{ {
theEnemy->target = &player; alien->target = &player;
theEnemy->thinktime = 1; alien->thinktime = 1;
} }
} }
} }
if ((!(theEnemy->flags & FL_DISABLED)) && (theEnemy->thinktime == 0) && (theEnemy->target != theEnemy) && (theEnemy->owner == theEnemy)) if ((!(alien->flags & FL_DISABLED)) && (alien->thinktime == 0) && (alien->target != alien) && (alien->owner == alien))
{ {
if (theEnemy->classDef == CD_KLINE) if (alien->classDef == CD_KLINE)
alien_setKlineAI(theEnemy); alien_setKlineAI(alien);
else else
alien_setAI(theEnemy); alien_setAI(alien);
theEnemy->thinktime = (rand() % 25) * 10; alien->thinktime = (rand() % 25) * 10;
// Face direction of movement unless you always face your target(!) // Face direction of movement unless you always face your target(!)
if (!(theEnemy->flags & FL_ALWAYSFACE)) if (!(alien->flags & FL_ALWAYSFACE))
{ {
theEnemy->face = 0; alien->face = 0;
if (theEnemy->dx > 0) theEnemy->face = 1; if (alien->dx > 0) alien->face = 1;
} }
limitFloat(&theEnemy->dx, 0 - theEnemy->speed, theEnemy->speed); limitFloat(&alien->dx, 0 - alien->speed, alien->speed);
limitFloat(&theEnemy->dy, 0 - theEnemy->speed, theEnemy->speed); limitFloat(&alien->dy, 0 - alien->speed, alien->speed);
} }
if (theEnemy->flags & FL_ALWAYSFACE) if (alien->flags & FL_ALWAYSFACE)
{ {
theEnemy->face = 0; alien->face = 0;
if (theEnemy->x > theEnemy->target->x) theEnemy->face = 1; if (alien->x > alien->target->x) alien->face = 1;
} }
if ((currentGame.area == 18) && (theEnemy->classDef == CD_BOSS)) if ((currentGame.area == 18) && (alien->classDef == CD_BOSS))
theEnemy->face = 0; alien->face = 0;
if ((theEnemy->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0)) if ((alien->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0))
alien_addDrone(theEnemy); alien_addDrone(alien);
if (theEnemy->flags & FL_LEAVESECTOR) if (alien->flags & FL_LEAVESECTOR)
{ {
limitFloat(&(theEnemy->dx -= 0.5), 0, -15); limitFloat(&(alien->dx -= 0.5), 0, -15);
theEnemy->dy = 0; alien->dy = 0;
theEnemy->thinktime = 999; alien->thinktime = 999;
theEnemy->face = 0; alien->face = 0;
if (theEnemy->x >= 5000) if (alien->x >= 5000)
{ {
theEnemy->flags -= FL_LEAVESECTOR; alien->flags -= FL_LEAVESECTOR;
theEnemy->flags += FL_ESCAPED; alien->flags += FL_ESCAPED;
theEnemy->active = false; alien->active = false;
if (theEnemy->classDef == CD_CLOAKFIGHTER) if (alien->classDef == CD_CLOAKFIGHTER)
{ {
currentGame.experimentalShield = theEnemy->shield; currentGame.experimentalShield = alien->shield;
setInfoLine("Experimental Fighter has fled", FONT_CYAN); setInfoLine("Experimental Fighter has fled", FONT_CYAN);
} }
theEnemy->shield = 0; alien->shield = 0;
updateMissionRequirements(M_ESCAPE_TARGET, theEnemy->classDef, 1); updateMissionRequirements(M_ESCAPE_TARGET, alien->classDef, 1);
if (theEnemy->classDef != CD_CLOAKFIGHTER) if (alien->classDef != CD_CLOAKFIGHTER)
updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->classDef, 1); updateMissionRequirements(M_DESTROY_TARGET_TYPE, alien->classDef, 1);
} }
} }
@ -1082,46 +1037,46 @@ void doAliens()
It can cloak and uncloak at random. When cloaked, it's sprite is It can cloak and uncloak at random. When cloaked, it's sprite is
not displayed. However the engine trail is still visible! not displayed. However the engine trail is still visible!
*/ */
if ((theEnemy->flags & FL_CANCLOAK) && ((rand() % 500) == 0)) if ((alien->flags & FL_CANCLOAK) && ((rand() % 500) == 0))
{ {
if (theEnemy->flags & FL_ISCLOAKED) if (alien->flags & FL_ISCLOAKED)
theEnemy->flags -= FL_ISCLOAKED; alien->flags -= FL_ISCLOAKED;
else else
theEnemy->flags += FL_ISCLOAKED; alien->flags += FL_ISCLOAKED;
playSound(SFX_CLOAK, theEnemy->x); playSound(SFX_CLOAK, alien->x);
} }
// ------------ Barriers ------------------ // ------------ Barriers ------------------
if (theEnemy->classDef == CD_BARRIER) if (alien->classDef == CD_BARRIER)
{ {
theEnemy->dx = -10 + (sinf(barrierLoop + theEnemy->speed) * 60); alien->dx = -10 + (sinf(barrierLoop + alien->speed) * 60);
theEnemy->dy = 20 + (cosf(barrierLoop + theEnemy->speed) * 40); alien->dy = 20 + (cosf(barrierLoop + alien->speed) * 40);
} }
// ---------------------------------------- // ----------------------------------------
// ------------ Mobile Shields ------------ // ------------ Mobile Shields ------------
if (theEnemy->classDef == CD_MOBILESHIELD) if (alien->classDef == CD_MOBILESHIELD)
{ {
limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield); limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield);
} }
// ---------------------------------------- // ----------------------------------------
limitCharAdd(&theEnemy->reload[0], -1, 0, 999); limitCharAdd(&alien->reload[0], -1, 0, 999);
limitCharAdd(&theEnemy->reload[1], -1, 0, 999); limitCharAdd(&alien->reload[1], -1, 0, 999);
if ((!(theEnemy->flags & FL_DISABLED)) && if ((!(alien->flags & FL_DISABLED)) &&
(!(theEnemy->flags & FL_NOFIRE))) (!(alien->flags & FL_NOFIRE)))
{ {
if ((theEnemy->target->shield > 0)) if ((alien->target->shield > 0))
canFire = alien_checkTarget(theEnemy); canFire = alien_checkTarget(alien);
if (((theEnemy->thinktime % 2) == 0) && if (((alien->thinktime % 2) == 0) &&
(theEnemy->flags & FL_FRIEND)) (alien->flags & FL_FRIEND))
canFire = alien_enemiesInFront(theEnemy); canFire = alien_enemiesInFront(alien);
} }
else else
{ {
@ -1130,138 +1085,140 @@ void doAliens()
if ((canFire) && (dev.fireAliens)) if ((canFire) && (dev.fireAliens))
{ {
if ((theEnemy->reload[0] == 0) && if ((alien->reload[0] == 0) &&
((rand() % 1000 < theEnemy->chance[0]) || ((rand() % 1000 < alien->chance[0]) ||
(theEnemy->flags & FL_CONTINUOUS_FIRE))) (alien->flags & FL_CONTINUOUS_FIRE)))
{ {
fireBullet(theEnemy, 0); fireBullet(alien, 0);
} }
if ((theEnemy->reload[1] == 0) && if ((alien->reload[1] == 0) &&
((rand() % 1000 < theEnemy->chance[1]) || ((rand() % 1000 < alien->chance[1]) ||
(theEnemy->flags & FL_CONTINUOUS_FIRE))) (alien->flags & FL_CONTINUOUS_FIRE)))
{ {
if ((theEnemy->weaponType[1] != W_ENERGYRAY) && if ((alien->weaponType[1] != W_ENERGYRAY) &&
(theEnemy->weaponType[1] != W_LASER)) (alien->weaponType[1] != W_LASER))
{ {
if (theEnemy->weaponType[1] == W_CHARGER) if (alien->weaponType[1] == W_CHARGER)
theEnemy->ammo[1] = 50 + rand() % 150; alien->ammo[1] = 50 + rand() % 150;
fireBullet(theEnemy, 1); fireBullet(alien, 1);
} }
else if (theEnemy->weaponType[1] == W_LASER) else if (alien->weaponType[1] == W_LASER)
{ {
theEnemy->flags += FL_FIRELASER; alien->flags += FL_FIRELASER;
} }
else if ((theEnemy->weaponType[1] == W_ENERGYRAY) && else if ((alien->weaponType[1] == W_ENERGYRAY) &&
(theEnemy->ammo[0] == 250)) (alien->ammo[0] == 250))
{ {
theEnemy->flags += FL_FIRERAY; alien->flags += FL_FIRERAY;
playSound(SFX_ENERGYRAY, theEnemy->x); playSound(SFX_ENERGYRAY, alien->x);
} }
} }
} }
// --------------- Ray specific stuff ------------------ // --------------- Ray specific stuff ------------------
if (theEnemy->flags & FL_FIRERAY) if (alien->flags & FL_FIRERAY)
{ {
fireRay(theEnemy); fireRay(alien);
} }
else else
{ {
limitCharAdd(&theEnemy->ammo[0], 1, 0, 250); limitCharAdd(&alien->ammo[0], 1, 0, 250);
} }
// ------------------------------------------------------- // -------------------------------------------------------
// --------------- Laser specific stuff ------------------ // --------------- Laser specific stuff ------------------
if (theEnemy->flags & FL_FIRELASER) if (alien->flags & FL_FIRELASER)
{ {
fireBullet(theEnemy, 1); fireBullet(alien, 1);
if ((rand() % 25) == 0) if ((rand() % 25) == 0)
theEnemy->flags -= FL_FIRELASER; alien->flags -= FL_FIRELASER;
} }
// ------------------------------------------------------- // -------------------------------------------------------
// ---------------- Mine specific stuff ------------------ // ---------------- Mine specific stuff ------------------
if (theEnemy->flags & FL_DROPMINES) if (alien->flags & FL_DROPMINES)
if ((rand() % 150) == 0) if ((rand() % 150) == 0)
addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, addCollectable(alien->x, alien->y, P_MINE, 25,
600 + rand() % 2400); 600 + rand() % 2400);
// Kline drops mines a lot more often // Kline drops mines a lot more often
if ((theEnemy->flags & FL_DROPMINES) && (theEnemy == &enemy[WC_KLINE])) if ((alien->flags & FL_DROPMINES) && (alien == &enemy[WC_KLINE]))
if ((rand() % 10) == 0) if ((rand() % 10) == 0)
addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, addCollectable(alien->x, alien->y, P_MINE, 25,
600 + rand() % 2400); 600 + rand() % 2400);
// ------------------------------------------------------- // -------------------------------------------------------
shapeToUse = theEnemy->imageIndex[theEnemy->face]; shapeToUse = alien->imageIndex[alien->face];
if (theEnemy->hit) if (alien->hit)
shapeToUse += SHIP_HIT_INDEX; shapeToUse += SHIP_HIT_INDEX;
limitCharAdd(&theEnemy->hit, -1, 0, 100); limitCharAdd(&alien->hit, -1, 0, 100);
if ((theEnemy->x + theEnemy->image[0]->w > 0) && (theEnemy->x < screen->w) && (theEnemy->y + theEnemy->image[0]->h > 0) && (theEnemy->y < screen->h)) if ((alien->x + alien->image[0]->w > 0) && (alien->x < screen->w) && (alien->y + alien->image[0]->h > 0) && (alien->y < screen->h))
{ {
if ((!(theEnemy->flags & FL_DISABLED)) && (theEnemy->classDef != CD_ASTEROID) && (theEnemy->classDef != CD_ASTEROID2)) if ((!(alien->flags & FL_DISABLED)) && (alien->classDef != CD_ASTEROID) && (alien->classDef != CD_ASTEROID2))
addEngine(theEnemy); addEngine(alien);
if ((!(theEnemy->flags & FL_ISCLOAKED)) || (theEnemy->hit > 0)) if ((!(alien->flags & FL_ISCLOAKED)) || (alien->hit > 0))
blit(shipShape[shapeToUse], (int)theEnemy->x, (int)theEnemy->y); blit(shipShape[shapeToUse], (int)alien->x, (int)alien->y);
if (theEnemy->flags & FL_DISABLED) if (alien->flags & FL_DISABLED)
{ {
if ((rand() % 10) == 0) if ((rand() % 10) == 0)
addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_ELECTRICAL); addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_ELECTRICAL);
} }
} }
if ((currentGame.area == 24) && (theEnemy->x < -300)) if ((currentGame.area == 24) && (alien->x < -300))
theEnemy->active = false; alien->active = false;
} }
else else
{ {
theEnemy->shield--; alien->shield--;
if ((theEnemy->x > 0) && (theEnemy->x < screen->w) && (theEnemy->y > 0) && (theEnemy->y < screen->h)) if ((alien->x > 0) && (alien->x < screen->w) && (alien->y > 0) && (alien->y < screen->h))
{ {
blit(theEnemy->image[theEnemy->face], (int)theEnemy->x, (int)theEnemy->y); blit(alien->image[alien->face], (int)alien->x, (int)alien->y);
addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_BIG_EXPLOSION); addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_BIG_EXPLOSION);
} }
if (theEnemy->shield < theEnemy->deathCounter) if (alien->shield < alien->deathCounter)
{ {
theEnemy->active = false; alien->active = false;
if ((theEnemy->classDef == CD_BOSS) || if ((alien->classDef == CD_BOSS) ||
(theEnemy->owner == &enemy[WC_BOSS]) || (alien->owner == &enemy[WC_BOSS]) ||
(theEnemy->flags & FL_FRIEND) || (alien->flags & FL_FRIEND) ||
(theEnemy->classDef == CD_ASTEROID) || (alien->classDef == CD_ASTEROID) ||
(theEnemy->classDef == CD_KLINE)) (alien->classDef == CD_KLINE))
addDebris((int)theEnemy->x, (int)theEnemy->y, addDebris((int)alien->x, (int)alien->y,
theEnemy->maxShield); alien->maxShield);
if (theEnemy->classDef == CD_ASTEROID) if (alien->classDef == CD_ASTEROID)
{ {
int i = 1 + (rand() % 3); int i = 1 + (rand() % 3);
for (int j = 0 ; j < i ; j++) for (int j = 0 ; j < i ; j++)
alien_addSmallAsteroid(theEnemy); alien_addSmallAsteroid(alien);
} }
} }
} }
// Adjust the movement even whilst exploding // Adjust the movement even whilst exploding
if ((dev.moveAliens) && (!(theEnemy->flags & FL_NOMOVE)) && if ((dev.moveAliens) && (!(alien->flags & FL_NOMOVE)) &&
(!(theEnemy->flags & FL_DISABLED))) (!(alien->flags & FL_DISABLED)))
moveAndSeparate(theEnemy); alien_move(alien);
if ((currentGame.area != 18) || (theEnemy->shield < 0)) if ((currentGame.area != 18) || (alien->shield < 0))
theEnemy->x += engine.ssx; alien->x += engine.ssx;
theEnemy->x += engine.smx; alien->x += engine.smx;
theEnemy->y += engine.ssy + engine.smy; alien->y += engine.ssy + engine.smy;
} }
theEnemy++; alien++;
} }
} }
// XXX: This function is called only once, as part of the function that
// loads game graphics. Should probably be merged into that function.
void setAlienShapes() void setAlienShapes()
{ {
for (int i = 0 ; i < MAX_DEFALIENS ; i++) for (int i = 0 ; i < MAX_DEFALIENS ; i++)
@ -1276,6 +1233,8 @@ void setAlienShapes()
} }
} }
// XXX: This function is called only once, before the game starts.
// Should probably be merged into main.
void defineAliens() void defineAliens()
{ {
// Dual Plasma Fighter. // Dual Plasma Fighter.

View File

@ -269,49 +269,51 @@ static object *getRandomEnemy(object *bullet)
/* /*
Fill in later... Fill in later...
*/ */
static void destroyAlien(object *bullet, object *theEnemy) static void alien_destroy(object *alien, object *attacker)
{ {
playSound(SFX_EXPLOSION, theEnemy->x); playSound(SFX_EXPLOSION, alien->x);
// Chain reaction destruction if needed // Chain reaction destruction if needed
if (theEnemy->flags & FL_DAMAGEOWNER) if (alien->flags & FL_DAMAGEOWNER)
{ {
theEnemy->owner->shield -= theEnemy->maxShield; alien->owner->shield -= alien->maxShield;
if (theEnemy->owner->shield < 1) if (alien->owner->shield < 1)
destroyAlien(bullet, theEnemy->owner); alien_destroy(alien->owner, attacker);
} }
if (theEnemy->flags & FL_FRIEND) if (alien->flags & FL_FRIEND)
{ {
if (theEnemy->classDef == CD_PHOEBE) if (alien->classDef == CD_PHOEBE)
currentGame.wingMate1Ejects++; currentGame.wingMate1Ejects++;
else if (theEnemy->classDef == CD_URSULA) else if (alien->classDef == CD_URSULA)
currentGame.wingMate2Ejects++; currentGame.wingMate2Ejects++;
// Phoebe cannot eject on the rescue mission // Phoebe cannot eject on the rescue mission
if (currentGame.area != 7) if (currentGame.area != 7)
{ {
if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA)) if ((alien->classDef == CD_PHOEBE) || (alien->classDef == CD_URSULA))
setInfoLine(">> Ally has ejected! <<\n", FONT_RED); setInfoLine(">> Ally has ejected! <<\n", FONT_RED);
else else
setInfoLine(">> Friendly craft has been destroyed!! <<\n", FONT_RED); setInfoLine(">> Friendly craft has been destroyed!! <<\n", FONT_RED);
} }
} }
if (bullet->owner == &player) if (attacker != NULL)
{
if (attacker == &player)
{ {
// Once again, stop point leeching // Once again, stop point leeching
if (currentGame.area != MAX_MISSIONS - 1) if (currentGame.area != MAX_MISSIONS - 1)
currentGame.cash += theEnemy->score; currentGame.cash += alien->score;
currentGame.cashEarned += theEnemy->score; currentGame.cashEarned += alien->score;
currentGame.totalKills++; currentGame.totalKills++;
updateMissionRequirements(M_COLLECT, P_CASH, theEnemy->score); updateMissionRequirements(M_COLLECT, P_CASH, alien->score);
} }
else if (bullet->owner->classDef == CD_PHOEBE) else if (attacker->classDef == CD_PHOEBE)
{ {
currentGame.wingMate1Kills++; currentGame.wingMate1Kills++;
} }
else if (bullet->owner->classDef == CD_URSULA) else if (attacker->classDef == CD_URSULA)
{ {
currentGame.wingMate2Kills++; currentGame.wingMate2Kills++;
} }
@ -320,49 +322,50 @@ static void destroyAlien(object *bullet, object *theEnemy)
currentGame.totalOtherKills++; currentGame.totalOtherKills++;
} }
if ((bullet->owner->classDef == CD_PHOEBE) || (bullet->owner->classDef == CD_URSULA)) if ((attacker->classDef == CD_PHOEBE) || (attacker->classDef == CD_URSULA))
{ {
if ((rand() % 8) == 0) if ((rand() % 8) == 0)
{ {
getKillMessage(bullet->owner); getKillMessage(attacker);
}
} }
} }
updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->classDef, 1); updateMissionRequirements(M_DESTROY_TARGET_TYPE, alien->classDef, 1);
updateMissionRequirements(M_PROTECT_TARGET, theEnemy->classDef, 1); updateMissionRequirements(M_PROTECT_TARGET, alien->classDef, 1);
if (rand() % 100 <= theEnemy->collectChance) if (rand() % 100 <= alien->collectChance)
{ {
unsigned char value; unsigned char value;
if ((rand() % 10) == 0) if ((rand() % 10) == 0)
theEnemy->collectValue *= 2; alien->collectValue *= 2;
while (theEnemy->collectValue > 0) while (alien->collectValue > 0)
{ {
value = (10 + (rand() % theEnemy->collectValue)); value = (10 + (rand() % alien->collectValue));
if (value > theEnemy->collectValue) if (value > alien->collectValue)
value =theEnemy->collectValue; value =alien->collectValue;
addCollectable(theEnemy->x, theEnemy->y, theEnemy->collectType, value, 600); addCollectable(alien->x, alien->y, alien->collectType, value, 600);
theEnemy->collectValue -= value; alien->collectValue -= value;
} }
} }
// Make it explode immediately // Make it explode immediately
if (theEnemy->classDef == CD_ASTEROID) if (alien->classDef == CD_ASTEROID)
{ {
theEnemy->shield = -999; alien->shield = -999;
} }
if ((theEnemy->classDef == CD_KRASS) && (bullet->owner == &player)) if ((alien->classDef == CD_KRASS) && (attacker == &player))
setRadioMessage(FACE_CHRIS, "My NAME is CHRIS!!!!!!!!", 1); setRadioMessage(FACE_CHRIS, "My NAME is CHRIS!!!!!!!!", 1);
if (theEnemy->classDef == CD_KLINE) if (alien->classDef == CD_KLINE)
{ {
setRadioMessage(FACE_KLINE, "It was an honor... to have fought you...", 1); setRadioMessage(FACE_KLINE, "It was an honor... to have fought you...", 1);
theEnemy->dx = theEnemy->dy = 0; alien->dx = alien->dy = 0;
theEnemy->maxShield = 1500; alien->maxShield = 1500;
theEnemy->shield = -200; alien->shield = -200;
} }
} }
@ -460,7 +463,7 @@ void fireRay(object *attacker)
playSound(SFX_HIT, anEnemy->x); playSound(SFX_HIT, anEnemy->x);
if (anEnemy->shield < 1) if (anEnemy->shield < 1)
{ {
destroyAlien(attacker, anEnemy); alien_destroy(anEnemy, attacker->owner);
} }
} }
} }
@ -489,7 +492,7 @@ void doBullets()
object *prevBullet = engine.bulletHead; object *prevBullet = engine.bulletHead;
engine.bulletTail = engine.bulletHead; engine.bulletTail = engine.bulletHead;
object *theEnemy, *theCargo; object *alien, *theCargo;
bool okayToHit = false; bool okayToHit = false;
float homingMissileSpeed = 0; float homingMissileSpeed = 0;
@ -564,55 +567,55 @@ void doBullets()
for (int i = 0 ; i < MAX_ALIENS ; i++) for (int i = 0 ; i < MAX_ALIENS ; i++)
{ {
theEnemy = &enemy[i]; alien = &enemy[i];
if ((theEnemy->shield < 1) || (!theEnemy->active)) if ((alien->shield < 1) || (!alien->active))
continue; continue;
okayToHit = false; okayToHit = false;
if ((bullet->flags & WF_FRIEND) && (theEnemy->flags & FL_WEAPCO)) if ((bullet->flags & WF_FRIEND) && (alien->flags & FL_WEAPCO))
okayToHit = true; okayToHit = true;
if ((bullet->flags & WF_WEAPCO) && (theEnemy->flags & FL_FRIEND)) if ((bullet->flags & WF_WEAPCO) && (alien->flags & FL_FRIEND))
okayToHit = true; okayToHit = true;
if ((bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER)) if ((bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
okayToHit = true; okayToHit = true;
if (bullet->owner == theEnemy->owner) if (bullet->owner == alien->owner)
okayToHit = false; okayToHit = false;
if (okayToHit) if (okayToHit)
{ {
if ((bullet->active) && (collision(bullet, theEnemy))) if ((bullet->active) && (collision(bullet, alien)))
{ {
if (bullet->owner == &player) if (bullet->owner == &player)
{ {
currentGame.hits++; currentGame.hits++;
if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA)) if ((alien->classDef == CD_PHOEBE) || (alien->classDef == CD_URSULA))
getMissFireMessage(theEnemy); getMissFireMessage(alien);
} }
if (!(theEnemy->flags & FL_IMMORTAL)) if (!(alien->flags & FL_IMMORTAL))
{ {
if (!(bullet->flags & WF_DISABLE)) if (!(bullet->flags & WF_DISABLE))
theEnemy->shield -= bullet->damage; alien->shield -= bullet->damage;
else else
theEnemy->systemPower -= bullet->damage; alien->systemPower -= bullet->damage;
theEnemy->hit = 5; alien->hit = 5;
} }
if (theEnemy->flags & FL_CANNOTDIE) if (alien->flags & FL_CANNOTDIE)
{ {
limitInt(&theEnemy->shield, 1, theEnemy->maxShield); limitInt(&alien->shield, 1, alien->maxShield);
if (theEnemy->shield == 1) if (alien->shield == 1)
{ {
if (currentGame.area != 26) if (currentGame.area != 26)
{ {
if (!(theEnemy->flags & FL_LEAVESECTOR)) if (!(alien->flags & FL_LEAVESECTOR))
{ {
theEnemy->flags |= FL_LEAVESECTOR; alien->flags |= FL_LEAVESECTOR;
theEnemy->flags &= ~FL_CIRCLES; alien->flags &= ~FL_CIRCLES;
if (currentGame.area == 11) if (currentGame.area == 11)
setRadioMessage(FACE_KLINE, "Seems I underestimated you, Bainfield! We'll meet again!", 1); setRadioMessage(FACE_KLINE, "Seems I underestimated you, Bainfield! We'll meet again!", 1);
else if (currentGame.area == 25) else if (currentGame.area == 25)
@ -621,14 +624,14 @@ void doBullets()
} }
else else
{ {
alien_setKlineAttackMethod(theEnemy); alien_setKlineAttackMethod(alien);
} }
} }
} }
if ((theEnemy->flags & FL_RUNSAWAY) && ((rand() % 50) == 0)) if ((alien->flags & FL_RUNSAWAY) && ((rand() % 50) == 0))
{ {
theEnemy->flags |= FL_LEAVESECTOR; alien->flags |= FL_LEAVESECTOR;
} }
if (bullet->id != WT_CHARGER) if (bullet->id != WT_CHARGER)
@ -638,29 +641,29 @@ void doBullets()
} }
else if (bullet->id == WT_CHARGER) else if (bullet->id == WT_CHARGER)
{ {
bullet->shield -= theEnemy->shield; bullet->shield -= alien->shield;
if (bullet->shield < 0) if (bullet->shield < 0)
bullet->active = false; bullet->active = false;
} }
playSound(SFX_HIT, theEnemy->x); playSound(SFX_HIT, alien->x);
if (theEnemy->AIType == AI_EVASIVE) if (alien->AIType == AI_EVASIVE)
theEnemy->thinktime = 0; alien->thinktime = 0;
if (theEnemy->shield < 1) if (alien->shield < 1)
destroyAlien(bullet, theEnemy); alien_destroy(alien, bullet->owner);
if (theEnemy->systemPower < 1) if (alien->systemPower < 1)
{ {
if (!(theEnemy->flags & FL_DISABLED)) if (!(alien->flags & FL_DISABLED))
{ {
theEnemy->flags += FL_DISABLED; alien->flags += FL_DISABLED;
updateMissionRequirements(M_DISABLE_TARGET, theEnemy->classDef, 1); updateMissionRequirements(M_DISABLE_TARGET, alien->classDef, 1);
} }
theEnemy->systemPower = 0; alien->systemPower = 0;
if (theEnemy->classDef == CD_KLINE) if (alien->classDef == CD_KLINE)
theEnemy->systemPower = theEnemy->maxShield; alien->systemPower = alien->maxShield;
} }
if (bullet->id == WT_ROCKET) if (bullet->id == WT_ROCKET)
@ -700,7 +703,7 @@ void doBullets()
} }
else if (bullet->id == WT_CHARGER) else if (bullet->id == WT_CHARGER)
{ {
bullet->shield -= theEnemy->shield; bullet->shield -= alien->shield;
if (bullet->shield < 0) if (bullet->shield < 0)
bullet->active = false; bullet->active = false;
} }

View File

@ -34,6 +34,10 @@ void loadGameGraphics()
{ {
int index; int index;
char string[75] = ""; char string[75] = "";
FILE *fp;
uint32_t *p32;
uint16_t *p16;
uint8_t *p8;
freeGraphics(); freeGraphics();
@ -56,8 +60,6 @@ void loadGameGraphics()
break; break;
} }
FILE *fp;
fp = fopen(string, "rb"); fp = fopen(string, "rb");
if (fp == NULL) if (fp == NULL)
@ -81,33 +83,38 @@ void loadGameGraphics()
shipShape[i- SHIP_HIT_INDEX]->h); shipShape[i- SHIP_HIT_INDEX]->h);
blit(shipShape[i - SHIP_HIT_INDEX], 0, 0, shipShape[i]); blit(shipShape[i - SHIP_HIT_INDEX], 0, 0, shipShape[i]);
switch(shipShape[i]->format->BytesPerPixel) { switch (shipShape[i]->format->BytesPerPixel)
case 4: { {
uint32_t *p = (uint32_t *)shipShape[i]->pixels; case 4:
p32 = (uint32_t *)shipShape[i]->pixels;
for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++) for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++)
if (p[j]) {
p[j] |= shipShape[i]->format->Rmask; if (p32[j])
p32[j] |= shipShape[i]->format->Rmask;
}
break;
case 2:
p16 = (uint16_t *)shipShape[i]->pixels;
for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++)
{
if (p16[j])
p16[j] |= shipShape[i]->format->Rmask;
}
break;
case 1:
p8 = (uint8_t *)shipShape[i]->pixels;
for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++)
{
if (p8[j])
p8[j] = SDL_MapRGB(shipShape[i]->format, 255, 0, 0);
}
break; break;
} }
case 2: { SDL_SetColorKey(shipShape[i], SDL_TRUE,
uint16_t *p = (uint16_t *)shipShape[i]->pixels; SDL_MapRGB(shipShape[i]->format, 0, 0, 0));
for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++)
if (p[j])
p[j] |= shipShape[i]->format->Rmask;
break;
}
case 1: {
uint8_t *p = (uint8_t *)shipShape[i]->pixels;
for (int j = 0; j < shipShape[i]->w * shipShape[i]->h; j++)
if (p[j])
p[j] = SDL_MapRGB(shipShape[i]->format, 255, 0, 0);
break;
}
}
SDL_SetColorKey(shipShape[i], SDL_TRUE, SDL_MapRGB(shipShape[i]->format, 0, 0, 0));
} }
strcpy(string, "data/resources_all.dat"); strcpy(string, "data/resources_all.dat");