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

📄 weapon_brickbat.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Output :
//-----------------------------------------------------------------------------
int CWeaponBrickbat::WeaponRangeAttack1Condition( float flDot, float flDist )
{
	// If things haven't changed too much since last time
	// just return that previously calculated value
	if (gpGlobals->curtime < m_fNextThrowCheck )
	{
		return m_iThrowBits;
	}
	
	if ( flDist < m_fMinRange1) 
	{
		m_iThrowBits = COND_TOO_CLOSE_TO_ATTACK;
	}
	else if (flDist > m_fMaxRange1) 
	{
		m_iThrowBits = COND_TOO_FAR_TO_ATTACK;
	}
	else if (flDot < 0.5) 
	{
		m_iThrowBits = COND_NOT_FACING_ATTACK;
	}

	// If moving, can't throw.
	else if ( m_flGroundSpeed != 0 )
	{
		m_iThrowBits = COND_NONE;
	}
	else 
	{
		// Ok we should check again as some time has passed
		// This function is only used by NPC's so we can cast to a Base Monster
		CAI_BaseNPC *pNPC	= GetOwner()->MyNPCPointer();
		CBaseEntity *pEnemy = pNPC->GetEnemy();

		if (!pEnemy)
		{
			return COND_NONE;
		}

		// Get Enemy Position 
		Vector vecTarget = Vector( pEnemy->GetAbsOrigin().x, 
									pEnemy->GetAbsOrigin().y, 
									pEnemy->GetAbsMins().z );

		// Get Toss Vector
		Vector			throwStart  = pNPC->Weapon_ShootPosition();
		Vector			vecToss;
		CBaseEntity*	pBlocker	= NULL;
		float			throwDist	= (throwStart - vecTarget).Length();
		float			fGravity	= sv_gravity.GetFloat(); 
		float			throwLimit	= pNPC->ThrowLimit(throwStart, vecTarget, fGravity, 35, WorldAlignMins(), WorldAlignMaxs(), pEnemy, &vecToss, &pBlocker);

		// If I can make the throw (or most of the throw)
		if (!throwLimit || (throwLimit != throwDist && throwLimit > 0.8*throwDist))
		{
			m_vecTossVelocity = vecToss;
			m_iThrowBits = COND_CAN_RANGE_ATTACK1;

		}
		else
		{
			m_iThrowBits = COND_NONE;
		}

	}
	// don't check again for a while.
	m_fNextThrowCheck = gpGlobals->curtime + 0.33; // 1/3 second.

	return m_iThrowBits;
}

//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CWeaponBrickbat::ThrowBrickbat( Vector vecSrc, Vector vecVelocity, float damage)
{
	CGrenade_Brickbat *pBrickbat = (CGrenade_Brickbat*)Create( BrickBatAmmoArray[m_iCurrentAmmoType].m_sClassName, vecSrc, vec3_angle, GetOwner() );

	if (!pBrickbat)
	{
		Msg("Brickbat type (%s) not defined!\n",BrickBatAmmoArray[m_iCurrentAmmoType].m_sClassName);
		return;
	}

	AngularImpulse vecAngVel;
	// Tumble through the air
	vecAngVel.x = random->RandomFloat ( -100, -500 );
	vecAngVel.z = random->RandomFloat ( -100, -500 );
	vecAngVel.y = random->RandomFloat ( -100, -500 );

	// If physically simulated
	IPhysicsObject *pPhysicsObject = pBrickbat->VPhysicsGetObject();
	if ( pPhysicsObject )
	{
		pPhysicsObject->AddVelocity( &vecVelocity, &vecAngVel );
	}
	// Otherwise
	else
	{
		pBrickbat->SetAbsVelocity( vecVelocity );

		QAngle angVel;
		AngularImpulseToQAngle( vecAngVel, angVel );
		pBrickbat->SetLocalAngularVelocity( angVel );
	}

	pBrickbat->SetOwner( GetOwner() );
	pBrickbat->SetOwnerEntity( ((CBaseEntity*)GetOwner()) );
	pBrickbat->SetDamage(damage);

	m_nAmmoCount[m_iCurrentAmmoType]--;

	m_bNeedThrow = false;
}

//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CWeaponBrickbat::PrimaryAttack( void )
{

	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if (!pPlayer)
	{
		return;
	}

	SendWeaponAnim(ACT_VM_PULLBACK);
	
	// Don't fire again until fire animation has completed
	float flSequenceEndTime = gpGlobals->curtime + SequenceDuration();
	pPlayer->m_flNextAttack = m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSequenceEndTime;

	m_bNeedThrow = true;
}

//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CWeaponBrickbat::Throw( void )
{

	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if (!pPlayer)
	{
		return;
	}

	Vector vecSrc		= pPlayer->WorldSpaceCenter();
	Vector vecFacing	= pPlayer->BodyDirection3D( );
	vecSrc				= vecSrc + vecFacing * 18.0;
	vecSrc.z		   += 24.0f;

	// Player may have turned to face a wall during the throw anim in which case
	// we don't want to throw the SLAM into the wall
	if (ObjectInWay())
	{
		vecSrc = pPlayer->WorldSpaceCenter() + vecFacing * 5.0;
	}

	Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	vecAiming.z += 0.20; // Raise up so passes through reticle

	ThrowBrickbat(vecSrc, vecAiming*800, sk_plr_dmg_brickbat.GetFloat());
	pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );

	SendWeaponAnim(ACT_VM_THROW);
	
	// Don't fire again until fire animation has completed
	float flSequenceEndTime = gpGlobals->curtime + SequenceDuration();
	pPlayer->m_flNextAttack = m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSequenceEndTime;

	m_bNeedThrow = false;
	m_bNeedDraw	 = true;
}
//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CWeaponBrickbat::SecondaryAttack( void )
{
	int counter = 0;
	while (counter < NUM_BRICKBAT_AMMO_TYPES)
	{
		m_iCurrentAmmoType = ((++m_iCurrentAmmoType)%NUM_BRICKBAT_AMMO_TYPES);

		// If I've found a category with ammo stop looking
		if (m_nAmmoCount[m_iCurrentAmmoType] > 0)
		{
			DrawAmmo();
			return;
		}
		counter++;
	}
	// I'm out of all ammo types
}

//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CWeaponBrickbat::DrawAmmo( void )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	// -------------------------------------------
	// Make sure I have ammo of the current type
	// -------------------------------------------
	int counter = 0;
	while (m_nAmmoCount[m_iCurrentAmmoType] <=0)
	{
		m_iCurrentAmmoType = ((++m_iCurrentAmmoType)%NUM_BRICKBAT_AMMO_TYPES);
		counter++;

		// ----------------------------------------------------
		// No ammo of any types so drop the weapon and destroy
		// ----------------------------------------------------
		if (counter >= NUM_BRICKBAT_AMMO_TYPES)
		{
			pOwner->Weapon_Drop( this, NULL, NULL );
			UTIL_Remove(this);
			return;
		}
	}
	SetModel( BrickBatAmmoArray[m_iCurrentAmmoType].m_sViewModel);
	CBaseViewModel *vm = pOwner->GetViewModel();
	if ( vm )
	{
		vm->SetModel( BrickBatAmmoArray[m_iCurrentAmmoType].m_sViewModel );
	}

	//Msg("Drawing %s...\n",BrickBatAmmoArray[m_iCurrentAmmoType].m_sClassName);
	m_bNeedDraw = false;

	SendWeaponAnim(ACT_VM_DRAW);

	// Don't fire again until fire animation has completed
	float flSequenceEndTime = gpGlobals->curtime + SequenceDuration();
	pOwner->m_flNextAttack = m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSequenceEndTime;
}

//-----------------------------------------------------------------------------
// Purpose: Override so shotgun can do mulitple reloads in a row
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CWeaponBrickbat::ItemPostFrame( void )
{
	/*  HANDY FOR DEBUG
	for (int i=0;i<NUM_BRICKBAT_AMMO_TYPES;i++)
	{
		Msg("%i %s",m_nAmmoCount[i],BrickBatAmmoArray[i].m_sClassName);
		if (i==m_iCurrentAmmoType)
		{
			Msg("**");
		}
		Msg("\n");
	}
	*/

	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if (!pOwner)
	{
		return;
	}

	if (m_bNeedThrow)
	{
		Throw();
	}
	else if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
	{
		SecondaryAttack();
	}
	else if ((pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
	{
		// Uses secondary ammo only
		if (pOwner->GetAmmoCount(m_iPrimaryAmmoType))
		{
			PrimaryAttack();
		}
	}
	else if (m_bNeedDraw)
	{
		DrawAmmo();
	}
	else
	{
		SendWeaponAnim( ACT_VM_IDLE );
		//pOwner->m_flNextAttack = gpGlobals->curtime + SequenceDuration();
	}
}

//-----------------------------------------------------------------------------
// Purpose:
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CWeaponBrickbat::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
	if ( info.GetDamageType() & DMG_BULLET)
	{
		if (BrickBatAmmoArray[m_iCurrentAmmoType].m_nAmmoType == BRICKBAT_CREMATORHEAD ||
			BrickBatAmmoArray[m_iCurrentAmmoType].m_nAmmoType == BRICKBAT_ROCK			)
		{
			g_pEffects->Ricochet(ptr->endpos,ptr->plane.normal);
		}	
	}
	BaseClass::TraceAttack( info, vecDir, ptr );
}

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponBrickbat::CWeaponBrickbat( void )
{
#ifdef _DEBUG
	m_vecTossVelocity.Init();
#endif

	m_fMinRange1	= 200;
	m_fMaxRange1	= 1000;
}

⌨️ 快捷键说明

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