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

📄 hl1_npc_gargantua.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	PRECACHE_SOUND_ARRAY(pFootSounds);
	PRECACHE_SOUND_ARRAY(pIdleSounds);
	PRECACHE_SOUND_ARRAY(pAlertSounds);
	PRECACHE_SOUND_ARRAY(pPainSounds);
	PRECACHE_SOUND_ARRAY(pAttackSounds);
	PRECACHE_SOUND_ARRAY(pStompSounds);
	PRECACHE_SOUND_ARRAY(pBreatheSounds);
}	

Class_T  CNPC_Gargantua::Classify ( void )
{
	return CLASS_ALIEN_MONSTER;
}

void CNPC_Gargantua :: PrescheduleThink( void )
{
	if ( !HasCondition( COND_SEE_ENEMY ) )
	{
		m_seeTime = gpGlobals->curtime + 5;
		EyeOff();
	}
	else
	{
		EyeOn( 200 );
	}
	
	EyeUpdate();
}

float CNPC_Gargantua::MaxYawSpeed ( void )	
{
	float ys = 60;

	switch ( GetActivity() )
	{
	case ACT_IDLE:
		ys = 60;
		break;
	case ACT_TURN_LEFT:
	case ACT_TURN_RIGHT:
		ys = 180;
		break;
	case ACT_WALK:
	case ACT_RUN:
		ys = 60;
		break;

	default:
		ys = 60;
		break;
	}

	return ys;
}

int CNPC_Gargantua::MeleeAttack1Conditions( float flDot, float flDist )
{
	if (flDot >= 0.7)
	{
		if ( flDist <= GARG_ATTACKDIST )
		{
			 return COND_CAN_MELEE_ATTACK1;
		}
	}

	return COND_NONE;
}


// Flame thrower madness!
int CNPC_Gargantua::MeleeAttack2Conditions( float flDot, float flDist )
{
	if ( gpGlobals->curtime > m_flameTime )
	{
		if ( flDot >= 0.8 )
		{
			if ( flDist > GARG_ATTACKDIST )
			{
				if ( flDist <= GARG_FLAME_LENGTH )
					 return COND_CAN_MELEE_ATTACK2;
			}
		}
	}
	
	return COND_NONE;
}

//=========================================================
// CheckRangeAttack1
// flDot is the cos of the angle of the cone within which
// the attack can occur.
//=========================================================
//
// Stomp attack
//
//=========================================================
int CNPC_Gargantua::RangeAttack1Conditions( float flDot, float flDist )
{
	if ( gpGlobals->curtime > m_seeTime )
	{
		if ( flDot >= 0.7 )
		{
			if ( flDist > GARG_ATTACKDIST )
			{
				 return COND_CAN_RANGE_ATTACK1;
			}
		}
	}

	return COND_NONE;
}

//=========================================================
// CheckTraceHullAttack - expects a length to trace, amount 
// of damage to do, and damage type. Returns a pointer to
// the damaged entity in case the monster wishes to do
// other stuff to the victim (punchangle, etc)
// Used for many contact-range melee attacks. Bites, claws, etc.

// Overridden for Gargantua because his swing starts lower as
// a percentage of his height (otherwise he swings over the
// players head)
//=========================================================
CBaseEntity* CNPC_Gargantua::GargantuaCheckTraceHullAttack(float flDist, int iDamage, int iDmgType)
{
	trace_t tr;

	Vector vForward, vUp;
	AngleVectors( GetAbsAngles(), &vForward, NULL, &vUp );

	Vector vecStart = GetAbsOrigin();
	vecStart.z += 64;
	Vector vecEnd = vecStart + ( vForward * flDist) - ( vUp * flDist * 0.3);

	//UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr );

	UTIL_TraceEntity( this, GetAbsOrigin(), vecEnd, MASK_SOLID, &tr );
	
	if ( tr.m_pEnt )
	{
		CBaseEntity *pEntity = tr.m_pEnt;

		if ( iDamage > 0 )
		{
			CTakeDamageInfo info( this, this, iDamage, iDmgType );
			CalculateMeleeDamageForce( &info, vForward, tr.endpos );
			pEntity->TakeDamage( info );
		}

		return pEntity;
	}

	return NULL;
}

void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent )
{
	CPASAttenuationFilter filter( this );

	switch( pEvent->event )
	{
	case GARG_AE_SLASH_LEFT:
		{
			// HACKHACK!!!
			CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH );

			if (pHurt)
			{
				if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) )
				{
					pHurt->ViewPunch( QAngle( -30, -30, 30 ) );

					Vector vRight;
					AngleVectors( GetAbsAngles(), NULL, &vRight, NULL );
					pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 );
				}

				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
			}
			else // Play a random attack miss sound
				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
		}
		break;

	case GARG_AE_RIGHT_FOOT:
	case GARG_AE_LEFT_FOOT:

		UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START );
		enginesound->EmitSound( filter, entindex(), CHAN_BODY, pFootSounds[ random->RandomInt(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
		break;

	case GARG_AE_STOMP:
		StompAttack();
		m_seeTime = gpGlobals->curtime + 12;
		break;

	case GARG_AE_BREATHE:
		enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pBreatheSounds[ random->RandomInt(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
		break;

	default:
		BaseClass::HandleAnimEvent(pEvent);
		break;
	}
}

int CNPC_Gargantua::TranslateSchedule( int scheduleType )
{
	//TEMP TEMP
	if ( FlameIsOn() )
		 FlameDestroy();

	switch( scheduleType )
	{
		case SCHED_MELEE_ATTACK2:
			return SCHED_GARG_FLAME;
		case SCHED_MELEE_ATTACK1:
			return SCHED_GARG_SWIPE;

			
		case SCHED_CHASE_ENEMY_FAILED:
		case SCHED_ALERT_STAND:
			return SCHED_CHASE_ENEMY;
			 
		break;
	}

	return BaseClass::TranslateSchedule( scheduleType );
}

void CNPC_Gargantua::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_FLAME_SWEEP:

		//TEMP TEMP
		FlameCreate();
		m_flWaitFinished = gpGlobals->curtime + pTask->flTaskData;
		m_flameTime = gpGlobals->curtime + 6;
		m_flameX = 0;
		m_flameY = 0;
		break;

	case TASK_SOUND_ATTACK:

		if ( random->RandomInt(0,100) < 30 )
		{
			CPASAttenuationFilter filter( this );
			enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pAttackSounds[ random->RandomInt(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM );
		}
			
		TaskComplete();
		break;
	
	case TASK_DIE:
		m_flWaitFinished = gpGlobals->curtime + 1.6;
		DeathEffect();
		// FALL THROUGH
	default: 
		BaseClass::StartTask( pTask );
		break;
	}
}

bool CNPC_Gargantua::ShouldGib( const CTakeDamageInfo &info )
{
	return false;
}

//=========================================================
// RunTask
//=========================================================
void CNPC_Gargantua::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_DIE:

		if ( gpGlobals->curtime > m_flWaitFinished )
		{
			//TEMP TEMP
			m_nRenderFX = kRenderFxExplode;
			SetRenderColor( 255, 0, 0 , 255 );
			StopAnimation();
			SetNextThink( gpGlobals->curtime + 0.15 );
			SetThink( SUB_Remove );

			int i;
		
			int parts = modelinfo->GetModelFrameCount( modelinfo->GetModel( gGargGibModel ) );

			for ( i = 0; i < 10; i++ )
			{
				CGib *pGib = CREATE_ENTITY( CGib, "gib" );

				pGib->Spawn( GARG_GIB_MODEL);
				
				int bodyPart = 0;

				if ( parts > 1 )
					 bodyPart = random->RandomInt( 0, parts-1 );

				pGib->SetBodygroup( 0, bodyPart );
				pGib->SetBloodColor( BLOOD_COLOR_YELLOW );
				pGib->m_material = matNone;
				pGib->SetAbsOrigin( GetAbsOrigin() );
				pGib->SetAbsVelocity( UTIL_RandomBloodVector() * random->RandomFloat( 300, 500 ) );
	
				pGib->SetNextThink( gpGlobals->curtime + 1.25 );
				pGib->SetThink( SUB_FadeOut );
				pGib->m_flModelScale = 10;
			}
	
			Vector vecSize = Vector( 200, 200, 128 );
			CPVSFilter filter( GetAbsOrigin() );
			te->BreakModel( filter, 0.0, &GetAbsOrigin(), &vecSize, &vec3_origin, gGargGibModel, 200, 50, 3.0, BREAK_FLESH );
	
			return;
		}
		else
			BaseClass::RunTask( pTask );
		break;

	case TASK_FLAME_SWEEP:
		if ( gpGlobals->curtime > m_flWaitFinished )
		{
			//TEMP TEMP
			FlameDestroy();
			TaskComplete();
			FlameControls( 0, 0 );
			SetBoneController( 0, 0 );
			SetBoneController( 1, 0 );
		}
		else
		{
			bool cancel = false;

			QAngle angles = QAngle( 0, 0, 0 );

			//TEMP TEMP
			FlameUpdate();
			CBaseEntity *pEnemy = GetEnemy();

			if ( pEnemy )
			{
				Vector org = GetAbsOrigin();
				org.z += 64;
				Vector dir = pEnemy->BodyTarget(org) - org;

				VectorAngles( dir, angles );
				angles.x = -angles.x;
				angles.y -= GetAbsAngles().y;

				if ( dir.Length() > 400 )
					cancel = true;
			}
			if ( fabs(angles.y) > 60 )
				cancel = true;
			
			if ( cancel )
			{
				m_flWaitFinished -= 0.5;
				m_flameTime -= 0.5;
			}

			//TEMP TEMP
			//FlameControls( angles.x + 2 * sin(gpGlobals->curtime*8), angles.y + 28 * sin(gpGlobals->curtime*8.5) );
			FlameControls( angles.x, angles.y );
		}
		break;

	default:
		BaseClass::RunTask( pTask );
		break;
	}
}

void CNPC_Gargantua::FlameCreate( void )
{
	int			i;
	Vector		posGun;
	QAngle angleGun;

	trace_t trace;

	Vector	vForward;

	AngleVectors( GetAbsAngles(), &vForward );

 	for ( i = 0; i < 4; i++ )
	{
		if ( i < 2 )
			m_pFlame[i] = CBeam::BeamCreate( GARG_BEAM_SPRITE_NAME, 24.0 );

⌨️ 快捷键说明

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