コード例 #1
0
ファイル: bg_lua.cpp プロジェクト: dpadgett/japp
static int JPLua_ScreenShake(lua_State *L){
	vector3 *origin = JPLua_CheckVector(L, 1);
	float intense = luaL_checknumber(L, 2);
	int duration = luaL_checkinteger(L, 3);
	qboolean global = lua_toboolean(L, 4);

	G_ScreenShake(origin, NULL, intense, duration, global);
	return 0;
}
コード例 #2
0
ファイル: NPC_AI_Rancor.c プロジェクト: Almightygir/OpenJK
void Rancor_Attack( float distance, qboolean doCharge )
{

	if ( !TIMER_Exists( NPCS.NPC, "attacking" ) )
	{
		if ( NPCS.NPC->count == 2 && NPCS.NPC->activator )
		{
		}
		else if ( NPCS.NPC->count == 1 && NPCS.NPC->activator )
		{//holding enemy
			if ( NPCS.NPC->activator->health > 0 && Q_irand( 0, 1 ) )
			{//quick bite
				NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				TIMER_Set( NPCS.NPC, "attack_dmg", 450 );
			}
			else
			{//full eat
				NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK3, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				TIMER_Set( NPCS.NPC, "attack_dmg", 900 );
				//Make victim scream in fright
				if ( NPCS.NPC->activator->health > 0 && NPCS.NPC->activator->client )
				{
					G_AddEvent( NPCS.NPC->activator, Q_irand(EV_DEATH1, EV_DEATH3), 0 );
					NPC_SetAnim( NPCS.NPC->activator, SETANIM_TORSO, BOTH_FALLDEATH1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
					if ( NPCS.NPC->activator->NPC )
					{//no more thinking for you
						TossClientItems( NPCS.NPC );
						NPCS.NPC->activator->NPC->nextBStateThink = Q3_INFINITE;
					}
				}
			}
		}
		else if ( NPCS.NPC->enemy->health > 0 && doCharge )
		{//charge
			vec3_t	fwd, yawAng;
			VectorSet( yawAng, 0, NPCS.NPC->client->ps.viewangles[YAW], 0 );
			AngleVectors( yawAng, fwd, NULL, NULL );
			VectorScale( fwd, distance*1.5f, NPCS.NPC->client->ps.velocity );
			NPCS.NPC->client->ps.velocity[2] = 150;
			NPCS.NPC->client->ps.groundEntityNum = ENTITYNUM_NONE;

			NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_MELEE2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
			TIMER_Set( NPCS.NPC, "attack_dmg", 1250 );
		}
		else if ( !Q_irand(0, 1) )
		{//smash
			NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_MELEE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
			TIMER_Set( NPCS.NPC, "attack_dmg", 1000 );
		}
		else
		{//try to grab
			NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
			TIMER_Set( NPCS.NPC, "attack_dmg", 1000 );
		}

		TIMER_Set( NPCS.NPC, "attacking", NPCS.NPC->client->ps.legsTimer + random() * 200 );
	}

	// Need to do delayed damage since the attack animations encapsulate multiple mini-attacks

	if ( TIMER_Done2( NPCS.NPC, "attack_dmg", qtrue ) )
	{
		vec3_t shakePos;
		switch ( NPCS.NPC->client->ps.legsAnim )
		{
		case BOTH_MELEE1:
			Rancor_Smash();
			G_GetBoltPosition( NPCS.NPC, NPCS.NPC->client->renderInfo.handLBolt, shakePos, 0 );
			G_ScreenShake( shakePos, NULL, 4.0f, 1000, qfalse );
			//CGCam_Shake( 1.0f*playerDist/128.0f, 1000 );
			break;
		case BOTH_MELEE2:
			Rancor_Bite();
			TIMER_Set( NPCS.NPC, "attack_dmg2", 450 );
			break;
		case BOTH_ATTACK1:
			if ( NPCS.NPC->count == 1 && NPCS.NPC->activator )
			{
				G_Damage( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC, vec3_origin, NPCS.NPC->activator->r.currentOrigin, Q_irand( 25, 40 ), DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK, MOD_MELEE );
				if ( NPCS.NPC->activator->health <= 0 )
				{//killed him
					//make it look like we bit his head off
					//NPC->activator->client->dismembered = qfalse;
					G_Dismember( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC->activator->r.currentOrigin, G2_MODELPART_HEAD, 90, 0, NPCS.NPC->activator->client->ps.torsoAnim, qtrue);
					//G_DoDismemberment( NPC->activator, NPC->activator->r.currentOrigin, MOD_SABER, 1000, HL_HEAD, qtrue );
					NPCS.NPC->activator->client->ps.forceHandExtend = HANDEXTEND_NONE;
					NPCS.NPC->activator->client->ps.forceHandExtendTime = 0;
					NPC_SetAnim( NPCS.NPC->activator, SETANIM_BOTH, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				}
				G_Sound( NPCS.NPC->activator, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/chomp.wav" ) );
			}
			break;
		case BOTH_ATTACK2:
			//try to grab
			Rancor_Swing( qtrue );
			break;
		case BOTH_ATTACK3:
			if ( NPCS.NPC->count == 1 && NPCS.NPC->activator )
			{
				//cut in half
				if ( NPCS.NPC->activator->client )
				{
					//NPC->activator->client->dismembered = qfalse;
					G_Dismember( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC->activator->r.currentOrigin, G2_MODELPART_WAIST, 90, 0, NPCS.NPC->activator->client->ps.torsoAnim, qtrue);
					//G_DoDismemberment( NPC->activator, NPC->enemy->r.currentOrigin, MOD_SABER, 1000, HL_WAIST, qtrue );
				}
				//KILL
				G_Damage( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC, vec3_origin, NPCS.NPC->activator->r.currentOrigin, NPCS.NPC->enemy->health+10, DAMAGE_NO_PROTECTION|DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK|DAMAGE_NO_HIT_LOC, MOD_MELEE );//, HL_NONE );//
				if ( NPCS.NPC->activator->client )
				{
					NPCS.NPC->activator->client->ps.forceHandExtend = HANDEXTEND_NONE;
					NPCS.NPC->activator->client->ps.forceHandExtendTime = 0;
					NPC_SetAnim( NPCS.NPC->activator, SETANIM_BOTH, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
				}
				TIMER_Set( NPCS.NPC, "attack_dmg2", 1350 );
				G_Sound( NPCS.NPC->activator, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/swipehit.wav" ) );
				G_AddEvent( NPCS.NPC->activator, EV_JUMP, NPCS.NPC->activator->health );
			}
			break;
		}
	}
	else if ( TIMER_Done2( NPCS.NPC, "attack_dmg2", qtrue ) )
	{
		switch ( NPCS.NPC->client->ps.legsAnim )
		{
		case BOTH_MELEE1:
			break;
		case BOTH_MELEE2:
			Rancor_Bite();
			break;
		case BOTH_ATTACK1:
			break;
		case BOTH_ATTACK2:
			break;
		case BOTH_ATTACK3:
			if ( NPCS.NPC->count == 1 && NPCS.NPC->activator )
			{//swallow victim
				G_Sound( NPCS.NPC->activator, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/chomp.wav" ) );
				//FIXME: sometimes end up with a live one in our mouths?
				//just make sure they're dead
				if ( NPCS.NPC->activator->health > 0 )
				{
					//cut in half
					//NPC->activator->client->dismembered = qfalse;
					G_Dismember( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC->activator->r.currentOrigin, G2_MODELPART_WAIST, 90, 0, NPCS.NPC->activator->client->ps.torsoAnim, qtrue);
					//G_DoDismemberment( NPC->activator, NPC->enemy->r.currentOrigin, MOD_SABER, 1000, HL_WAIST, qtrue );
					//KILL
					G_Damage( NPCS.NPC->activator, NPCS.NPC, NPCS.NPC, vec3_origin, NPCS.NPC->activator->r.currentOrigin, NPCS.NPC->enemy->health+10, DAMAGE_NO_PROTECTION|DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK|DAMAGE_NO_HIT_LOC, MOD_MELEE );//, HL_NONE );
					NPCS.NPC->activator->client->ps.forceHandExtend = HANDEXTEND_NONE;
					NPCS.NPC->activator->client->ps.forceHandExtendTime = 0;
					NPC_SetAnim( NPCS.NPC->activator, SETANIM_BOTH, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
					G_AddEvent( NPCS.NPC->activator, EV_JUMP, NPCS.NPC->activator->health );
				}
				if ( NPCS.NPC->activator->client )
				{//*sigh*, can't get tags right, just remove them?
					NPCS.NPC->activator->client->ps.eFlags |= EF_NODRAW;
				}
				NPCS.NPC->count = 2;
				TIMER_Set( NPCS.NPC, "clearGrabbed", 2600 );
			}
			break;
		}
	}
	else if ( NPCS.NPC->client->ps.legsAnim == BOTH_ATTACK2 )
	{
		if ( NPCS.NPC->client->ps.legsTimer >= 1200 && NPCS.NPC->client->ps.legsTimer <= 1350 )
		{
			if ( Q_irand( 0, 2 ) )
			{
				Rancor_Swing( qfalse );
			}
			else
			{
				Rancor_Swing( qtrue );
			}
		}
		else if ( NPCS.NPC->client->ps.legsTimer >= 1100 && NPCS.NPC->client->ps.legsTimer <= 1550 )
		{
			Rancor_Swing( qtrue );
		}
	}

	// Just using this to remove the attacking flag at the right time
	TIMER_Done2( NPCS.NPC, "attacking", qtrue );
}
コード例 #3
0
static void Howler_Howl( void )
{
	//gentity_t	*radiusEnts[ 128 ];
	int			radiusEntsNums[128];
	gentity_t	*ent;
	int			numEnts;
	const float	radius = (NPC->spawnflags&1)?256:128;
	const float	halfRadSquared = ((radius/2)*(radius/2));
	const float	radiusSquared = (radius*radius);
	float		distSq;
	int			i;
	vec3_t		boltOrg;

	AddSoundEvent( NPC, NPC->r.currentOrigin, 512, AEL_DANGER, qfalse, qtrue );

	//RACC - handLBolt never defined for Howlers? *shrug* just use the tongue base
	numEnts = NPC_GetEntsNearBolt( radiusEntsNums, radius, NPC->NPC->genericBolt1, boltOrg );
	//numEnts = NPC_GetEntsNearBolt( radiusEnts, radius, NPC->handLBolt, boltOrg );

	for ( i = 0; i < numEnts; i++ )
	{
		ent = &g_entities[radiusEntsNums[i]];

		if ( !ent->inuse )
		{
			continue;
		}
		
		if ( ent == NPC )
		{//Skip the rancor ent
			//RACC - assume this means the source howler
			continue;
		}
		
		if ( ent->client == NULL )
		{//must be a client
			continue;
		}

		if ( ent->client->NPC_class == CLASS_HOWLER )
		{//other howlers immune
			continue;
		}

		distSq = DistanceSquared( ent->r.currentOrigin, boltOrg );
		if ( distSq <= radiusSquared )
		{
			if ( distSq < halfRadSquared )
			{//close enough to do damage, too
				if ( Q_irand( 0, g_spskill.integer ) )
				{//does no damage on easy, does 1 point every other frame on medium, more often on hard
					//RACC - Impact isn't a MOD in MP.
					G_Damage( ent, NPC, NPC, vec3_origin, NPC->r.currentOrigin, 1, DAMAGE_NO_KNOCKBACK, MOD_CRUSH );
					//G_Damage( ent, NPC, NPC, vec3_origin, NPC->r.currentOrigin, 1, DAMAGE_NO_KNOCKBACK, MOD_IMPACT );
				}
			}
			if ( ent->health > 0 
				&& ent->client
				&& ent->client->NPC_class != CLASS_RANCOR
				&& ent->client->NPC_class != CLASS_ATST 
				&& !PM_InKnockDown( &ent->client->ps ) )
			{
				if ( BG_HasAnimation( ent->localAnimIndex, BOTH_SONICPAIN_START ) )
				{
					if ( ent->client->ps.torsoAnim != BOTH_SONICPAIN_START 
						&& ent->client->ps.torsoAnim != BOTH_SONICPAIN_HOLD )
					{
						NPC_SetAnim( ent, SETANIM_LEGS, BOTH_SONICPAIN_START, SETANIM_FLAG_NORMAL );
						NPC_SetAnim( ent, SETANIM_TORSO, BOTH_SONICPAIN_START, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
						ent->client->ps.torsoTimer += 100;
						ent->client->ps.weaponTime = ent->client->ps.torsoTimer;
					}
					else if ( ent->client->ps.torsoTimer <= 100 )
					{//at the end of the sonic pain start or hold anim
						NPC_SetAnim( ent, SETANIM_LEGS, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_NORMAL );
						NPC_SetAnim( ent, SETANIM_TORSO, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
						ent->client->ps.torsoTimer += 100; 
						ent->client->ps.weaponTime = ent->client->ps.torsoTimer;
					}
				}
				/*  racc - commented out of SP code?
				else if ( distSq < halfRadSquared 
					&& radiusEnts[i]->client->ps.groundEntityNum != ENTITYNUM_NONE 
					&& !Q_irand( 0, 10 ) )//FIXME: base on skill
				{//within range
					G_Knockdown( radiusEnts[i], NPC, vec3_origin, 500, qfalse );
				}
				*/
			}
		}

		//camera shaking
		distSq = Distance( boltOrg, ent->r.currentOrigin );
		if ( distSq < 256.0f )
		{
			G_ScreenShake(boltOrg, ent, 1.0f*distSq/128.0f, 200, qfalse);
		}
	}

	//RACC - changed to work for multiple players
	/*
	playerDist = NPC_EntRangeFromBolt( player, NPC->genericBolt1 );
	if ( playerDist < 256.0f )
	{
		CGCam_Shake( 1.0f*playerDist/128.0f, 200 );
	}
	*/
}