📄 aliens.cpp
字号:
enemy[11].owner = &enemy[13];
enemy[11].target = &player;
enemy[11].dx = -35;
enemy[11].dy = -12;
enemy[10].owner = &enemy[12];
enemy[10].target = &player;
enemy[10].dx = -35;
enemy[10].dy = 20;
if (currentGame.area == 14)
{
enemy[WC_BOSS].AIType = AI_EVASIVE;
for (int i = 10 ; i < 15 ; i++)
{
enemy[i].imageIndex[0] += 15;
enemy[i].imageIndex[1] += 15;
enemy[i].image[0] = graphics.shipShape[enemy[i].imageIndex[0]];
enemy[i].image[1] = graphics.shipShape[enemy[i].imageIndex[1]];
}
}
}
else if (currentGame.area == 21)
{
enemy[WC_BOSS].target = &player;
enemy[WC_BOSS].x = 400;
enemy[WC_BOSS].y = 300;
enemy[13].owner = &enemy[WC_BOSS];
enemy[13].dy = 20;
enemy[12].owner = &enemy[WC_BOSS];
enemy[12].dy = -16;
}
}
void addFriendly(int type)
{
if (type != FR_SID)
enemy[type] = defEnemy[CD_FRIEND];
else
enemy[type] = defEnemy[CD_SID];
enemy[type].owner = &enemy[type];
enemy[type].target = &enemy[type];
enemy[type].active = 1;
if (rand() % 2 == 0)
enemy[type].x = Math::rrand(400, 550);
else
enemy[type].x = Math::rrand(250, 400);
if (rand() % 2 == 0)
enemy[type].y = Math::rrand(300, 450);
else
enemy[type].y = Math::rrand(150, 300);
if (type == FR_PHOEBE)
enemy[type].classDef = CD_PHOEBE;
if (type == FR_URSULA)
enemy[type].classDef = CD_URSULA;
// For the sake of it being the final battle :)
if (currentGame.area == 25)
enemy[type].flags += FL_IMMORTAL;
}
void setTarget(int index)
{
engine.targetIndex = index;
engine.targetShield = 85;
engine.targetShield /= enemy[index].shield;
engine.targetArrowTimer = -1;
if (currentGame.area == 10)
engine.targetArrowTimer = 0;
}
void initAliens()
{
for (int i = 0 ; i < MAX_ALIENS ; i++)
{
enemy[i].active = 0;
enemy[i].shield = -1;
enemy[i].flags = 0;
}
engine.targetIndex = -1;
getPreDefinedAliens();
// specific for Phoebe being captured!
if (currentGame.area == 7)
currentGame.hasWingMate1 = 1;
if (currentGame.area == 11)
enemy[WC_KLINE].active = 0;
for (int i = 0 ; i < engine.maxAliens ; i++)
addAlien();
if (currentGame.hasWingMate1)
addFriendly(FR_PHOEBE);
if (currentGame.hasWingMate2)
addFriendly(FR_URSULA);
if ((currentGame.area == 9) || (currentGame.area == 17) || (currentGame.area == 25))
addFriendly(FR_SID);
// Disable Wingmates for certain missions
switch (currentGame.area)
{
case 7:
case 9:
case 10:
case 15:
case 16:
case 18:
case 24:
case 26:
enemy[FR_PHOEBE].active = 0;
enemy[FR_URSULA].active = 0;
break;
}
if (currentGame.area == 10)
{
enemy[0].collectChance = 100;
enemy[0].collectType = P_ESCAPEPOD;
}
// Some specifics for interception missions
if (currentGame.area == MAX_MISSIONS - 1)
{
if ((currentGame.system > 1) && ((rand() % 5) == 0))
{
enemy[WC_KLINE] = defEnemy[CD_KLINE];
enemy[WC_KLINE].owner = &enemy[WC_KLINE];
enemy[WC_KLINE].target = &player;
enemy[WC_KLINE].shield = 100;
enemy[WC_KLINE].active = 1;
enemy[WC_KLINE].x = player.x + 1000;
enemy[WC_KLINE].y = player.y;
setTarget(WC_KLINE);
}
if ((currentGame.system == 2) && (currentGame.experimentalShield > 0))
{
if ((rand() % 2) == 0)
{
enemy[10] = defEnemy[CD_CLOAKFIGHTER];
enemy[10].owner = &enemy[10];
enemy[10].target = &enemy[10];
enemy[10].shield = 1000;
enemy[10].active = 1;
enemy[10].x = player.x - 1000;
enemy[10].y = player.y;
setTarget(10);
enemy[10].shield = currentGame.experimentalShield;
}
}
}
if (currentGame.area == 26)
{
enemy[WC_KLINE].flags += FL_IMMORTAL;
enemy[WC_KLINE].flags += FL_NOFIRE;
enemy[WC_KLINE].flags += FL_NOMOVE;
enemy[WC_KLINE].x = 600;
enemy[WC_KLINE].y = 300;
enemy[WC_KLINE].deathCounter = -250;
enemy[WC_KLINE].maxShield = 1500;
enemy[WC_KLINE].shield = 500;
}
for (int i = 0 ; i < MAX_ALIENS ; i++)
{
enemy[i].systemPower = enemy[i].maxShield;
enemy[i].deathCounter = 0 - (enemy[i].maxShield * 3);
Math::limitInt(&enemy[i].deathCounter, -350, 0);
}
// Set target energy meter
switch (currentGame.area)
{
case 5:
case 11:
case 13:
case 17:
case 18:
case 19:
case 20:
case 21:
case 23:
setTarget(WC_BOSS);
break;
case 7:
setTarget(FR_PHOEBE);
break;
case 8:
setTarget(19);
break;
case 9:
setTarget(FR_SID);
break;
case 10:
setTarget(0);
break;
case 25:
case 26:
setTarget(WC_KLINE);
break;
default:
break;
}
}
/*
"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.
*/
void searchForTarget(object *theEnemy)
{
int i;
if (theEnemy->flags & FL_WEAPCO)
{
i = (rand() % 10);
if (i == 0)
{
theEnemy->target = &player;
return;
}
}
i = rand() % MAX_ALIENS;
object *targetEnemy = &enemy[i];
// 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)
if ((theEnemy->classDef == CD_SID) && (currentGame.area != 25))
{
if ((targetEnemy->flags & FL_DISABLED) || (!(targetEnemy->flags & FL_NOFIRE)))
return;
}
// 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 ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA))
{
// Don't attack the boss or we could be here all day(!)
if (targetEnemy->classDef == CD_BOSS)
return;
if ((targetEnemy->flags & FL_DISABLED) || (targetEnemy->flags & FL_NOFIRE))
return;
}
}
if ((targetEnemy->shield < 1) || (!targetEnemy->active))
return;
if ((targetEnemy->flags & FL_WEAPCO) && (theEnemy->flags & FL_WEAPCO))
return;
if ((targetEnemy->flags & FL_FRIEND) && (theEnemy->flags & FL_FRIEND))
return;
if (abs((int)theEnemy->x - (int)theEnemy->target->x) > 550)
return;
if (abs((int)theEnemy->y - (int)theEnemy->target->y) > 400)
return;
theEnemy->target = targetEnemy;
}
int traceTarget(object *theEnemy)
{
// Do various checks to see if the alien can fire at
// the target. Start with the most obvious checks.
// No target
if (theEnemy->target == theEnemy)
return 0;
// Whilst firing a Ray, no other weapons can be fired!
if (theEnemy->flags & FL_FIRERAY)
return 0;
// The target is on the same side as you!
if ((theEnemy->flags & FL_WEAPCO) && (theEnemy->target->flags & FL_WEAPCO))
return 0;
if ((theEnemy->flags & FL_FRIEND) && (theEnemy->target->flags & FL_FRIEND))
return 0;
// You're facing the wrong way
if ((theEnemy->face == 0) && (theEnemy->target->x < theEnemy->x))
return 0;
if ((theEnemy->face == 1) && (theEnemy->target->x > theEnemy->x))
return 0;
// Slightly more than half a screen away from you
if (abs((int)theEnemy->x - (int)theEnemy->target->x) > 550)
return 0;
if ((theEnemy->flags & FL_AIMS) || (theEnemy->flags & FL_CONTINUOUS_FIRE))
return 1;
// Not at the correct vertical height
if ((theEnemy->y < theEnemy->target->y - 15) || (theEnemy->y > theEnemy->target->y + theEnemy->target->image[0]->h + 15))
return 0;
return 1;
}
/*
Currently only used for the allies. Whilst flying around, the allies will fire on
any enemy craft that enter their line of sight.
*/
int traceView(object *theEnemy)
{
object *anEnemy = enemy;
for (int i = 0 ; i < MAX_ALIENS ; i++)
{
if ((theEnemy != anEnemy) && (anEnemy->flags & FL_WEAPCO) && (anEnemy->shield > 0))
{
if ((theEnemy->y > anEnemy->y - 15) && (theEnemy->y < anEnemy->y + anEnemy->image[0]->h + 15))
{
if ((theEnemy->face == 1) && (anEnemy->x < theEnemy->x))
return 1;
if ((theEnemy->face == 0) && (anEnemy->x > theEnemy->x))
return 1;
}
}
*anEnemy++;
}
return 0;
}
void moveAndSeparate(object *theEnemy)
{
signed char checkCollisions = 1;
signed char hasCollided = 0;
// don't worry about bumping into other craft
if ((theEnemy->flags & FL_LEAVESECTOR) || (theEnemy->classDef == CD_DRONE) || (currentGame.area == 18))
checkCollisions = 0;
if (theEnemy->shield < 1)
checkCollisions = 0;
if (theEnemy->owner == theEnemy)
{
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);
}
else
{
theEnemy->x -= theEnemy->dx;
theEnemy->y -= theEnemy->dy;
}
}
object *anEnemy = enemy;
if (checkCollisions)
{
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))
{
*anEnemy++;
continue;
}
if (Collision::collision(theEnemy, anEnemy))
{
if ((anEnemy->classDef == CD_BARRIER) && (anEnemy->owner != theEnemy))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -