Ejemplo n.º 1
0
Archivo: NPC.c Proyecto: Geptun/japp
void NPC_SetAnim(gentity_t *ent, int setAnimParts, int anim, int setAnimFlags)
{	// FIXME : once torsoAnim and legsAnim are in the same structure for NCP and Players
	// rename PM_SETAnimFinal to PM_SetAnim and have both NCP and Players call PM_SetAnim
	G_SetAnim(ent, NULL, setAnimParts, anim, setAnimFlags, 0);
/*
	if(ent->client)
	{//Players, NPCs
		if (setAnimFlags&SETANIM_FLAG_OVERRIDE)
		{		
			if (setAnimParts & SETANIM_TORSO)
			{
				if( (setAnimFlags & SETANIM_FLAG_RESTART) || ent->client->ps.torsoAnim != anim )
				{
					PM_SetTorsoAnimTimer( ent, &ent->client->ps.torsoTimer, 0 );
				}
			}
			if (setAnimParts & SETANIM_LEGS)
			{
				if( (setAnimFlags & SETANIM_FLAG_RESTART) || ent->client->ps.legsAnim != anim )
				{
					PM_SetLegsAnimTimer( ent, &ent->client->ps.legsAnimTimer, 0 );
				}
			}
		}

		PM_SetAnimFinal(&ent->client->ps.torsoAnim,&ent->client->ps.legsAnim,setAnimParts,anim,setAnimFlags,
			&ent->client->ps.torsoAnimTimer,&ent->client->ps.legsAnimTimer,ent);
	}
	else
	{//bodies, etc.
		if (setAnimFlags&SETANIM_FLAG_OVERRIDE)
		{		
			if (setAnimParts & SETANIM_TORSO)
			{
				if( (setAnimFlags & SETANIM_FLAG_RESTART) || ent->s.torsoAnim != anim )
				{
					PM_SetTorsoAnimTimer( ent, &ent->s.torsoAnimTimer, 0 );
				}
			}
			if (setAnimParts & SETANIM_LEGS)
			{
				if( (setAnimFlags & SETANIM_FLAG_RESTART) || ent->s.legsAnim != anim )
				{
					PM_SetLegsAnimTimer( ent, &ent->s.legsAnimTimer, 0 );
				}
			}
		}

		PM_SetAnimFinal(&ent->s.torsoAnim,&ent->s.legsAnim,setAnimParts,anim,setAnimFlags,
			&ent->s.torsoAnimTimer,&ent->s.legsAnimTimer,ent);
	}
	*/
}
Ejemplo n.º 2
0
void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) 
{
	if( !other->client ) 
	{
		return;
	}

	if ( self->flags & FL_INACTIVE )
	{//set by target_deactivate
		return;
	}

#ifdef _PHASE1
	if (self->spawnflags & 32 && jkg_arearestrictions.integer)
	{
		return;	// eezstreet: Pande's orders
	}
#endif

	if( self->alliedTeam )
	{
		if ( other->client->sess.sessionTeam != self->alliedTeam )
		{
			return;
		}
	}

// moved to just above multi_trigger because up here it just checks if the trigger is not being touched
// we want it to check any conditions set on the trigger, if one of those isn't met, the trigger is considered to be "cleared"
//	if ( self->e_ThinkFunc == thinkF_trigger_cleared_fire )
//	{//We're waiting to fire our target2 first
//		self->nextthink = level.time + self->speed;
//		return;
//	}

	if ( self->spawnflags & 1 )
	{
		if ( other->s.eType == ET_NPC )
		{
			return;
		}
	}
	else
	{
		if ( self->spawnflags & 16 )
		{//NPCONLY
			if ( other->NPC == NULL )
			{
				return;
			}
		}

		if ( self->NPC_targetname && self->NPC_targetname[0] )
		{
			if ( other->script_targetname && other->script_targetname[0] )
			{
				if ( Q_stricmp( self->NPC_targetname, other->script_targetname ) != 0 )
				{//not the right guy to fire me off
					return;
				}
			}
			else
			{
				return;
			}
		}
	}

	if ( self->spawnflags & 2 )
	{//FACING
		vec3_t	forward;

		AngleVectors( other->client->ps.viewangles, forward, NULL, NULL );

		if ( DotProduct( self->movedir, forward ) < 0.5 )
		{//Not Within 45 degrees
			return;
		}
	}

	if ( self->spawnflags & 4 )
	{//USE_BUTTON
		if( !( other->client->pers.cmd.buttons & BUTTON_USE ) )
		{//not pressing use button
			return;
		}

		if ((other->client->ps.weaponTime > 0 && other->client->ps.torsoAnim != BOTH_BUTTON_HOLD && other->client->ps.torsoAnim != BOTH_CONSOLE1) || other->health < 1 ||
			(other->client->ps.pm_flags & PMF_FOLLOW) || other->client->sess.sessionTeam == TEAM_SPECTATOR ||
			other->client->ps.forceHandExtend != HANDEXTEND_NONE)
		{ //player has to be free of other things to use.
			return;
		}

		if (self->genericValue7)
		{ //we have to be holding the use key in this trigger for x milliseconds before firing
			if (!G_PointInBounds( other->client->ps.origin, self->r.absmin, self->r.absmax ))
			{
				return;
			}
			else if (other->client->isHacking != self->s.number && other->s.number < MAX_CLIENTS )
			{ //start the hack
				other->client->isHacking = self->s.number;
				VectorCopy(other->client->ps.viewangles, other->client->hackingAngles);
				other->client->ps.hackingTime = level.time + self->genericValue7;
				other->client->ps.hackingBaseTime = self->genericValue7;
				if (other->client->ps.hackingBaseTime > 60000)
				{ //don't allow a bit overflow
					other->client->ps.hackingTime = level.time + 60000;
					other->client->ps.hackingBaseTime = 60000;
				}
				return;
			}
			else if (other->client->ps.hackingTime < level.time)
			{ //finished with the hack, reset the hacking values and let it fall through
				other->client->isHacking = 0; //can't hack a client
				other->client->ps.hackingTime = 0;
			}
			else
			{ //hack in progress
				// UQ1: Added this code from below... It would never have gotten there before...
				if (other->client->ps.torsoAnim != BOTH_BUTTON_HOLD &&
					other->client->ps.torsoAnim != BOTH_CONSOLE1)
				{
					G_SetAnim( other, NULL, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
				}
				else
				{
					other->client->ps.torsoTimer = 500;
				}
				other->client->ps.weaponTime = other->client->ps.torsoTimer;
				// UQ1: End added...
				return;
			}
		}
	}

	if ( self->spawnflags & 8 )
	{//FIRE_BUTTON
		if( !( other->client->pers.cmd.buttons & BUTTON_ATTACK ) )
		{//not pressing fire button or altfire button
			return;
		}
	}

	if ( self->radius )
	{
		vec3_t	eyeSpot;

		//Only works if your head is in it, but we allow leaning out
		//NOTE: We don't use CalcEntitySpot SPOT_HEAD because we don't want this
		//to be reliant on the physical model the player uses.
		VectorCopy(other->client->ps.origin, eyeSpot);
		eyeSpot[2] += other->client->ps.viewheight;

		if ( G_PointInBounds( eyeSpot, self->r.absmin, self->r.absmax ) )
		{
			if( !( other->client->pers.cmd.buttons & BUTTON_ATTACK ) )
			{//not attacking, so hiding bonus
				/*
				//FIXME:  should really have sound events clear the hiddenDist
				other->client->hiddenDist = self->radius;
				//NOTE: movedir HAS to be normalized!
				if ( VectorLength( self->movedir ) )
				{//They can only be hidden from enemies looking in this direction
					VectorCopy( self->movedir, other->client->hiddenDir );
				}
				else
				{
					VectorClear( other->client->hiddenDir );
				}
				*/
				//Not using this, at least not yet.
			}
		}
	}

	if ( self->spawnflags & 4 )
	{//USE_BUTTON
		if (other->client->ps.torsoAnim != BOTH_BUTTON_HOLD &&
			other->client->ps.torsoAnim != BOTH_CONSOLE1)
		{
			G_SetAnim( other, NULL, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
		}
		else
		{
			other->client->ps.torsoTimer = 500;
		}
		other->client->ps.weaponTime = other->client->ps.torsoTimer;
	}
	
	if ( self->think == trigger_cleared_fire )
	{//We're waiting to fire our target2 first
		self->nextthink = level.time + self->speed;
		return;
	}

	multi_trigger( self, other );
}
Ejemplo n.º 3
0
void WP_GrenadeBlow(gentity_t*self)
{
	if(Q_stricmp(self->classname,"emp_grenade")==0
		||Q_stricmp(self->classname,"cryoban_grenade")==0
		||Q_stricmp(self->classname,"flash_grenade")==0)
	{
		vec3_t	dir={0,0,1};
		int entitys[1024];
		vec3_t mins,maxs,v;
		int num=0,i=0,dist=0,mpDamage=7;
		int e=0;
		gentity_t*ent;
		for ( i = 0 ; i < 3 ; i++ ) 
		{
			mins[i] = self->r.currentOrigin[i] - TD_SPLASH_RAD / 2;
			maxs[i] = self->r.currentOrigin[i] + TD_SPLASH_RAD / 2;
		}
		num = trap_EntitiesInBox(mins,maxs,entitys,MAX_GENTITIES);
		for ( i = 0 ; i < num ; i++ ) 
		{
			ent = &g_entities[entitys[ i ]];
			if (ent == self)
				continue;
			if (!ent->takedamage)
				continue;
			if(!ent->inuse || !ent->client)
				continue;

			// find the distance from the edge of the bounding box
			for ( e = 0 ; e < 3 ; e++ ) {
				if ( self->r.currentOrigin[e] < ent->r.absmin[e] ) {
					v[e] = ent->r.absmin[e] - self->r.currentOrigin[e];
				} else if ( self->r.currentOrigin[e] > ent->r.absmax[e] ) {
					v[e] = self->r.currentOrigin[e] - ent->r.absmax[e];
				} else {
					v[e] = 0;
				}
			}

			dist = VectorLength( v );
			if ( dist >= TD_SPLASH_RAD ) {
				continue;
			}

			if(Q_stricmp(self->classname,"cryoban_grenade") == 0)
				G_AddEvent(ent, EV_CRYOBAN, DirToByte(dir));

			if(Q_stricmp(self->classname,"emp_grenade")==0)
			{
				int shield = Q_irand(25,50);
				int ammo = Q_irand(15,30);
				G_DodgeDrain(ent, self, 15);//15 for nau
				ent->client->ps.saberAttackChainCount += mpDamage;
				if(ent->client->ps.stats[STAT_ARMOR]-shield >= 0)
					ent->client->ps.stats[STAT_ARMOR]-=shield;
				else
					ent->client->ps.stats[STAT_ARMOR]=0;

				if(ent->client->ps.ammo[weaponData[ent->client->ps.weapon].ammoIndex]-ammo >= 0)
					ent->client->ps.ammo[weaponData[ent->client->ps.weapon].ammoIndex]-=ammo;
				else
					ent->client->ps.ammo[weaponData[ent->client->ps.weapon].ammoIndex]=0;

				if(Q_stricmp(ent->classname,"item_seeker")==0||Q_stricmp(ent->classname,"item_sentry_gun")==0)
				{
					G_Damage( ent, ent, ent, NULL, NULL, 999, 0, MOD_UNKNOWN );
				}
				ent->client->ps.electrifyTime = level.time + Q_irand( 300, 800 );
			}
			else if(Q_stricmp(self->classname,"cryoban_grenade")==0)
			{
				ent->client->frozenTime = level.time+FROZEN_TIME;
				ent->client->ps.userInt3 |= (1 << FLAG_FROZEN);
				ent->client->ps.userInt1 |= LOCK_UP;
				ent->client->ps.userInt1 |= LOCK_DOWN;
				ent->client->ps.userInt1 |= LOCK_RIGHT;
				ent->client->ps.userInt1 |= LOCK_LEFT;
				ent->client->viewLockTime = level.time+FROZEN_TIME;
				ent->client->ps.legsTimer = ent->client->ps.torsoTimer=level.time+FROZEN_TIME;
				G_SetAnim(ent, NULL, SETANIM_BOTH, WeaponReadyAnim[ent->client->ps.weapon], SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD, 100);
			}
			else if(Q_stricmp(self->classname,"flash_grenade")==0)
				G_AddEvent( ent, EV_FLASHGRENADE, DirToByte( dir ) );
		}
		self->s.eType = ET_GENERAL;
		if(Q_stricmp(self->classname,"emp_grenade") == 0)
			G_AddEvent( self, EV_EMPGRENADE, DirToByte( dir ) );
		else if(Q_stricmp(self->classname,"cryoban_grenade") == 0)
			G_AddEvent( self, EV_CRYOBAN_EXPLODE, DirToByte( dir ) );
		self->freeAfterEvent = qtrue;
	}
	else if(Q_stricmp(self->classname,"smoke_grenade")==0)
	{
		vec3_t	dir={0,0,1};

			G_AddEvent( self, EV_SMOKEGRENADE, DirToByte( dir ) );
		self->freeAfterEvent = qtrue;
	}
	else
	{
		self->think = G_FreeEntity;
		self->nextthink = level.time;
	}
}
Ejemplo n.º 4
0
void JKG_GrappleUpdate( gentity_t *self )
{
	gentity_t *grappler = &g_entities[self->client->grappleIndex];

	if (!grappler->inuse || !grappler->client || grappler->client->grappleIndex != self->s.number ||
		!BG_InGrappleMove(grappler->client->ps.torsoAnim) || !BG_InGrappleMove(grappler->client->ps.legsAnim) ||
		!BG_InGrappleMove(self->client->ps.torsoAnim) || !BG_InGrappleMove(self->client->ps.legsAnim) ||
		!self->client->grappleState || !grappler->client->grappleState ||
		grappler->health < 1 || self->health < 1 ||
		!G_PrettyCloseIGuess(self->client->ps.origin[2], grappler->client->ps.origin[2], 4.0f))
	{
		self->client->grappleState = 0;
		if ((BG_InGrappleMove(self->client->ps.torsoAnim) && self->client->ps.torsoTimer > 100) ||
			(BG_InGrappleMove(self->client->ps.legsAnim) && self->client->ps.legsTimer > 100))
		{ //if they're pretty far from finishing the anim then shove them into another anim
			G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
			if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
			{ //providing the anim set succeeded..
				self->client->ps.weaponTime = self->client->ps.torsoTimer;
			}
		}
	}
	else
	{
		vec3_t grapAng;

		VectorSubtract(grappler->client->ps.origin, self->client->ps.origin, grapAng);

		if (VectorLength(grapAng) > 64.0f)
		{ //too far away, break it off
			if ((BG_InGrappleMove(self->client->ps.torsoAnim) && self->client->ps.torsoTimer > 100) ||
				(BG_InGrappleMove(self->client->ps.legsAnim) && self->client->ps.legsTimer > 100))
			{
				self->client->grappleState = 0;

				G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
				if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
				{ //providing the anim set succeeded..
					self->client->ps.weaponTime = self->client->ps.torsoTimer;
				}
			}
		}
		else
		{
			vectoangles(grapAng, grapAng);
			SetClientViewAngle(self, grapAng);

			if (self->client->grappleState >= 20)
			{ //grapplee
				//try to position myself at the correct distance from my grappler
				float idealDist;
				vec3_t gFwd, idealSpot;
				trace_t trace;

				if (grappler->client->ps.torsoAnim == BOTH_KYLE_PA_1)
				{ //grab punch
					idealDist = 46.0f;
				}
				else
				{ //knee-throw
					idealDist = 34.0f;
				}

				AngleVectors(grappler->client->ps.viewangles, gFwd, 0, 0);
				VectorMA(grappler->client->ps.origin, idealDist, gFwd, idealSpot);

				trap_Trace(&trace, self->client->ps.origin, self->r.mins, self->r.maxs, idealSpot, self->s.number, self->clipmask);
				if (!trace.startsolid && !trace.allsolid && trace.fraction == 1.0f)
				{ //go there
					G_SetOrigin(self, idealSpot);
					VectorCopy(idealSpot, self->client->ps.origin);
				}
			}
			else if (self->client->grappleState >= 1)
			{ //grappler
				if (grappler->client->ps.weapon == WP_SABER)
				{ //make sure their saber is shut off
					if (!grappler->client->ps.saberHolstered)
					{
						grappler->client->ps.saberHolstered = 2;
						if (grappler->client->saber[0].soundOff)
						{
							G_Sound(grappler, CHAN_AUTO, grappler->client->saber[0].soundOff);
						}
						if (grappler->client->saber[1].soundOff &&
							grappler->client->saber[1].model[0])
						{
							G_Sound(grappler, CHAN_AUTO, grappler->client->saber[1].soundOff);
						}
					}
				}

				//check for smashy events
				if (self->client->ps.torsoAnim == BOTH_KYLE_PA_1)
				{ //grab punch
                    if (self->client->grappleState == 1)
					{ //smack
						if (self->client->ps.torsoTimer < 3400)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else if (self->client->grappleState == 2)
					{ //smack!
						if (self->client->ps.torsoTimer < 2550)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else
					{ //SMACK!
						if (self->client->ps.torsoTimer < 1300)
						{
							vec3_t tossDir;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 30, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							self->client->grappleState = 0;

							VectorSubtract(grappler->client->ps.origin, self->client->ps.origin, tossDir);
							VectorNormalize(tossDir);
							VectorScale(tossDir, 500.0f, tossDir);
							tossDir[2] = 200.0f;

							VectorAdd(grappler->client->ps.velocity, tossDir, grappler->client->ps.velocity);

							if (grappler->health > 0)
							{ //if still alive knock them down
								grappler->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN;
								grappler->client->ps.forceHandExtendTime = level.time + 1300;
							}
						}
					}
				}
				else if (self->client->ps.torsoAnim == BOTH_KYLE_PA_2)
				{ //knee throw
                    if (self->client->grappleState == 1)
					{ //knee to the face
						if (self->client->ps.torsoTimer < 3200)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 20, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else if (self->client->grappleState == 2)
					{ //smashed on the ground
						if (self->client->ps.torsoTimer < 2000)
						{
							//G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//don't do damage on this one, it would look very freaky if they died
							G_EntitySound( grappler, CHAN_VOICE, G_SoundIndex("*pain100.wav") );
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );
							self->client->grappleState++;
						}
					}
					else
					{ //and another smash
						if (self->client->ps.torsoTimer < 1000)
						{
							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 30, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoTimer = 1000;
								//G_SetAnim(grappler, &grappler->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP3, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
								grappler->client->grappleState = 0;
							}
							else
							{ //override death anim
								grappler->client->ps.torsoAnim = BOTH_DEADFLOP1;
								grappler->client->ps.legsAnim = BOTH_DEADFLOP1;
							}

							self->client->grappleState = 0;
						}
					}
				}
				else
				{ //?
				}
			}
		}
	}
}
Ejemplo n.º 5
0
void G_GrabSomeMofos(gentity_t *self)
{
	renderInfo_t *ri = &self->client->renderInfo;
	mdxaBone_t boltMatrix;
	vec3_t flatAng;
	vec3_t pos;
	vec3_t grabMins, grabMaxs;
	trace_t trace;

	if (!self->ghoul2 || ri->handRBolt == -1)
	{ //no good
		return;
	}

    VectorSet(flatAng, 0.0f, self->client->ps.viewangles[1], 0.0f);
	trap_G2API_GetBoltMatrix(self->ghoul2, 0, ri->handRBolt, &boltMatrix, flatAng, self->client->ps.origin,
		level.time, NULL, self->modelScale);
	BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, pos);

	VectorSet(grabMins, -4.0f, -4.0f, -4.0f);
	VectorSet(grabMaxs, 4.0f, 4.0f, 4.0f);

	//trace from my origin to my hand, if we hit anyone then get 'em
	trap_G2Trace( &trace, self->client->ps.origin, grabMins, grabMaxs, pos, self->s.number, MASK_SHOT, G2TRFLAG_DOGHOULTRACE|G2TRFLAG_GETSURFINDEX|G2TRFLAG_THICK|G2TRFLAG_HITCORPSES, g_g2TraceLod.integer );
    
	if (trace.fraction != 1.0f &&
		trace.entityNum < ENTITYNUM_WORLD)
	{
		gentity_t *grabbed = &g_entities[trace.entityNum];

		if (grabbed->inuse && (grabbed->s.eType == ET_PLAYER || grabbed->s.eType == ET_NPC) &&
			grabbed->client && grabbed->health > 0 &&
			G_CanBeEnemy(self, grabbed) &&
			G_PrettyCloseIGuess(grabbed->client->ps.origin[2], self->client->ps.origin[2], 4.0f) &&
			(!BG_InGrappleMove(grabbed->client->ps.torsoAnim) || grabbed->client->ps.torsoAnim == BOTH_KYLE_GRAB) &&
			(!BG_InGrappleMove(grabbed->client->ps.legsAnim) || grabbed->client->ps.legsAnim == BOTH_KYLE_GRAB))
		{ //grabbed an active player/npc
			int tortureAnim = -1;
			int correspondingAnim = -1;

			if (self->client->pers.cmd.forwardmove > 0)
			{ //punch grab
				tortureAnim = BOTH_KYLE_PA_1;
				correspondingAnim = BOTH_PLAYER_PA_1;
			}
			else if (self->client->pers.cmd.forwardmove < 0)
			{ //knee-throw
				tortureAnim = BOTH_KYLE_PA_2;
				correspondingAnim = BOTH_PLAYER_PA_2;
			}

			if (tortureAnim == -1 || correspondingAnim == -1)
			{
				if (self->client->ps.torsoTimer < 300 && !self->client->grappleState)
				{ //you failed to grab anyone, play the "failed to grab" anim
					G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
					if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
					{ //providing the anim set succeeded..
						self->client->ps.weaponTime = self->client->ps.torsoTimer;
					}
				}
				return;
			}

			self->client->grappleIndex = grabbed->s.number;
			self->client->grappleState = 1;

			grabbed->client->grappleIndex = self->s.number;
			grabbed->client->grappleState = 20;

			//time to crack some heads
			G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, tortureAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
			if (self->client->ps.torsoAnim == tortureAnim)
			{ //providing the anim set succeeded..
				self->client->ps.weaponTime = self->client->ps.torsoTimer;
			}

			G_SetAnim(grabbed, &grabbed->client->pers.cmd, SETANIM_BOTH, correspondingAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
			if (grabbed->client->ps.torsoAnim == correspondingAnim)
			{ //providing the anim set succeeded..
				if (grabbed->client->ps.weapon == WP_SABER)
				{ //turn it off
					if (!grabbed->client->ps.saberHolstered)
					{
						grabbed->client->ps.saberHolstered = 2;
						if (grabbed->client->saber[0].soundOff)
						{
							G_Sound(grabbed, CHAN_AUTO, grabbed->client->saber[0].soundOff);
						}
						if (grabbed->client->saber[1].soundOff &&
							grabbed->client->saber[1].model[0])
						{
							G_Sound(grabbed, CHAN_AUTO, grabbed->client->saber[1].soundOff);
						}
					}
				}
				if (grabbed->client->ps.torsoTimer < self->client->ps.torsoTimer)
				{ //make sure they stay in the anim at least as long as the grabber
					grabbed->client->ps.torsoTimer = self->client->ps.torsoTimer;
				}
				grabbed->client->ps.weaponTime = grabbed->client->ps.torsoTimer;
			}
		}
	}

	if (self->client->ps.torsoTimer < 300 && !self->client->grappleState)
	{ //you failed to grab anyone, play the "failed to grab" anim
		G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
		if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
		{ //providing the anim set succeeded..
			self->client->ps.weaponTime = self->client->ps.torsoTimer;
		}
	}
}
Ejemplo n.º 6
0
void NPC_SetAnim(gentity_t *ent, int setAnimParts, int anim, int setAnimFlags)
{	// FIXME : once torsoAnim and legsAnim are in the same structure for NCP and Players
	// rename PM_SETAnimFinal to PM_SetAnim and have both NCP and Players call PM_SetAnim
	G_SetAnim(ent, NULL, setAnimParts, anim, setAnimFlags, 0);
}