📄 aliens.cpp
字号:
{
theEnemy->shield--;
theEnemy->hit = 3;
theEnemy->dx *= -1;
theEnemy->dy *= -1;
playSound(SFX_HIT);
}
if (anEnemy->owner == anEnemy)
hasCollided = 1;
}
*anEnemy++;
}
}
// Handle a collision with the player
if ((player.shield > 0) && (theEnemy->shield > 0) && (checkCollisions))
{
if (Collision::collision(theEnemy, &player))
{
hasCollided = 1;
if (theEnemy->classDef == CD_ASTEROID)
{
if (!engine.cheatShield)
player.shield -= theEnemy->shield;
theEnemy->shield = 0;
playSound(SFX_EXPLOSION);
setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED);
player.hit = 5;
playSound(SFX_HIT);
}
if (theEnemy->classDef == CD_ASTEROID2)
{
if (!engine.cheatShield)
player.shield -= theEnemy->shield;
theEnemy->shield = 0;
playSound(SFX_EXPLOSION);
setInfoLine("Warning: Asteroid Collision Damage!!", FONT_RED);
player.hit = 5;
playSound(SFX_HIT);
}
if (theEnemy->classDef == CD_BARRIER)
{
if (!engine.cheatShield)
player.shield--;
player.hit = 5;
playSound(SFX_HIT);
}
}
}
// 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 += (sin(theEnemy->dx) * 4);
theEnemy->y += (cos(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;
Math::limitInt(&theEnemy->thinktime, 0, 15);
}
}
}
}
/*
Call this whenever a mission requires all the remaining aliens to
automatically die
*/
void killAllAliens()
{
for (int i = 0 ; i < MAX_ALIENS ; i++)
{
if ((enemy[i].flags & FL_WEAPCO) && (enemy[i].active) && (enemy[i].shield > 0))
enemy[i].shield = 0;
}
}
void doAliens()
{
static float barrierLoop = 0;
barrierLoop += 0.2;
// A global variable for checking if all the aliens are dead
engine.allAliensDead = 1;
signed char canFire;
int shapeToUse;
object *theEnemy = enemy;
for (int i = 0 ; i < MAX_ALIENS ; i++)
{
if (theEnemy->active)
{
if (theEnemy->shield > 0)
{
if ((theEnemy->flags & FL_WEAPCO) && (!(theEnemy->flags & FL_DISABLED)))
engine.allAliensDead = 0;
// Set part attributes
if (theEnemy->owner != theEnemy)
{
theEnemy->face = theEnemy->owner->face;
if (theEnemy->face == 0)
theEnemy->x = theEnemy->owner->x - theEnemy->dx;
else
theEnemy->x = theEnemy->owner->x + theEnemy->owner->image[0]->w + theEnemy->dx - theEnemy->image[0]->w;
theEnemy->y = (theEnemy->owner->y + theEnemy->dy);
if (theEnemy->owner->shield < 1)
{
if ((theEnemy->classDef != CD_URANUSBOSSWING1) && (theEnemy->classDef != CD_URANUSBOSSWING2))
{
theEnemy->shield = 0;
}
else
{
theEnemy->flags -= FL_IMMORTAL;
theEnemy->owner = theEnemy;
theEnemy->chance[0] = 25;
}
}
}
canFire = 1; // The alien is allowed to fire
Math::limitInt(&--theEnemy->thinktime, 0, 250);
if (theEnemy->target->shield < 1)
theEnemy->target = theEnemy;
// Specific to Sid to stop him pissing about(!)
if ((theEnemy->classDef == CD_SID) && (theEnemy->target->flags & FL_DISABLED))
theEnemy->target = theEnemy;
if (theEnemy->target == theEnemy)
{
if (engine.missionCompleteTimer == 0)
{
searchForTarget(theEnemy);
}
else
{
if (theEnemy->flags & FL_FRIEND)
{
theEnemy->target = &player;
theEnemy->thinktime = 1;
}
}
}
if ((!(theEnemy->flags & FL_DISABLED)) && (theEnemy->thinktime == 0) && (theEnemy->target != theEnemy) && (theEnemy->owner == theEnemy))
{
if (theEnemy->classDef != CD_KLINE)
setEnemyAI(theEnemy);
else
setKlineAI(theEnemy);
theEnemy->thinktime = (rand() % 25) * 10;
// Face direction of movement unless you always face your target(!)
if (!(theEnemy->flags & FL_ALWAYSFACE))
{
theEnemy->face = 0;
if (theEnemy->dx > 0) theEnemy->face = 1;
}
Math::limitFloat(&theEnemy->dx, 0 - theEnemy->speed, theEnemy->speed);
Math::limitFloat(&theEnemy->dy, 0 - theEnemy->speed, theEnemy->speed);
}
if (theEnemy->flags & FL_ALWAYSFACE)
{
theEnemy->face = 0;
if (theEnemy->x > theEnemy->target->x) theEnemy->face = 1;
}
if ((currentGame.area == 18) && (theEnemy->classDef == CD_BOSS))
theEnemy->face = 0;
if ((theEnemy->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0))
addDrone(theEnemy);
if (theEnemy->flags & FL_LEAVESECTOR)
{
Math::limitFloat(&(theEnemy->dx -= 0.5), 0, -15);
theEnemy->dy = 0;
theEnemy->thinktime = 999;
theEnemy->face = 0;
if (theEnemy->x >= 5000)
{
theEnemy->flags -= FL_LEAVESECTOR;
theEnemy->flags += FL_ESCAPED;
theEnemy->active = 0;
if (theEnemy->classDef == CD_CLOAKFIGHTER)
{
currentGame.experimentalShield = theEnemy->shield;
setInfoLine("Experimental Fighter has fled", FONT_CYAN);
}
theEnemy->shield = 0;
updateMissionRequirements(M_ESCAPE_TARGET, theEnemy->classDef, 1);
if (theEnemy->classDef != CD_CLOAKFIGHTER)
updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->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, it's sprite is
not displayed. However the engine trail is still visible!
*/
if ((theEnemy->flags & FL_CANCLOAK) && ((rand() % 500) == 0))
{
if (theEnemy->flags & FL_ISCLOAKED)
theEnemy->flags -= FL_ISCLOAKED;
else
theEnemy->flags += FL_ISCLOAKED;
playSound(SFX_CLOAK);
}
// ------------ Barriers ------------------
if (theEnemy->classDef == CD_BARRIER)
{
theEnemy->dx = -10 + (sin(barrierLoop + theEnemy->speed) * 60);
theEnemy->dy = 20 + (cos(barrierLoop + theEnemy->speed) * 40);
}
// ----------------------------------------
// ------------ Mobile Shields ------------
if (theEnemy->classDef == CD_MOBILESHIELD)
{
Math::limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield);
}
// ----------------------------------------
Math::limitChar(&--theEnemy->reload[0], 0, 999);
Math::limitChar(&--theEnemy->reload[1], 0, 999);
if ((!(theEnemy->flags & FL_DISABLED)) && (!(theEnemy->flags & FL_NOFIRE)))
{
if ((theEnemy->target->shield > 0))
canFire = traceTarget(theEnemy);
if (((theEnemy->thinktime % 2) == 0) && (theEnemy->flags & FL_FRIEND))
canFire = traceView(theEnemy);
}
else
{
canFire = 0;
}
if ((canFire == 1) && (dev.fireAliens))
{
if ((theEnemy->reload[0] == 0) && ((rand() % 1000 < theEnemy->chance[0]) || (theEnemy->flags & FL_CONTINUOUS_FIRE)))
{
fireBullet(theEnemy, 0);
}
if ((theEnemy->reload[1] == 0) && ((rand() % 1000 < theEnemy->chance[1]) || (theEnemy->flags & FL_CONTINUOUS_FIRE)))
{
if ((theEnemy->weaponType[1] != W_ENERGYRAY) && (theEnemy->weaponType[1] != W_LASER))
{
if (theEnemy->weaponType[1] == W_CHARGER)
theEnemy->ammo[1] = 50 + rand() % 150;
fireBullet(theEnemy, 1);
}
else if (theEnemy->weaponType[1] == W_LASER)
{
theEnemy->flags += FL_FIRELASER;
}
else if ((theEnemy->weaponType[1] == W_ENERGYRAY) && (theEnemy->ammo[0] == 250))
{
theEnemy->flags += FL_FIRERAY;
playSound(SFX_ENERGYRAY);
}
}
}
// --------------- Ray specific stuff ------------------
if (theEnemy->flags & FL_FIRERAY)
{
fireRay(theEnemy);
}
else
{
Math::limitChar(&++theEnemy->ammo[0], 0, 250);
}
// -------------------------------------------------------
// --------------- Laser specific stuff ------------------
if (theEnemy->flags & FL_FIRELASER)
{
fireBullet(theEnemy, 1);
if ((rand() % 25) == 0)
theEnemy->flags -= FL_FIRELASER;
}
// -------------------------------------------------------
// ---------------- Mine specific stuff ------------------
if (theEnemy->flags & FL_DROPMINES)
if ((rand() % 150) == 0)
addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, 600 + rand() % 2400);
// Kline drops mines a lot more often
if ((theEnemy->flags & FL_DROPMINES) && (theEnemy == &enemy[WC_KLINE]))
if ((rand() % 10) == 0)
addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, 600 + rand() % 2400);
// -------------------------------------------------------
shapeToUse = theEnemy->imageIndex[theEnemy->face];
if (theEnemy->hit)
shapeToUse += SHIP_HIT_INDEX;
Math::limitChar(&--theEnemy->hit, 0, 100);
if ((theEnemy->x + theEnemy->image[0]->w > 0) && (theEnemy->x < 800) && (theEnemy->y + theEnemy->image[0]->h > 0) && (theEnemy->y < 600))
{
if ((!(theEnemy->flags & FL_DISABLED)) && (theEnemy->classDef != CD_ASTEROID) && (theEnemy->classDef != CD_ASTEROID2))
addEngine(theEnemy);
if ((!(theEnemy->flags & FL_ISCLOAKED)) || (theEnemy->hit > 0))
graphics.blit(graphics.shipShape[shapeToUse], (int)theEnemy->x, (int)theEnemy->y);
if (theEnemy->flags & FL_DISABLED)
{
if ((rand() % 10) == 0)
addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_ELECTRICAL);
}
}
if ((currentGame.area == 24) && (theEnemy->x < -300))
theEnemy->active = 0;
}
else
{
theEnemy->shield--;
if ((theEnemy->x > 0) && (theEnemy->x < 800) && (theEnemy->y > 0) && (theEnemy->y < 600))
{
graphics.blit(theEnemy->image[theEnemy->face], (int)theEnemy->x, (int)theEnemy->y);
addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_BIG_EXPLOSION);
}
if (theEnemy->shield < theEnemy->deathCounter)
{
theEnemy->active = 0;
if ((theEnemy->classDef == CD_BOSS) || (theEnemy->owner == &enemy[WC_BOSS]) || (theEnemy->flags & FL_FRIEND) || (theEnemy->classDef == CD_ASTEROID) || (theEnemy->classDef == CD_KLINE))
addDebris((int)theEnemy->x, (int)theEnemy->y, theEnemy->maxShield);
if (theEnemy->classDef == CD_ASTEROID)
{
int i = 1 + (rand() % 3);
for (int j = 0 ; j < i ; j++)
addSmallAsteroid(theEnemy);
}
}
}
// Adjust the movement even whilst exploding
if ((dev.moveAliens) && (!(theEnemy->flags & FL_NOMOVE)) && (!(theEnemy->flags & FL_DISABLED)))
{
moveAndSeparate(theEnemy);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -