aliens.cpp

来自「打飞机的过关游戏(linux)」· C++ 代码 · 共 2,019 行 · 第 1/5 页

CPP
2,019
字号
#include "aliens.h"

signed char placeAlien(object *theEnemy)
{
	if (rand() % 2 == 0)
		theEnemy->x = Math::rrand(800, 1600);
	else
		theEnemy->x = Math::rrand(-800, 0);

	if (rand() % 2 == 0)
		theEnemy->y = Math::rrand(600, 1200);
	else
		theEnemy->y = Math::rrand(-600, 0);

	if (currentGame.area == 24)
	{
		theEnemy->x = 800;
		theEnemy->y = Math::rrand(200, 400);
	}

	for (int i = 0 ; i < MAX_ALIENS ; i++)
	{
		if ((enemy[i].owner != theEnemy) && (enemy[i].shield > 0))
		{
			if (Collision::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))
				return 0;
		}
	}

	return 1;
}

/*
This simply pulls back an alien from the array that is
"dead" (no shield) and returns the index number so we can have
a new one.
*/
int getAlien()
{
	for (int i = 0 ; i < engine.maxAliens ; i++)
	{
		if (!enemy[i].active)
		{
			return i;
		}
	}

	return -1;
}

void addDrone(object *host)
{
	int index = getAlien();

	if (index == -1)
		return;

	enemy[index] = defEnemy[CD_DRONE];
	enemy[index].active = 1;
	enemy[index].face = rand() % 2;
	enemy[index].owner = &enemy[index]; // Most enemies will own themselves
	enemy[index].target = &enemy[index];
	enemy[index].thinktime = (50 + rand() % 50);
	enemy[index].systemPower = enemy[index].maxShield;
	enemy[index].deathCounter = 0 - (enemy[index].maxShield * 3);
	enemy[index].hit = 0;

	enemy[index].x = host->x + rand() % 50;
	enemy[index].y = host->y + rand() % 50;
}

void addSmallAsteroid(object *host)
{
	if (engine.missionCompleteTimer != 0)
		return;

	int index = -1;
	int debris = 1 + rand() % 10;

	for (int i = 0 ; i < debris ; i++)
		addBullet(&weapon[W_ROCKETS], host, 0, 0);

	for (int i = 10 ; i < 20 ; i++)
		if (enemy[i].active == 0)
			index = i;

	if (index == -1)
		return;

	if ((rand() % 10) > 3)
	{
		enemy[index] = defEnemy[CD_ASTEROID2];
		enemy[index].imageIndex[0] = enemy[index].imageIndex[1] = 39 + rand() % 2;
		enemy[index].image[0] = graphics.shipShape[enemy[index].imageIndex[0]];
		enemy[index].image[1] = graphics.shipShape[enemy[index].imageIndex[1]];
	}
	else
	{
		enemy[index] = defEnemy[CD_DRONE];
	}

	enemy[index].owner = &enemy[index]; // Most enemies will own themselves
	enemy[index].target = &enemy[index];
	enemy[index].thinktime = 1;
	enemy[index].systemPower = enemy[index].maxShield;
	enemy[index].deathCounter = 0 - (enemy[index].maxShield * 3);
	enemy[index].hit = 0;

	enemy[index].x = host->x;
	enemy[index].y = host->y;
	enemy[index].active = 1;
}

signed char addAlien()
{
	int index = getAlien();

	if ((index == -1) || (currentGame.area == 23) || (currentGame.area == 26))
		return 0;

	signed char *alienArray;
	signed char numberOfAliens = 1;

	alienArray = new signed char[5];

	switch(currentGame.area)
	{
		case 0:
		case 3:
		case 11:
			numberOfAliens = 1;
			alienArray[0] = CD_DUALFIGHTER;
			break;
		case 1:
		case 2:
		case 4:
		case 5:
			numberOfAliens = 2;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_PROTOFIGHTER;
			break;
		case 9:
		case 13:
		case 14:
		case 16:
			numberOfAliens = 4;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_PROTOFIGHTER;
			alienArray[2] = CD_MISSILEBOAT;
			alienArray[3] = CD_AIMFIGHTER;
			break;
		case 25:
			numberOfAliens = 6;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_PROTOFIGHTER;
			alienArray[2] = CD_MISSILEBOAT;
			alienArray[3] = CD_AIMFIGHTER;
			alienArray[4] = CD_ESCORT;
			alienArray[5] = CD_MOBILE_RAY;
			break;
		case 22:
			numberOfAliens = 2;
			alienArray[0] = CD_AIMFIGHTER;
			alienArray[1] = CD_DUALFIGHTER;
			break;
		case 7:
		case 8:
			numberOfAliens = 3;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_PROTOFIGHTER;
			alienArray[2] = CD_AIMFIGHTER;
			break;
		case 18:
			numberOfAliens = 2;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_MINER;
			break;
		case 10:
		case 15:
			numberOfAliens = 1;
			alienArray[0] = CD_ASTEROID;
			break;
		case 24:
			numberOfAliens = 2;
			alienArray[0] = CD_ASTEROID;
			alienArray[1] = CD_ASTEROID2;
			break;
		case MAX_MISSIONS - 1:
			numberOfAliens = 3;
			alienArray[0] = CD_DUALFIGHTER;
			alienArray[1] = CD_MISSILEBOAT;
			alienArray[2] = CD_AIMFIGHTER;
			if (currentGame.system == 2)
			{
				numberOfAliens = 4;
				alienArray[3] = CD_PROTOFIGHTER;
			}
			break;
		default:
			numberOfAliens = 1;
			alienArray[0] = CD_DUALFIGHTER;
			break;
	}

	signed char randEnemy = alienArray[rand() % numberOfAliens];

	if ((currentGame.area != 10) && (currentGame.area != 15) && (currentGame.area != 24))
	{
		if ((currentGame.system == 1) && (currentGame.area == MAX_MISSIONS - 1))
		{
			if ((rand() % 5) == 0)
				randEnemy = CD_SLAVETRANSPORT;
		}

		if ((rand() % 6) == 0)
			randEnemy = CD_TRANSPORTSHIP;
	}

	delete(alienArray);

	enemy[index] = defEnemy[randEnemy];
	enemy[index].active = 1;
	enemy[index].face = rand() % 2;
	enemy[index].owner = &enemy[index]; // Most enemies will own themselves
	enemy[index].target = &enemy[index];
	enemy[index].thinktime = (50 + rand() % 50);
	enemy[index].systemPower = enemy[index].maxShield;
	enemy[index].deathCounter = 0 - (enemy[index].maxShield * 3);
	enemy[index].hit = 0;

	Math::limitInt(&enemy[index].deathCounter, -250, 0);

	// Attempts to place an alien. If it fails, the alien is deactivated.
	for (int i = 0 ; i < 100 ; i++)
	{
		if (placeAlien(&enemy[index]))
			break;
		enemy[index].active = 0;

		return 0;
	}

	if (enemy[index].classDef == CD_CARGOSHIP)
		addCargo(&enemy[index], P_CARGO);

	if (enemy[index].classDef == CD_MOBILE_RAY)
		enemy[index].shield = 25;

	if (enemy[index].classDef == CD_ESCORT)
		enemy[index].shield = 50;

	enemy[index].dx = Math::rrand(-2, 2);
	enemy[index].dy = Math::rrand(-2, 2);

	enemy[index].ammo[0] = 0;

	if (currentGame.area == 18)
		enemy[index].flags += FL_HASMINIMUMSPEED;

	return 1;
}

void getPreDefinedAliens()
{
	FILE *fp;
	char string[255];
	strcpy(string, "");

	int index, alienType, placeAttempt;
	int barrierSpeed = 1;

	sprintf(string, "data/aliens%d.dat", currentGame.area);
	#if USEPACK
	int dataLocation = locateDataInPak(string, 0);
	if (dataLocation == -1)
		return;
	fp = fopen(PACKLOCATION, "rb");
	fseek(fp, dataLocation, SEEK_SET);
	#else
	fp = fopen(string, "rb");
	if (fp == NULL)
		return;
	#endif

	fscanf(fp, "%d ", &index);

	while (index != -1)
	{
		placeAttempt = 0;

		fscanf(fp, "%d ", &alienType);

		enemy[index] = defEnemy[alienType];
		enemy[index].owner = &enemy[index];
		enemy[index].target = &enemy[index];
		enemy[index].face = rand() % 2;
		enemy[index].active = 1;

		/*
		we make 1000 attempts to place this enemy since it is required. If after 1000 attempts
		we still have managed to place the alien, then it simple isn't going to happen and we
		will just exit the same. The chances of this happening are very very low!
		*/
		while (true)
		{
			placeAttempt++;

			if (placeAlien(&enemy[index]))
				break;

			if (placeAttempt > 1000)
				showErrorAndExit(2, "");
		}

		if (currentGame.area == 2)
			addCargo(&enemy[index], P_CARGO);
		else if (currentGame.area == 7)
			addCargo(&enemy[index], P_PHOEBE);

		if (index == WC_KLINE)
		{
			enemy[WC_KLINE].target = &player;
			if (currentGame.area == 25)
				enemy[WC_KLINE].shield = 500;
		}

		if (enemy[index].classDef == CD_CLOAKFIGHTER)
		{
			enemy[index].active = 0;
			enemy[index].maxShield = enemy[index].shield = 400;
			enemy[index].flags -= FL_RUNSAWAY;
			enemy[index].speed = 3;
		}

		if ((enemy[index].classDef == CD_MOBILE_RAY) && (index >= 11))
		{
			enemy[index].active = 0;
		}

		if (enemy[index].classDef == CD_FIREFLY)
		{
			enemy[index].active = 0;
		}

		if (enemy[index].classDef == CD_BARRIER)
		{
			enemy[index].owner = &enemy[WC_BOSS];
			enemy[index].speed = barrierSpeed;
			barrierSpeed++;
		}

		if ((currentGame.area == 17) && (enemy[index].classDef == CD_BOSS))
		{
			enemy[index].imageIndex[1] = 29;
			enemy[index].flags += FL_IMMORTAL;
		}

		if (currentGame.area == 18)
			enemy[index].flags += FL_HASMINIMUMSPEED;

		if (currentGame.area == 23)
		{
			enemy[index].flags = FL_WEAPCO;
			if (index == WC_BOSS)
				enemy[index].chance[1] = 5;
		}

		fscanf(fp, "%d ", &index);
	}

	fclose(fp);

	if (currentGame.area == 5)
	{
		enemy[WC_BOSS].target = &player;
		enemy[WC_BOSS].x = -400;
		enemy[WC_BOSS].y = 300;

		enemy[13].owner = &enemy[WC_BOSS];
		enemy[13].target = &player;
		enemy[13].dx = -25;
		enemy[13].dy = -21;

		enemy[12].owner = &enemy[WC_BOSS];
		enemy[12].target = &player;
		enemy[12].dx = -20;
		enemy[12].dy = 37;
	}
	else if ((currentGame.area == 11) || (currentGame.area == 14))
	{
		enemy[WC_BOSS].target = &player;
		enemy[WC_BOSS].x = -400;
		enemy[WC_BOSS].y = 300;

		enemy[13].owner = &enemy[WC_BOSS];
		enemy[13].target = &player;
		enemy[13].dx = 15;
		enemy[13].dy = -22;

		enemy[12].owner = &enemy[WC_BOSS];
		enemy[12].target = &player;
		enemy[12].dx = 15;
		enemy[12].dy = 22;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?