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

📄 hl1_npc_osprey.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	ApplySidewaysDrag( right );
	ApplyGeneralDrag();
	
	// apply power to stay correct height
	// FIXME: these need to be per class variables
#define MAX_FORCE		80
#define FORCE_POSDELTA	12	
#define FORCE_NEGDELTA	8

	if (m_flForce < MAX_FORCE && vecEst.z < m_vecDesiredPosition.z) 
	{
		m_flForce += FORCE_POSDELTA;
	}
	else if (m_flForce > 30)
	{
		if (vecEst.z > m_vecDesiredPosition.z) 
			m_flForce -= FORCE_NEGDELTA;
	}
	
	// pitch forward or back to get to target
	//-----------------------------------------
	// Pitch is reversed since Half-Life! (sjb)
	//-----------------------------------------


	// when we're way out, lean forward up to 40 degrees to accelerate to target
	// not exceeding our goal speed.
#if 0
	float nodeSpeed = m_pGoalEnt->m_flSpeed;

	if ( flDist > 300 && flSpeed < m_flGoalSpeed && GetLocalAngles().x + angVel.x < 25 )
	{
		angVel.x += 8.0;	//lean forward
	}
	else if ( flDist < 500 && GetLocalAngles().x + angVel.x > -30 && nodeSpeed == 0)
	{
		angVel.x -= 8.0;	// lean backwards as we approach the target
	}
	else if (GetLocalAngles().x + angVel.x < -20 )
	{
		// ALERT( at_console, "f " );
		angVel.x += 2.0;
	}
	else if (GetLocalAngles().x + angVel.x > 20 )
	{
		// ALERT( at_console, "b " );
		angVel.x -= 2.0;
	}
#else
	m_angleVelocity = GetLocalAngles().x + angVel.x;
	float angleX = angVel.x;

//	Msg("AngVel %f, %f\n", m_angleVelocity, flDist);
	if (flDist > 128 && flSpeed < m_flGoalSpeed && m_angleVelocity < 30)
	{
		// ALERT( at_console, "F " );
		// lean forward
		angleX += 12.0;
	}
	else if (flDist < -128 && flSpeed > -50 && m_angleVelocity  > -20)
	{
		// ALERT( at_console, "B " );
		// lean backward
		angleX -= 12.0;
	}
	else if ( (m_angleVelocity < -20) || (m_angleVelocity < 0 && flDist < 128) )
	{
		// ALERT( at_console, "f " );
		if ( abs(m_angleVelocity) < 5 )
		{
			angleX += 1.0;
		}
		else
		{
			angleX += 4.0;
		}
	}
	else if ( (m_angleVelocity > 20) || (m_angleVelocity > 0 && flDist < 128) )
	{
		// ALERT( at_console, "b " );
		if ( abs(m_angleVelocity) < 5 )
		{
			angleX -= 1.0;
		}
		else
		{
			angleX -= 4.0;
		}
	}

	angVel.x = angleX;
	//Msg("AngVel.x %f %f\n", angVel.x, angleX );

#endif

	SetLocalAngularVelocity( angVel );
	// ALERT( at_console, "%.0f %.0f : %.0f %.0f : %.0f %.0f : %.0f\n", GetAbsOrigin().x, GetAbsVelocity().x, flDist, flSpeed, GetLocalAngles().x, m_vecAngVelocity.x, m_flForce ); 
	// ALERT( at_console, "%.0f %.0f : %.0f %0.f : %.0f\n", GetAbsOrigin().z, GetAbsVelocity().z, vecEst.z, m_vecDesiredPosition.z, m_flForce ); 
}


//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::InitializeRotorSound( void )
{
	if (m_pRotorSound)
	{
		CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

		// Get the rotor sound started up.
		controller.Play( m_pRotorSound, 0.0, 100 );
		controller.SoundChangeVolume(m_pRotorSound, GetRotorVolume(), 2.0);
	}

	m_iSoundState = SND_CHANGE_PITCH; // hack for going through level transitions
}


//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::UpdateRotorSoundPitch( int iPitch )
{
	if (m_pRotorSound)
	{
		CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
		controller.SoundChangePitch( m_pRotorSound, iPitch, 0.1 );
		controller.SoundChangeVolume( m_pRotorSound, GetRotorVolume(), 0.1 );
	}
}


//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::FlyTouch( CBaseEntity *pOther )
{
	// bounce if we hit something solid
	if ( pOther->GetSolid() == SOLID_BSP) 
	{
		trace_t tr = CBaseEntity::GetTouchTrace( );

		// UNDONE, do a real bounce
		ApplyAbsVelocityImpulse( tr.plane.normal * (GetAbsVelocity().Length() + 200) );
	}
}


//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::CrashTouch( CBaseEntity *pOther )
{
	// only crash if we hit something solid
	if ( pOther->GetSolid() == SOLID_BSP) 
	{
		SetTouch( NULL );
		SetNextThink( gpGlobals->curtime );
		Vector position = GetAbsOrigin();
		position.z += 32;

		CPASFilter filter( GetAbsOrigin() );
		for (int i = 0; i < 7; i++)
		{
			te->Explosion( filter, i * 0.2,	&GetAbsOrigin(), g_sModelIndexFireball,	10, 15, TE_EXPLFLAG_NONE, 100, 0 );
			position.z += 15;
		}
		UTIL_Remove( this );
	}
}


//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::DyingThink( void )
{
	StudioFrameAdvance( );
	SetNextThink( gpGlobals->curtime + 0.1f );

	SetLocalAngularVelocity( GetLocalAngularVelocity() * 1.02 );
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------
int CBaseHelicopter::OnTakeDamage_Alive( const CTakeDamageInfo &info )
{
#if 0
	// This code didn't port easily. WTF does it do? (sjb)
	if (pevInflictor->m_owner == pev)
		return 0;
#endif

	/*
	if ( (bitsDamageType & DMG_BULLET) && flDamage > 50)
	{
		// clip bullet damage at 50
		flDamage = 50;
	}
	*/

	return BaseClass::OnTakeDamage_Alive( info );
}


//-----------------------------------------------------------------------------
// Purpose: Override base class to add display of fly direction
// Input  :
// Output : 
//-----------------------------------------------------------------------------
void CBaseHelicopter::DrawDebugGeometryOverlays(void) 
{
	if (m_pfnThink!= NULL)
	{
		// ------------------------------
		// Draw route if requested
		// ------------------------------
		if (m_debugOverlays & OVERLAY_NPC_ROUTE_BIT)
		{
			NDebugOverlay::Line(GetAbsOrigin(), m_vecDesiredPosition, 0,0,255, true, 0);
		}
	}
	BaseClass::DrawDebugGeometryOverlays();
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------
void CBaseHelicopter::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
	CTakeDamageInfo dmgInfo = info;

	// ALERT( at_console, "%d %.0f\n", ptr->iHitgroup, flDamage );

	// HITGROUPS don't work currently.
	// ignore blades
//	if (ptr->hitgroup == 6 && (info.GetDamageType() & (DMG_ENERGYBEAM|DMG_BULLET|DMG_CLUB)))
//		return;

	// hit hard, hits cockpit
	if (info.GetDamage() > 50 || ptr->hitgroup == 11 )
	{
		// ALERT( at_console, "%map .0f\n", flDamage );
		AddMultiDamage( dmgInfo, this );
//		m_iDoSmokePuff = 3 + (info.GetDamage() / 5.0);
	}
	else
	{
		// do half damage in the body
		dmgInfo.ScaleDamage(0.5);
		AddMultiDamage( dmgInfo, this );
		g_pEffects->Ricochet( ptr->endpos, ptr->plane.normal );
	}

}

//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBaseHelicopter::NullThink( void )
{
	StudioFrameAdvance( );
	SetNextThink( gpGlobals->curtime + 0.5f );
}


void CBaseHelicopter::Startup( void )
{
	m_flGoalSpeed = m_flInitialSpeed;
	SetThink( HelicopterThink );
	SetTouch( FlyTouch );
	SetNextThink( gpGlobals->curtime + 0.1f );
}


void CBaseHelicopter::Event_Killed( const CTakeDamageInfo &info )
{
	m_lifeState			= LIFE_DYING;

	SetMoveType( MOVETYPE_FLYGRAVITY );
	SetGravity( 0.3 );

	// Kill the rotor sound.

	UTIL_SetSize( this, Vector( -32, -32, -64), Vector( 32, 32, 0) );
	SetThink( CallDyingThink );
	SetTouch( CrashTouch );

	SetNextThink( gpGlobals->curtime + 0.1f );
	m_iHealth = 0;
	m_takedamage = DAMAGE_NO;

/*
	if (m_spawnflags & SF_NOWRECKAGE)
	{
		m_flNextRocket = gpGlobals->curtime + 4.0;
	}
	else
	{
		m_flNextRocket = gpGlobals->curtime + 15.0;
	}
*/	
	m_OnDeath.FireOutput( info.GetAttacker(), this );
}


void CBaseHelicopter::StopLoopingSounds()
{
	CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
	controller.SoundDestroy( m_pRotorSound );
	m_pRotorSound = NULL;

	BaseClass::StopLoopingSounds();
}

void CBaseHelicopter::GibMonster( void )
{
}


void CBaseHelicopter::ChangePathCorner( const char *pszName )
{
	if( m_lifeState != LIFE_ALIVE )
	{
		// Disregard this if dead or dying.
		return;
	}

	if (m_pGoalEnt)
	{
		m_pGoalEnt = gEntList.FindEntityByName( NULL, pszName, this );

		// I don't think we need to do this. The FLIGHT() code will do it for us (sjb)
		if (m_pGoalEnt)
		{
			m_vecDesiredPosition = m_pGoalEnt->GetLocalOrigin();
			AngleVectors( m_pGoalEnt->GetLocalAngles(), &m_vecGoalOrientation );
		}
	}
}


//-----------------------------------------------------------------------------
// Purpose: Slams the chopper's current path corner and sends it to a new one.
//          This code does NOT check that the path from the current position
//			to the wished path corner is clear!
//-----------------------------------------------------------------------------
void CBaseHelicopter::InputChangePathCorner( inputdata_t &inputdata )
{
	ChangePathCorner( inputdata.value.String() );
}


//-----------------------------------------------------------------------------
// Purpose: Call Startup for a helicopter that's been flagged to start disabled
//-----------------------------------------------------------------------------
void CBaseHelicopter::InputActivate( inputdata_t &inputdata )
{
	if( m_spawnflags & SF_AWAITINPUT )
	{
		Startup();

		// Now clear the spawnflag to protect from
		// subsequent calls.
		m_spawnflags &= ~SF_AWAITINPUT;
	}
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------

void CBaseHelicopter::ApplySidewaysDrag( const Vector &vecRight )
{
	Vector vecNewVelocity = GetAbsVelocity();
	vecNewVelocity.x *= 1.0 - fabs( vecRight.x ) * 0.05;
	vecNewVelocity.y *= 1.0 - fabs( vecRight.y ) * 0.05;
	vecNewVelocity.z *= 1.0 - fabs( vecRight.z ) * 0.05;
	SetAbsVelocity( vecNewVelocity );
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------
void CBaseHelicopter::ApplyGeneralDrag( void )
{
	Vector vecNewVelocity = GetAbsVelocity();
	vecNewVelocity *= 0.995;
	SetAbsVelocity( vecNewVelocity );
}
	

//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------
bool CBaseHelicopter::ChooseEnemy( void )
{
	// See if there's a new enemy.
	CBaseEntity *pNewEnemy;

	pNewEnemy = BestEnemy();

	if( ( pNewEnemy != GetEnemy() ) && pNewEnemy != NULL )
	{
		//New enemy! Clear the timers and set conditions.
 		SetCondition(COND_NEW_ENEMY);
		SetEnemy( pNewEnemy );
		m_flLastSeen = m_flPrevSeen = gpGlobals->curtime;
		return true;
	}
	else
	{
		ClearCondition( COND_NEW_ENEMY );
		return false;
	}
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  :
// Output : 
//-----------------------------------------------------------------------------
void CBaseHelicopter::CheckEnemy( CBaseEntity *pEnemy )
{
	// -------------------
	// If enemy is dead
	// -------------------
	if ( !pEnemy->IsAlive() )
	{
		SetCondition( COND_ENEMY_DEAD );
		ClearCondition( COND_SEE_ENEMY );
		ClearCondition( COND_ENEMY_OCCLUDED );
		return;
	}
}

⌨️ 快捷键说明

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