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

📄 hl1_npc_nihilanth.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		if (m_hFriend[i] == NULL)
		{
			if ( random->RandomInt( 0, 1 ) == 0)
			{
				int iNode = GetNavigator()->GetNetwork()->NearestNodeToPoint( vecStart );
				CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( iNode );

				if ( pNode && pNode->GetType() == NODE_AIR )
				{
					trace_t tr;
					Vector vNodeOrigin = pNode->GetOrigin();

					UTIL_TraceHull( vNodeOrigin + Vector( 0, 0, 32 ), vNodeOrigin + Vector( 0, 0, 32 ), Vector(-40,-40,   0),	Vector(40, 40, 100), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

					if ( tr.startsolid == 0 )
						 m_hFriend[i] = Create("monster_alien_controller", vNodeOrigin, GetAbsAngles() );
				}
			}
			else
			{
				int iNode = GetNavigator()->GetNetwork()->NearestNodeToPoint( vecStart );
				CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( iNode );

				if ( pNode && ( pNode->GetType() == NODE_GROUND || pNode->GetType() == NODE_WATER ) )
				{
					trace_t tr;
					Vector vNodeOrigin = pNode->GetOrigin();

					UTIL_TraceHull( vNodeOrigin + Vector( 0, 0, 36 ), vNodeOrigin + Vector( 0, 0, 36 ), Vector( -15, -15, 0),	Vector( 20, 15, 72 ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
					
					if (tr.startsolid == 0)
						m_hFriend[i] = Create("monster_alien_slave", vNodeOrigin, GetAbsAngles() );
				}
			}
			if (m_hFriend[i] != NULL)
			{
				CPASAttenuationFilter filter( this );
				enginesound->EmitSound( filter, m_hFriend[i]->entindex(), CHAN_WEAPON, "debris/beamstart7.wav", 1.0, ATTN_NORM ); 
			}

			return;
		}
	}
}

void CNPC_Nihilanth::ShootBalls( void )
{
	if (m_flShootEnd > gpGlobals->curtime)
	{
		Vector vecHand;
		QAngle vecAngle;
		
		while (m_flShootTime < m_flShootEnd && m_flShootTime < gpGlobals->curtime)
		{
			if ( GetEnemy() != NULL)
			{
				Vector vecSrc, vecDir;
				CNihilanthHVR *pEntity = NULL;

				GetAttachment( 3, vecHand, vecAngle );
				vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime);
				vecDir = m_posTarget - GetAbsOrigin();
				VectorNormalize( vecDir );
				vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime);
				
				pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR,  "nihilanth_energy_ball" );

				pEntity->SetAbsOrigin( vecSrc );
				pEntity->SetAbsAngles( vecAngle );
				pEntity->SetOwnerEntity( this );
				pEntity->Spawn();

				pEntity->SetAbsVelocity( vecDir * 200.0 );
				pEntity->ZapInit( GetEnemy() );
				
				GetAttachment( 4, vecHand, vecAngle );
				vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime);
				vecDir = m_posTarget - GetAbsOrigin();
				VectorNormalize( vecDir );
				
				vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime);
				
				pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR,  "nihilanth_energy_ball" );

				pEntity->SetAbsOrigin( vecSrc );
				pEntity->SetAbsAngles( vecAngle );
				pEntity->SetOwnerEntity( this );
				pEntity->Spawn();

				pEntity->SetAbsVelocity( vecDir * 200.0 );
				pEntity->ZapInit( GetEnemy() );

			}

			m_flShootTime += 0.2;
		}
	}
}

void CNPC_Nihilanth::FloatSequence( void )
{
	if (m_irritation >= 2)
	{
		SetSequence( LookupSequence( "float_open" ) );
	}
	else if (m_avelocity.y > 30)
	{
		SetSequence( LookupSequence( "walk_r" ) );
	}
	else if (m_avelocity.y < -30)
	{
		SetSequence( LookupSequence( "walk_l" ) );
	}
	else if (m_velocity.z > 30)
	{
		SetSequence( LookupSequence( "walk_u" ) );
	} 
	else if (m_velocity.z < -30)
	{
		SetSequence( LookupSequence( "walk_d" ) );
	}
	else
	{
		SetSequence( LookupSequence( "float" ) );
	}
}

void CNPC_Nihilanth::DyingThink( void )
{
	SetNextThink( gpGlobals->curtime + 0.1 );
	DispatchAnimEvents( this );
	StudioFrameAdvance( );

	if ( m_lifeState == LIFE_ALIVE )
	{
		DeathSound( );
		m_lifeState = LIFE_DYING;

		m_posDesired.z = m_flMaxZ;
	}

	if ( GetAbsOrigin().z < m_flMaxZ && m_lifeState == LIFE_DEAD )
	{
		 SetAbsOrigin( Vector( GetAbsOrigin().x, GetAbsOrigin().y, m_flMaxZ ) );
		 SetAbsVelocity( Vector( 0, 0, 0 ) );
	}

	if ( m_lifeState == LIFE_DYING )
	{
		Flight( );

		if (fabs( GetAbsOrigin().z - m_flMaxZ ) < 16)
		{
			CBaseEntity *pTrigger = NULL;

			SetAbsVelocity( Vector( 0, 0, 0 ) );
			SetGravity( 0 );

			while( pTrigger = gEntList.FindEntityByName( pTrigger, m_szDeadUse, NULL ) )
			{
				CLogicRelay *pRelay = (CLogicRelay*)pTrigger;
				pRelay->m_OnTrigger.FireOutput( this, this );
			}

			m_lifeState = LIFE_DEAD;
		}
	}

	if ( IsSequenceFinished() )
	{
		QAngle qAngularVel = GetLocalAngularVelocity();

		qAngularVel.y += random->RandomFloat( -100, 100 );
	
		if ( qAngularVel.y < -100)
			 qAngularVel.y = -100;
		if ( qAngularVel.y > 100)
			 qAngularVel.y = 100;

		SetLocalAngularVelocity( qAngularVel );
		SetSequence( LookupSequence( "die1" ) );
	}

	if ( m_pBall )
	{
		if (m_pBall->GetBrightness() > 0)
		{
			m_pBall->SetBrightness( max( 0, m_pBall->GetBrightness() - 7 ), 0 );
		}
		else
		{
			UTIL_Remove( m_pBall );
			m_pBall = NULL;
		}
	}

	Vector vecDir, vecSrc;
	QAngle vecAngles;
	Vector vForward, vRight, vUp;

	AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );

	int iAttachment = random->RandomInt( 1, 4 );

	do {
		vecDir = Vector( random->RandomFloat( -1, 1 ), random->RandomFloat( -1, 1 ), random->RandomFloat( -1, 1 ) );
	} while (DotProduct( vecDir, vecDir) > 1.0);

	switch( random->RandomInt( 1, 4 ))
	{
	case 1: // head
		vecDir.z = fabs( vecDir.z ) * 0.5;
		vecDir = vecDir + 2 * vUp;
		break;
	case 2: // eyes
		if (DotProduct( vecDir, vForward ) < 0)
			vecDir = vecDir * -1;

		vecDir = vecDir + 2 * vForward;
		break;
	case 3: // left hand
		if (DotProduct( vecDir, vRight ) > 0)
			vecDir = vecDir * -1;
		vecDir = vecDir - 2 * vRight;
		break;
	case 4: // right hand
		if (DotProduct( vecDir, vRight ) < 0)
			vecDir = vecDir * -1;
		vecDir = vecDir + 2 * vRight;
		break;
	}

	GetAttachment( iAttachment, vecSrc, vecAngles );

	trace_t tr;

	UTIL_TraceLine( vecSrc, vecSrc + vecDir * 4096, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

	CBeam *pBeam = CBeam::BeamCreate( "sprites/laserbeam.vmt", 16 );

	if ( pBeam == NULL )
		 return;

	pBeam->PointEntInit( tr.endpos, this );
	pBeam->SetEndAttachment( iAttachment );
	pBeam->SetColor( 64, 128, 255 );
	pBeam->SetFadeLength( 50 );
	pBeam->SetBrightness( 255 );
	pBeam->SetNoise( 12 );
	pBeam->SetScrollRate( 1.0 );
	pBeam->LiveForTime( 0.5 );
	
	GetAttachment( 0, vecSrc, vecAngles ); 
	CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
	
	pEntity->SetAbsOrigin( vecSrc );
	pEntity->SetAbsAngles( GetAbsAngles() );
	pEntity->SetOwnerEntity( this );
	pEntity->SetAbsVelocity( Vector ( random->RandomFloat( -0.7, 0.7 ), random->RandomFloat( -0.7, 0.7 ), 1.0 ) * 600.0 );
	pEntity->Spawn();

	pEntity->GreenBallInit();

	return;
}


void CNPC_Nihilanth::HandleAnimEvent( animevent_t *pEvent )
{
	switch( pEvent->event )
	{
	case 1:	// shoot 
		break;
	case 2:	// zen
		if ( GetEnemy() != NULL)
		{
			Vector vOrigin;
			QAngle vAngle;
			CPASAttenuationFilter filter( this );
		
			if ( random->RandomInt(0,4) == 0)
				enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pAttackSounds ), 1.0, 0.2 ); 
			
			enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pBallSounds ), 1.0, 0.2 ); 

			GetAttachment( 2, vOrigin, vAngle);
			
			CBroadcastRecipientFilter filterlight;

			te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );

			GetAttachment( 3, vOrigin, vAngle);
			te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );
		
			m_flShootTime = gpGlobals->curtime;
			m_flShootEnd = gpGlobals->curtime + 1.0;
		}
		break;
	case 3:	// prayer
		if (GetEnemy() != NULL)
		{
			char szText[32];

			Q_snprintf( szText, sizeof( szText ), "%s%d", m_szTeleportTouch, m_iTeleport );
			CBaseEntity *pTouch = gEntList.FindEntityByName( NULL, szText, NULL );

			Q_snprintf( szText, sizeof( szText ), "%s%d", m_szTeleportUse, m_iTeleport );
			CBaseEntity *pTrigger = gEntList.FindEntityByName( NULL, szText, NULL );

			if (pTrigger != NULL || pTouch != NULL)
			{
				CPASAttenuationFilter filter( this );
				enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pAttackSounds ), 1.0, 0.2 ); 

				Vector vecSrc;
				QAngle vecAngles;

				GetAttachment( 2, vecSrc, vecAngles ); 

				CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
				
				pEntity->SetAbsOrigin( vecSrc );
				pEntity->SetAbsAngles( vecAngles );
				pEntity->SetOwnerEntity( this );
				pEntity->Spawn();

				pEntity->TeleportInit( this, GetEnemy(), pTrigger, pTouch );

				pEntity->SetAbsVelocity( GetAbsOrigin() - vecSrc );
				pEntity->SetAbsVelocity( Vector( GetAbsVelocity().x, GetAbsVelocity().y, GetAbsVelocity().z * 0.2 ) );

			}
			else
			{
				Vector vOrigin;
				QAngle vAngle;

				m_iTeleport++; // unexpected failure

				CPASAttenuationFilter filter( this );
				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pBallSounds ), 1.0, 0.2 ); 

				Msg( "nihilanth can't target %s\n", szText );

				GetAttachment( 2, vOrigin, vAngle);
			
				CBroadcastRecipientFilter filterlight;

				te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );

				GetAttachment( 3, vOrigin, vAngle);
				te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );

				m_flShootTime = gpGlobals->curtime;
				m_flShootEnd = gpGlobals->curtime + 1.0;
			}
		}
		break;
	case 4:	// get a sphere
		{
			if (m_hRecharger != NULL)
			{
				if (!EmitSphere( ))
				{
					m_hRecharger = NULL;
				}
			}
		}
		break;
	case 5:	// start up sphere machine
		{
			CPASAttenuationFilter filter( this );
			enginesound->EmitSound( filter, entindex(), CHAN_VOICE , RANDOM_SOUND_ARRAY( pRechargeSounds ), 1.0, 0.2 ); 
		}
		break;
	case 6:
		if ( GetEnemy() != NULL)
		{
			Vector vecSrc;
			QAngle vecAngles;
			GetAttachment( 3, vecSrc, vecAngles ); 
						
			CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR,  "nihilanth_energy_ball" );

			pEntity->SetAbsOrigin( vecSrc );
			pEntity->SetAbsAngles( vecAngles );
			pEntity->SetOwnerEntity( this );
			pEntity->Spawn();

			pEntity->SetAbsVelocity( GetAbsOrigin() - vecSrc );
			pEntity->ZapInit( GetEnemy() );
		}
		break;
	case 7:
		/*
		Vector vecSrc, vecAngles;
		GetAttachment( 0, vecSrc, vecAngles ); 
		CNihilanthHVR *pEntity = (CNihilanthHVR *)Create( "nihilanth_energy_ball", vecSrc, pev->angles, edict() );
		pEntity->pev->velocity = Vector ( RANDOM_FLOAT( -0.7, 0.7 ), RANDOM_FLOAT( -0.7, 0.7 ), 1.0 ) * 600.0;
		pEntity->GreenBallInit( );
		*/
		break;
	}
}


//=========================================================
// Controller bouncy ball attack
//=========================================================



void CNihilanthHVR::Spawn( void )
{
	Precache( );
}


void CNihilanthHVR::Precache( void )
{
	engine->PrecacheModel("sprites/flare6.vmt");
	engine->PrecacheModel("sprites/nhth1.vmt");
	engine->PrecacheModel("sprites/exit1.vmt");
	engine->PrecacheModel("sprites/tele1.vmt");
	engine->PrecacheModel("sprites/animglow01.vmt");
	engine->PrecacheModel("sprites/xspark4.vmt");
	engine->PrecacheModel("sprites/muzzleflash3.vmt");
	enginesound->PrecacheSound("debris/zap4.wav");
	enginesound->PrecacheSound("weapons/electro4.wav");
	enginesound->PrecacheSound("x/x_teleattack1.wav");

	engine->PrecacheModel("sprites/laserbeam.vmt");
}

void CNihilanthHVR::CircleInit( CBaseEntity *pTarget )
{
	SetMoveType( MOVETYPE_FLY );
	SetSolid( SOLID_NONE );

	UTIL_SetSize( this, Vector( 0, 0, 0), Vector(0, 0, 0));
	UTIL_SetOrigin( this, GetAbsOrigin() );

	SetThink( &CNihilanthHVR::HoverThink );
	SetTouch( &CNihilanthHVR::BounceTouch );

⌨️ 快捷键说明

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