⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aliens.cpp

📁 打飞机的过关游戏(linux)
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -