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

📄 p_pspr.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
//============================================================================void A_CHolyAttack2(mobj_t *actor){	int j;	int i;	mobj_t *mo;	mobj_t *tail, *next;	for(j = 0; j < 4; j++)	{		mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_HOLY_FX);		if(!mo)		{			continue;		}		switch(j)		{ // float bob index			case 0:				mo->special2 = P_Random()&7; // upper-left				break;			case 1:				mo->special2 = 32+(P_Random()&7); // upper-right				break;			case 2:				mo->special2 = (32+(P_Random()&7))<<16; // lower-left				break;			case 3:				mo->special2 = ((32+(P_Random()&7))<<16)+32+(P_Random()&7);				break;		}		mo->z = actor->z;		mo->angle = actor->angle+(ANGLE_45+ANGLE_45/2)-ANGLE_45*j;		P_ThrustMobj(mo, mo->angle, mo->info->speed);		mo->target = actor->target;		mo->args[0] = 10; // initial turn value		mo->args[1] = 0; // initial look angle		if(deathmatch)		{ // Ghosts last slightly less longer in DeathMatch			mo->health = 85;		}		if(linetarget)		{			mo->special1 = (int)linetarget;			mo->flags |= MF_NOCLIP|MF_SKULLFLY;			mo->flags &= ~MF_MISSILE;		}		tail = P_SpawnMobj(mo->x, mo->y, mo->z, MT_HOLY_TAIL);		tail->special2 = (int)mo; // parent		for(i = 1; i < 3; i++)		{			next = P_SpawnMobj(mo->x, mo->y, mo->z, MT_HOLY_TAIL);			P_SetMobjState(next, next->info->spawnstate+1);			tail->special1 = (int)next;			tail = next;		}		tail->special1 = 0; // last tail bit	}}//============================================================================//// A_CHolyAttack////============================================================================void A_CHolyAttack(player_t *player, pspdef_t *psp){	mobj_t *mo;	player->mana[MANA_1] -= WeaponManaUse[player->class][player->readyweapon];	player->mana[MANA_2] -= WeaponManaUse[player->class][player->readyweapon];	mo = P_SpawnPlayerMissile(player->mo, MT_HOLY_MISSILE);	if(player == &players[consoleplayer])	{		player->damagecount = 0;		player->bonuscount = 0;		I_SetPalette((byte *)W_CacheLumpNum(W_GetNumForName("playpal"),			PU_CACHE)+STARTHOLYPAL*768);	}	S_StartSound(player->mo, SFX_CHOLY_FIRE);}//============================================================================//// A_CHolyPalette////============================================================================void A_CHolyPalette(player_t *player, pspdef_t *psp){	int pal;	if(player == &players[consoleplayer])	{		pal = STARTHOLYPAL+psp->state-(&states[S_CHOLYATK_6]);		if(pal == STARTHOLYPAL+3)		{ // reset back to original playpal			pal = 0;		}		I_SetPalette((byte *)W_CacheLumpNum(W_GetNumForName("playpal"),			PU_CACHE)+pal*768);	}}//============================================================================//// CHolyFindTarget////============================================================================static void CHolyFindTarget(mobj_t *actor){	mobj_t *target;	if(target = P_RoughMonsterSearch(actor, 6))	{		actor->special1 = (int)target;		actor->flags |= MF_NOCLIP|MF_SKULLFLY;		actor->flags &= ~MF_MISSILE;	}}//============================================================================//// CHolySeekerMissile//// 	 Similar to P_SeekerMissile, but seeks to a random Z on the target//============================================================================static void CHolySeekerMissile(mobj_t *actor, angle_t thresh, angle_t turnMax){	int dir;	int dist;	angle_t delta;	angle_t angle;	mobj_t *target;	fixed_t newZ;	fixed_t deltaZ;	target = (mobj_t *)actor->special1;	if(target == NULL)	{		return;	}	if(!(target->flags&MF_SHOOTABLE) 	|| (!(target->flags&MF_COUNTKILL) && !target->player))	{ // Target died/target isn't a player or creature		actor->special1 = 0;		actor->flags &= ~(MF_NOCLIP|MF_SKULLFLY);		actor->flags |= MF_MISSILE;		CHolyFindTarget(actor);		return;	}	dir = P_FaceMobj(actor, target, &delta);	if(delta > thresh)	{		delta >>= 1;		if(delta > turnMax)		{			delta = turnMax;		}	}	if(dir)	{ // Turn clockwise		actor->angle += delta;	}	else	{ // Turn counter clockwise		actor->angle -= delta;	}	angle = actor->angle>>ANGLETOFINESHIFT;	actor->momx = FixedMul(actor->info->speed, finecosine[angle]);	actor->momy = FixedMul(actor->info->speed, finesine[angle]);	if(!(leveltime&15) 		|| actor->z > target->z+(target->height)		|| actor->z+actor->height < target->z)	{		newZ = target->z+((P_Random()*target->height)>>8);		deltaZ = newZ-actor->z;		if(abs(deltaZ) > 15*FRACUNIT)		{			if(deltaZ > 0)			{				deltaZ = 15*FRACUNIT;			}			else			{				deltaZ = -15*FRACUNIT;			}		}		dist = P_AproxDistance(target->x-actor->x, target->y-actor->y);		dist = dist/actor->info->speed;		if(dist < 1)		{			dist = 1;		}		actor->momz = deltaZ/dist;	}	return;}//============================================================================//// A_CHolyWeave////============================================================================static void CHolyWeave(mobj_t *actor){	fixed_t newX, newY;	int weaveXY, weaveZ;	int angle;	weaveXY = actor->special2>>16;	weaveZ = actor->special2&0xFFFF;	angle = (actor->angle+ANG90)>>ANGLETOFINESHIFT;	newX = actor->x-FixedMul(finecosine[angle], 		FloatBobOffsets[weaveXY]<<2);	newY = actor->y-FixedMul(finesine[angle],		FloatBobOffsets[weaveXY]<<2);	weaveXY = (weaveXY+(P_Random()%5))&63;	newX += FixedMul(finecosine[angle], 		FloatBobOffsets[weaveXY]<<2);	newY += FixedMul(finesine[angle], 		FloatBobOffsets[weaveXY]<<2);	P_TryMove(actor, newX, newY);	actor->z -= FloatBobOffsets[weaveZ]<<1;	weaveZ = (weaveZ+(P_Random()%5))&63;	actor->z += FloatBobOffsets[weaveZ]<<1;		actor->special2 = weaveZ+(weaveXY<<16);}//============================================================================//// A_CHolySeek////============================================================================void A_CHolySeek(mobj_t *actor){	actor->health--;	if(actor->health <= 0)	{		actor->momx >>= 2;		actor->momy >>= 2;		actor->momz = 0;		P_SetMobjState(actor, actor->info->deathstate);		actor->tics -= P_Random()&3;		return;	}	if(actor->special1)	{		CHolySeekerMissile(actor, actor->args[0]*ANGLE_1,			actor->args[0]*ANGLE_1*2);		if(!((leveltime+7)&15))		{			actor->args[0] = 5+(P_Random()/20);		}	}	CHolyWeave(actor);}//============================================================================//// CHolyTailFollow////============================================================================static void CHolyTailFollow(mobj_t *actor, fixed_t dist){	mobj_t *child;	int an;	fixed_t oldDistance, newDistance;	child = (mobj_t *)actor->special1;	if(child)	{		an = R_PointToAngle2(actor->x, actor->y, child->x, 			child->y)>>ANGLETOFINESHIFT;		oldDistance = P_AproxDistance(child->x-actor->x, child->y-actor->y);		if(P_TryMove(child, actor->x+FixedMul(dist, finecosine[an]), 			actor->y+FixedMul(dist, finesine[an])))		{			newDistance = P_AproxDistance(child->x-actor->x, 				child->y-actor->y)-FRACUNIT;			if(oldDistance < FRACUNIT)			{				if(child->z < actor->z)				{					child->z = actor->z-dist;				}				else				{					child->z = actor->z+dist;				}			}			else			{				child->z = actor->z+FixedMul(FixedDiv(newDistance, 					oldDistance), child->z-actor->z);			}		}		CHolyTailFollow(child, dist-FRACUNIT);	}}//============================================================================//// CHolyTailRemove////============================================================================static void CHolyTailRemove(mobj_t *actor){	mobj_t *child;	child = (mobj_t *)actor->special1;	if(child)	{		CHolyTailRemove(child);	}	P_RemoveMobj(actor);}//============================================================================//// A_CHolyTail////============================================================================void A_CHolyTail(mobj_t *actor){	mobj_t *parent;	parent = (mobj_t *)actor->special2;	if(parent)	{		if(parent->state >= &states[parent->info->deathstate])		{ // Ghost removed, so remove all tail parts			CHolyTailRemove(actor);			return;		}		else if(P_TryMove(actor, parent->x-FixedMul(14*FRACUNIT,			finecosine[parent->angle>>ANGLETOFINESHIFT]),			parent->y-FixedMul(14*FRACUNIT, 			finesine[parent->angle>>ANGLETOFINESHIFT])))		{			actor->z = parent->z-5*FRACUNIT;		}		CHolyTailFollow(actor, 10*FRACUNIT);	}}//============================================================================//// A_CHolyCheckScream////============================================================================void A_CHolyCheckScream(mobj_t *actor){	A_CHolySeek(actor);	if(P_Random() < 20)	{		S_StartSound(actor, SFX_SPIRIT_ACTIVE);	}	if(!actor->special1)	{		CHolyFindTarget(actor);	}}//============================================================================//// A_CHolySpawnPuff////============================================================================void A_CHolySpawnPuff(mobj_t *actor){	P_SpawnMobj(actor->x, actor->y, actor->z, MT_HOLY_MISSILE_PUFF);}//----------------------------------------------------------------------------//// PROC A_FireConePL1////----------------------------------------------------------------------------#define SHARDSPAWN_LEFT		1#define SHARDSPAWN_RIGHT	2#define SHARDSPAWN_UP		4#define SHARDSPAWN_DOWN		8void A_FireConePL1(player_t *player, pspdef_t *psp){	angle_t angle;	int damage;	int slope;	int i;	mobj_t *pmo,*mo;	int conedone=false;	pmo = player->mo;	player->mana[MANA_1] -= WeaponManaUse[player->class][player->readyweapon];	S_StartSound(pmo, SFX_MAGE_SHARDS_FIRE);	damage = 90+(P_Random()&15);	for(i = 0; i < 16; i++)	{		angle = pmo->angle+i*(ANG45/16);		slope = P_AimLineAttack(pmo, angle, MELEERANGE);		if(linetarget)		{			pmo->flags2 |= MF2_ICEDAMAGE;			P_DamageMobj(linetarget, pmo, pmo, damage);			pmo->flags2 &= ~MF2_ICEDAMAGE;			conedone = true;			break;		}	}	// didn't find any creatures, so fire projectiles	if (!conedone)	{		mo = P_SpawnPlayerMissile(pmo, MT_SHARDFX1);		if (mo)		{			mo->special1 = SHARDSPAWN_LEFT|SHARDSPAWN_DOWN|SHARDSPAWN_UP				|SHARDSPAWN_RIGHT;			mo->special2 = 3; // Set sperm count (levels of reproductivity)			mo->target = pmo;			mo->args[0] = 3;		// Mark Initial shard as super damage		}	}}void A_ShedShard(mobj_t *actor){	mobj_t *mo;	int spawndir = actor->special1;	int spermcount = actor->special2;	if (spermcount <= 0) return;				// No sperm left	actor->special2 = 0;	spermcount--;	// every so many calls, spawn a new missile in it's set directions	if (spawndir & SHARDSPAWN_LEFT)	{		mo=P_SpawnMissileAngleSpeed(actor, MT_SHARDFX1, actor->angle+(ANG45/9),											 0, (20+2*spermcount)<<FRACBITS);		if (mo)		{			mo->special1 = SHARDSPAWN_LEFT;			mo->special2 = spermcount;			mo->momz = actor->momz;			mo->target = actor->target;			mo->args[0] = (spermcount==3)?2:0;		}	}	if (spawndir & SHARDSPAWN_RIGHT)	{		mo=P_SpawnMissileAngleSpeed(actor, MT_SHARDFX1, actor->angle-(ANG45/9),											 0, (20+2*spermcount)<<FRACBITS);		if (mo)		{			mo->special1 = SHARDSPAWN_RIGHT;			mo->special2 = spermcount;			mo->momz = actor->momz;			mo->target = actor->target;			mo->args[0] = (spermcount==3)?2:0;		}	}	if (spawndir & SHARDSPAWN_UP)	{		mo=P_SpawnMissileAngleSpeed(actor, MT_SHARDFX1, actor->angle, 											 0, (15+2*spermcount)<<FRACBITS);		if (mo)		{			mo->momz = actor->momz;			mo->z += 8*FRACUNIT;			if (spermcount & 1)			// Every other reproduction				mo->special1 = SHARDSPAWN_UP | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;			else				mo->special1 = SHARDSPAWN_UP;			mo->special2 = spermcount;			mo->target = actor->target;			mo->args[0] = (spermcount==3)?2:0;		}	}	if (spawndir & SHARDSPAWN_DOWN)	{		mo=P_SpawnMissileAngleSpeed(actor, MT_SHARDFX1, actor->angle, 											 0, (15+2*spermcount)<<FRACBITS);		if (mo)		{			mo->momz = actor->momz;			mo->z -= 4*FRACUNIT;			if (spermcount & 1)			// Every other reproduction				mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;			else				mo->special1 = SHARDSPAWN_DOWN;			mo->special2 = spermcount;			mo->target = actor->target;			mo->args[0] = (spermcount==3)?2:0;		}	}}//----------------------------------------------------------------------------//// PROC A_HideInCeiling////----------------------------------------------------------------------------/*void A_HideInCeiling(mobj_t *actor){	actor->z = actor->ceilingz+4*FRACUNIT;}*///----------------------------------------------------------------------------//// PROC A_FloatPuff////----------------------------------------------------------------------------/*void A_FloatPuff(mobj_t *puff){	puff->momz += 1.8*FRACUNIT;}*/void A_Light0(player_t *player, pspdef_t *psp){	player->extralight = 0;}/*void A_Light1(player_t *player, pspdef_t *psp){	player->extralight = 1;}*//*void A_Light2(player_t *player, pspdef_t *psp){	player->extralight = 2;}*///------------------------------------------------------------------------//// PROC P_SetupPsprites//// Called at start of level for each player////------------------------------------------------------------------------void P_SetupPsprites(player_t *player){	int i;	// Remove all psprites	for(i = 0; i < NUMPSPRITES; i++)	{		player->psprites[i].state = NULL;	}	// Spawn the ready weapon	player->pendingweapon = player->readyweapon;	P_BringUpWeapon(player);}//------------------------------------------------------------------------//// PROC P_MovePsprites//// Called every tic by player thinking routine////------------------------------------------------------------------------void P_MovePsprites(player_t *player){	int i;	pspdef_t *psp;	state_t *state;	psp = &player->psprites[0];	for(i = 0; i < NUMPSPRITES; i++, psp++)	{		if((state = psp->state) != 0) // a null state means not active		{			// drop tic count and possibly change state			if(psp->tics != -1)	// a -1 tic count never changes			{				psp->tics--;				if(!psp->tics)				{					P_SetPsprite(player, i, psp->state->nextstate);				}			}		}	}	player->psprites[ps_flash].sx = player->psprites[ps_weapon].sx;	player->psprites[ps_flash].sy = player->psprites[ps_weapon].sy;}

⌨️ 快捷键说明

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