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

📄 bullets.cpp

📁 After decades of war one company, who had gained powerful supplying both sides with weaponary, steps
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*Copyright (C) 2003 Parallel RealitiesThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*/#include "bullets.h"void addBullet(object *theWeapon, object *attacker, int y, int dy){	object *bullet;	signed char imageIndex;	int tempX, tempY, steps;	bullet = new object;	if (attacker == &player)		currentGame.shots++;	bullet->next = NULL;	bullet->active = 1;	bullet->x = attacker->x - ((attacker->image[0]->w / 2) * attacker->face);	bullet->y = attacker->y + y;	bullet->flags = theWeapon->flags;	bullet->shield = 300; // bullets live for (approximately) 5 seconds	// Timed explosions live between 1 and 3 seconds	if (bullet->flags & WF_TIMEDEXPLOSION)		bullet->shield = 60 + ((rand() % 3) * 60);	if (attacker->face == 0)	{		bullet->dx = theWeapon->speed;		if ((currentGame.area == 18) || (currentGame.area == 24))			bullet->dx += fabs(engine.ssx);	}	else	{		bullet->dx = (0 - theWeapon->speed);	}	if (bullet->flags & WF_VARIABLE_SPEED)	{		bullet->dx = Math::rrand(100, 200);		bullet->dx /= 10;		if (attacker->face == 1)			bullet->dx = 0 - bullet->dx;	}	bullet->dy = dy;	if (bullet->flags & WF_SCATTER)	{		bullet->dy = Math::rrand(-200, 200);		if (bullet->dy != 0)			bullet->dy /= 200;	}	if (attacker->flags & FL_WEAPCO)		bullet->flags += WF_WEAPCO;	else		bullet->flags += WF_FRIEND;	bullet->owner = attacker->owner;	bullet->id = theWeapon->id;	bullet->damage = theWeapon->damage;	if (bullet->id == WT_CHARGER)	{		bullet->damage = attacker->ammo[1];		if (bullet->damage < 50)		{			bullet->damage = 1;			bullet->id = WT_PLASMA;		}	}	bullet->target = NULL;	if (attacker->flags & FL_FRIEND)		imageIndex = 0;	else		imageIndex = 1;	// Use the enemy's images if applicable	if (bullet->id != WT_ROCKET)		bullet->image[0] = theWeapon->image[imageIndex];	else		bullet->image[0] = theWeapon->image[attacker->face];	if (bullet->flags & WF_AIMED)	{		tempX = (int)fabs(attacker->target->x - attacker->x);		tempY = (int)fabs(attacker->target->y - attacker->y);		steps = max(tempX, tempY);		if (steps == 0)			steps = 12;		if (!(bullet->flags & WF_TIMEDEXPLOSION))			steps /= 8;		else			steps /= 6 + (rand() % 6);		tempX = (int)(attacker->target->x - attacker->x);		tempY = (int)(attacker->target->y - attacker->y);		bullet->dx = tempX / steps;		bullet->dy = tempY / steps;	}	if (attacker->classDef == CD_ASTEROID)	{		bullet->dx = Math::rrand(-20, 20);		bullet->dy = Math::rrand(-20, 20);		bullet->image[0] = graphics.shape[4];	}	engine.bulletTail->next = bullet;	engine.bulletTail = bullet;}/*Fill in later...*/void fireBullet(object *attacker, int weaponType){	if (attacker->reload[weaponType] > 0)		return;	int y = (attacker->image[0]->h) / 5;	// Remove some ammo from the player	if ((attacker == &player) && (weaponType == 1) && (!engine.cheatAmmo))		player.ammo[1]--;	object *theWeapon = &weapon[attacker->weaponType[weaponType]];	switch(theWeapon->id)	{		case WT_PLASMA:		case WT_SPREAD:		case WT_DIRECTIONAL:			playSound(SFX_PLASMA);			break;		case WT_ROCKET:			playSound(SFX_MISSILE);			break;		case WT_LASER:			playSound(SFX_LASER);			break;		case WT_CHARGER:			playSound(SFX_PLASMA3);			break;	}	if (theWeapon->flags & WF_STRAIGHT)	{		switch (theWeapon->ammo[0])		{			case 1:				addBullet(theWeapon, attacker, y * 3, 0);				break;			case 2:				addBullet(theWeapon, attacker, y * 2, 0);				addBullet(theWeapon, attacker, y * 4, 0);				break;			case 3:				addBullet(theWeapon, attacker, y * 2, 0);				addBullet(theWeapon, attacker, y * 3, 0);				addBullet(theWeapon, attacker, y * 4, 0);				break;			case 4:				addBullet(theWeapon, attacker, y, 0);				addBullet(theWeapon, attacker, y * 2, 0);				addBullet(theWeapon, attacker, y * 4, 0);				addBullet(theWeapon, attacker, y * 5, 0);				break;			case 5:				for (int i = 1 ; i < 6; i++)					addBullet(theWeapon, attacker, y * i, 0);				break;		}	}	else if (theWeapon->flags & WF_THIN_SPREAD)	{		addBullet(theWeapon, attacker, y * 2, -1);		if (theWeapon->ammo[0] == 3)		{			addBullet(theWeapon, attacker, y * 3, 0);		}		else		{			addBullet(theWeapon, attacker, y * 2, 0);			addBullet(theWeapon, attacker, y * 4, 0);		}		addBullet(theWeapon, attacker, y * 4, 1);	}	else if (theWeapon->flags & WF_WIDE_SPREAD)	{		addBullet(theWeapon, attacker, y * 1, -2);		addBullet(theWeapon, attacker, y * 2, -1);		addBullet(theWeapon, attacker, y * 3, 0);		addBullet(theWeapon, attacker, y * 4, 1);		addBullet(theWeapon, attacker, y * 5, 2);	}	// Reset the weapon reload time. Double it if it is not friendly or a boss or Kline	attacker->reload[weaponType] = theWeapon->reload[0];	if ((attacker->flags & FL_WEAPCO) && (attacker != &enemy[WC_BOSS]) && (attacker != &enemy[WC_KLINE]) && (theWeapon->id != W_LASER))		attacker->reload[weaponType] *= 2;	if ((engine.cheatAmmo) || (theWeapon->id == WT_LASER))		return;	if ((attacker == &player) && (weaponType == 0))	{		if (player.ammo[0] > 0)		{			player.ammo[0]--;			if (player.ammo[0] == 0)			{				player.weaponType[0] = W_PLAYER_WEAPON;				weapon[W_PLAYER_WEAPON2] = weapon[W_PLAYER_WEAPON]; // reset to weapon 1 defaults			}		}	}}/*Used for homing missiles. When a missile is active and it is told to home inon an enemy, it will attempt to randomly grab one every frame if it does notalready have a target. If the target it is currently chasing is killed, it willbegin to look for a new one (done in doBullets()). The homing missile will makeone attempt per call (one call per frame) to find a suitable target. If the targetit picks is dead or outside the screen range, then it returns NULL. A suitabletarget will be returned as the object address.*/object *getRandomEnemy(object *bullet){	int i;	if (bullet->owner->flags & FL_WEAPCO)	{		i = (rand() % 10);		if (i < 1)			return &player;	}	i = rand() % MAX_ALIENS;	if ((enemy[i].shield < 1) || (!enemy[i].active))		return NULL;	if ((bullet->owner->flags & FL_WEAPCO) && (enemy[i].flags & FL_WEAPCO))		return NULL;	if ((bullet->owner->flags & FL_FRIEND) && (enemy[i].flags & FL_FRIEND))		return NULL;	if (abs((int)bullet->x - (int)enemy[i].target->x) > 800)		return NULL;	if (abs((int)bullet->y - (int)enemy[i].target->y) > 200)		return NULL;	return &enemy[i];}/*Fill in later...*/void destroyAlien(object *bullet, object *theEnemy){	playSound(SFX_EXPLOSION);	// Chain reaction destruction if needed	if (theEnemy->flags & FL_DAMAGEOWNER)	{		theEnemy->owner->shield -= theEnemy->maxShield;		if (theEnemy->owner->shield < 1)			destroyAlien(bullet, theEnemy->owner);	}	if (theEnemy->flags & FL_FRIEND)	{		if (theEnemy->classDef == CD_PHOEBE)			currentGame.wingMate1Ejects++;		else if (theEnemy->classDef == CD_URSULA)			currentGame.wingMate2Ejects++;		// Phoebe cannot eject on the rescue mission		if (currentGame.area != 7)		{			if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA))				setInfoLine(">> Ally has ejected! <<\n", FONT_RED);			else				setInfoLine(">> Friendly craft has been destroy!! <<\n", FONT_RED);		}	}	if (bullet->owner == &player)	{		// Once again, stop point leeching		if (currentGame.area != MAX_MISSIONS - 1)			currentGame.cash += theEnemy->score;		currentGame.cashEarned += theEnemy->score;		currentGame.totalKills++;	}	else if (bullet->owner->classDef == CD_PHOEBE)	{		currentGame.wingMate1Kills++;	}	else if (bullet->owner->classDef == CD_URSULA)	{		currentGame.wingMate2Kills++;	}	else	{		currentGame.totalOtherKills++;	}	if ((bullet->owner->classDef == CD_PHOEBE) || (bullet->owner->classDef == CD_URSULA))	{		if ((rand() % 8) == 0)		{			getKillMessage(bullet->owner);		}	}	updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->classDef, 1);	updateMissionRequirements(M_PROTECT_TARGET, theEnemy->classDef, 1);	if (rand() % 100 <= theEnemy->collectChance)	{		unsigned char value;		if ((rand() % 10) == 0)			theEnemy->collectValue *= 2;		while (theEnemy->collectValue > 0)		{			value = (10 + (rand() % theEnemy->collectValue));			if (value > theEnemy->collectValue)				value =theEnemy->collectValue;			addCollectable(theEnemy->x, theEnemy->y, theEnemy->collectType, value, 600);			theEnemy->collectValue -= value;		}	}	// Make it explode immediately	if (theEnemy->classDef == CD_ASTEROID)	{		theEnemy->shield = -999;		if ((currentGame.area == 10) && (theEnemy != &enemy[0]) && (currentMission.completed1[0] == 0) && (currentMission.targetValue1[1] == 1))			engine.targetArrowTimer = 120;	}	if ((theEnemy->classDef == CD_KRASS) && (bullet->owner == &player))		setRadioMessage(FACE_CHRIS, "My NAME is CHRIS!!!!!!!!", 1);	if (theEnemy->classDef == CD_KLINE)	{		setRadioMessage(FACE_KLINE, "It was an honor... to have fought you...", 1);		theEnemy->dx = theEnemy->dy = 0;		theEnemy->maxShield = 1500;		theEnemy->shield = -200;	}}char checkPlayerShockDamage(float x, float y, int radius){	// Don't let the player be hurt by an explosion after they have completed	// all the mission objectives. That would be *really* annoying!	if ((engine.cheatShield) || (engine.missionCompleteTimer != 0))		return 0;	float distX = fabs(x - player.x);	float distY = fabs(y - player.y);	if ((distX <= 50) && (distY <= 50))	{

⌨️ 快捷键说明

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