//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponShieldGrenade::PrimaryAttack( void ) { CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>( GetOwner() ); if ( !pPlayer ) return; if ( !ComputeEMPFireState() ) return; if ( !GetPrimaryAmmo() ) return; // player "shoot" animation PlayAttackAnimation( ACT_VM_THROW ); ThrowGrenade(); // Setup for refire m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; CheckRemoveDisguise(); // If I'm now out of ammo, switch away if ( !HasPrimaryAmmo() ) { g_pGameRules->GetNextBestWeapon( pPlayer, NULL ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatPlasmaGrenadeLauncher::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); if (!pPlayer) return; WeaponSound(SINGLE); // Fire the bullets Vector vecSrc = pPlayer->Weapon_ShootPosition( ); PlayAttackAnimation( GetPrimaryAttackActivity() ); // Launch the grenade Vector vecForward; pPlayer->EyeVectors( &vecForward ); Vector vecOrigin = pPlayer->EyePosition(); vecOrigin += (vecForward); #if !defined( CLIENT_DLL ) float flSpeed = 1200; CGrenadeAntiPersonnel* pGrenade = CGrenadeAntiPersonnel::Create(vecOrigin, vecForward * flSpeed, pPlayer ); pGrenade->SetModel( "models/weapons/w_grenade.mdl" ); pGrenade->SetBounceSound( "PlasmaGrenade.Bounce" ); pGrenade->SetDamage( weapon_combat_plasmagrenadelauncher_damage.GetFloat() ); pGrenade->SetDamageRadius( weapon_combat_plasmagrenadelauncher_radius.GetFloat() ); pGrenade->SetExplodeOnContact( true ); #endif m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_iClip1 = m_iClip1 - 1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatLaserRifle::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); if (!pPlayer) return; WeaponSound(SINGLE); // Fire the bullets Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming; pPlayer->EyeVectors( &vecAiming ); PlayAttackAnimation( GetPrimaryAttackActivity() ); // Reduce the spread if the player's ducking Vector vecSpread = GetBulletSpread(); vecSpread *= m_flInaccuracy; TFGameRules()->FireBullets( CTakeDamageInfo( this, pPlayer, weapon_combat_laserrifle_damage.GetFloat(), DMG_PLASMA), 1, vecSrc, vecAiming, vecSpread, weapon_combat_laserrifle_range.GetFloat(), m_iPrimaryAmmoType, 0, entindex(), 0 ); m_flInaccuracy += 0.3; m_flInaccuracy = clamp(m_flInaccuracy, 0, 1); m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_iClip1 = m_iClip1 - 1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHarpoon::ItemPostFrame( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if (!pOwner) return; // Look for button downs if ( (pOwner->m_afButtonPressed & IN_ATTACK) && !m_flStartedThrowAt && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { // If we don't have a harpoon, throw one out. Otherwise, yank it back. if ( m_bActiveHarpoon ) { YankHarpoon(); } else { m_bActiveHarpoon = true; m_flStartedThrowAt = gpGlobals->curtime; PlayAttackAnimation( ACT_VM_PULLBACK ); m_flCantThrowUntil = gpGlobals->curtime + SequenceDuration(); } } else if ( m_flCantThrowUntil && m_bActiveHarpoon && !(pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) && (m_flCantThrowUntil <= gpGlobals->curtime) ) { m_flNextPrimaryAttack = gpGlobals->curtime; PrimaryAttack(); m_flStartedThrowAt = 0; m_flCantThrowUntil = 0; } else if ( (pOwner->m_nButtons & IN_ATTACK2) && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { PlayAttackAnimation( ACT_VM_SECONDARYATTACK ); m_flSecondaryAttackAt = gpGlobals->curtime + SequenceDuration() * 0.3; m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); } else if ( m_flSecondaryAttackAt && m_flSecondaryAttackAt < gpGlobals->curtime ) { SecondaryAttack(); m_flSecondaryAttackAt = 0; } // No buttons down? if ( !((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)) ) { WeaponIdle( ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHarpoon::ThrowGrenade( void ) { CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>( GetOwner() ); if ( !pPlayer ) return; BaseClass::WeaponSound(WPN_DOUBLE); // Calculate launch velocity (3 seconds for max distance) float flThrowTime = min( (gpGlobals->curtime - m_flStartedThrowAt), 3.0 ); float flSpeed = 1000 + (200 * flThrowTime); PlayAttackAnimation( ACT_VM_PRIMARYATTACK ); // If the player's crouched, roll the grenade if ( pPlayer->GetFlags() & FL_DUCKING ) { // Launch the grenade Vector vecForward; QAngle vecAngles = pPlayer->EyeAngles(); // Throw it up just a tad vecAngles.x = -1; AngleVectors( vecAngles, &vecForward, NULL, NULL); Vector vecOrigin; VectorLerp( pPlayer->EyePosition(), pPlayer->GetAbsOrigin(), 0.25f, vecOrigin ); vecOrigin += (vecForward * 16); vecForward = vecForward * flSpeed; CreateHarpoon(vecOrigin, vecForward, pPlayer ); } else { // Launch the grenade Vector vecForward; QAngle vecAngles = pPlayer->EyeAngles(); AngleVectors( vecAngles, &vecForward, NULL, NULL); Vector vecOrigin = pPlayer->EyePosition(); vecOrigin += (vecForward * 16); vecForward = vecForward * flSpeed; CreateHarpoon(vecOrigin, vecForward, pPlayer ); } pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); }
//----------------------------------------------------------------------------- // Purpose: Firing //----------------------------------------------------------------------------- void CWeaponRocketLauncher::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = ( CBaseTFPlayer* )GetOwner(); if ( !pPlayer ) return; if ( !ComputeEMPFireState() ) return; // Weapon "Fire" sound. WeaponSound( SINGLE ); // Play the attack animation (need one for rocket launcher - deploy?) PlayAttackAnimation( GetPrimaryAttackActivity() ); // Fire the rocket (Get the position and angles). Vector vecFirePos = pPlayer->Weapon_ShootPosition(); Vector vecFireAng; pPlayer->EyeVectors( &vecFireAng ); // Shift it down a bit so the firer can see it Vector vecRight; AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &vecRight, NULL ); vecFirePos += Vector( 0, 0, -8 ) + vecRight * 12; // Create the rocket. #if !defined( CLIENT_DLL ) CWeaponGrenadeRocket *pRocket = CWeaponGrenadeRocket::Create( vecFirePos, vecFireAng, weapon_rocket_launcher_range.GetFloat(), pPlayer ); #else CWeaponGrenadeRocket *pRocket = CWeaponGrenadeRocket::Create( vecFirePos, vecFireAng, 0, pPlayer ); #endif if ( pRocket ) { pRocket->SetRealOwner( pPlayer ); #if !defined( CLIENT_DLL ) pRocket->SetDamage( weapon_rocket_launcher_damage.GetFloat() ); #endif } // Essentially you are done! m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_iClip1 = m_iClip1 - 1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombat_ChargeablePlasma::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); if (!pPlayer) return; WeaponSound(SINGLE); // Fire the bullets Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming; pPlayer->EyeVectors( &vecAiming ); // If we already have a lock target from button down, see if we shouldn't try and get a new one // Only do this is the button was released immediately if ( !m_hLockTarget || ( m_flLockedAt < gpGlobals->curtime ) ) { m_hLockTarget = GetLockTarget(); } PlayAttackAnimation( GetPrimaryAttackActivity() ); // Shift it down a bit so the firer can see it Vector right; AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL ); Vector vecStartSpot = vecSrc + Vector(0,0,-8) + right * 12; CGuidedPlasma *pShot = CGuidedPlasma::Create(vecStartSpot, vecAiming, m_hLockTarget, m_vecTargetOffset, pPlayer); // Set it's charged power level if (m_bHasCharge) m_flPower = min( MAX_CHARGED_TIME, gpGlobals->curtime - m_flChargeStartTime ); else m_flPower = 0.0f; float flDamageMult = RemapVal( m_flPower, 0, MAX_CHARGED_TIME, 1.0, MAX_CHARGED_POWER ); pShot->SetPowerLevel( flDamageMult ); m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_iClip1 = m_iClip1 - 1; m_hLockTarget = NULL; }
//----------------------------------------------------------------------------- // Purpose: Give the harpoon a yank //----------------------------------------------------------------------------- void CWeaponHarpoon::YankHarpoon( void ) { CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>( GetOwner() ); if ( !pPlayer ) return; #if !defined( CLIENT_DLL ) if ( m_bActiveHarpoon && m_hHarpoon.Get() ) { // If the harpoon's impaled something, pull it towards me CBaseEntity *pTarget = m_hHarpoon->GetImpaledTarget(); if ( pTarget ) { if ( !pTarget->IsBSPModel() && pTarget->GetMoveType() != MOVETYPE_NONE ) { // Bring him to me! EmitSound( "Harpoon.Yank" ); // Get a yank vector, and raise it a little to get them off the ground if they're on it Vector vecOverHere = ( pPlayer->GetAbsOrigin() - pTarget->GetAbsOrigin() ); VectorNormalize( vecOverHere ); if ( pTarget->GetFlags() & FL_ONGROUND ) { pTarget->SetGroundEntity( NULL ); vecOverHere.z = 0.5; } pTarget->ApplyAbsVelocityImpulse( vecOverHere * 500 ); PlayAttackAnimation( ACT_VM_HAULBACK ); } } m_hHarpoon->SetThink( SUB_Remove ); m_hHarpoon->SetNextThink( gpGlobals->curtime + 5.0 ); m_hHarpoon = NULL; m_bActiveHarpoon = false; } DetachRope(); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatBaseGrenade::PrimaryAttack( void ) { CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>( GetOwner() ); if ( !pPlayer ) return; if ( !ComputeEMPFireState() ) return; // player "shoot" animation PlayAttackAnimation( ACT_VM_THROW ); ThrowGrenade(); // Setup for refire m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; CheckRemoveDisguise(); // If I'm now out of ammo, switch away if ( !HasPrimaryAmmo() ) { pPlayer->SelectLastItem(); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponLaserRifle::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = ToBaseTFPlayer( m_hOwner ); if ( !pPlayer ) return; if ( !ComputeEMPFireState() ) return; WeaponSound(SINGLE); PlayAttackAnimation( GetPrimaryAttackActivity() ); pPlayer->m_fEffects |= EF_MUZZLEFLASH; // Fire the beam: BLOW OFF AUTOAIM Vector vecSrc = pPlayer->Weapon_ShootPosition( pPlayer->GetOrigin() ); Vector vecAiming, right, up; pPlayer->EyeVectors( &vecAiming, &right, &up); Vector vecSpread = VECTOR_CONE_4DEGREES; // Get endpoint float x, y, z; do { x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); z = x*x+y*y; } while (z > 1); Vector vecDir = vecAiming + x * vecSpread.x * right + y * vecSpread.y * up; Vector vecEnd = vecSrc + vecDir * weapon_laserrifle_range.GetFloat(); trace_t tr; float damagefactor = TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, pPlayer, DMG_ENERGYBEAM, &tr); // Hit target? if (tr.fraction != 1.0) { CBaseEntity *pEntity = CBaseEntity::Instance(tr.u.ent); if ( pEntity ) { ClearMultiDamage(); float flDamage = GetDamage( (tr.endpos - vecSrc).Length(), tr.hitgroup ); flDamage *= damagefactor; pEntity->TraceAttack( CTakeDamageInfo( pPlayer, pPlayer, flDamage, DMG_ENERGYBEAM ), vecDir, &tr ); ApplyMultiDamage( pPlayer, pPlayer ); } g_pEffects->EnergySplash( tr.endpos, tr.plane.normal ); } // Get hacked gun position AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL ); Vector vecTracerSrc = vecSrc + Vector (0,0,-8) + right * 12 + vecDir * 16; // Laser beam CBroadcastRecipientFilter filter; te->BeamPoints( filter, 0.0, &vecTracerSrc, &tr.endpos, m_iSpriteTexture, 0, // Halo index 0, // Start frame 0, // Frame rate 0.2, // Life 15, // Width 15, // EndWidth 0, // FadeLength 0, // Amplitude 200, // r 200, // g 255, // b 255, // a 255 ); // speed pPlayer->m_iAmmo[m_iPrimaryAmmoType]--; m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); CheckRemoveDisguise(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatBurstRifle::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); if (!pPlayer) return; WeaponSound(SINGLE); // Fire the bullets Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecSpread = GetBulletSpread(); Vector vecAiming, vecRight, vecUp; pPlayer->EyeVectors( &vecAiming, &vecRight, &vecUp ); // Add some inaccuracy int seed = 0; float x, y, z; do { float x1, x2, y1, y2; // Note the additional seed because otherwise we get the same set of random #'s and will get stuck // in an infinite loop here potentially // FIXME: Can we use a gaussian random # function instead? ywb x1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed ); x2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed ); y1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed ); y2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed ); x = x1 + x2; y = y1 + y2; z = x*x+y*y; } while (z > 1); Vector vecDir = vecAiming + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp; PlayAttackAnimation( GetPrimaryAttackActivity() ); // Shift it down a bit so the firer can see it Vector right, forward; AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, &forward, &right, NULL ); Vector vecStartSpot = vecSrc; // Get the firing position #ifdef CLIENT_DLL // On our client, grab the viewmodel's firing position Vector vecWorldOffset = vecStartSpot + Vector(0,0,-8) + right * 12 + forward * 16; #else // For everyone else, grab the weapon model's position /* Vector vecWorldOffset; QAngle angIgnore; GetAttachment( LookupAttachment( "muzzle" ), vecWorldOffset, angIgnore ); */ Vector vecWorldOffset = vecStartSpot + Vector(0,0,-8) + right * 12 + forward * 16; #endif Vector gunOffset = vecWorldOffset - vecStartSpot; CPowerPlasmaProjectile *pPlasma = CPowerPlasmaProjectile::CreatePredicted( vecStartSpot, vecDir, gunOffset, DMG_ENERGYBEAM, pPlayer ); if ( pPlasma ) { pPlasma->SetDamage( weapon_combat_burstrifle_damage.GetFloat() ); pPlasma->m_hOwner = pPlayer; pPlasma->SetPower( 2.0 ); pPlasma->SetMaxRange( weapon_combat_burstrifle_range.GetFloat() ); pPlasma->Activate(); } m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_iClip1 = m_iClip1 - 1; }