//----------------------------------------------------------------------------- // 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 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; }
void CWeaponStickyLauncher::PrimaryAttack( void ) { // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); WeaponSound(SINGLE); pPlayer->m_fEffects |= EF_MUZZLEFLASH; SendWeaponAnim( GetPrimaryAttackActivity() ); // player "shoot" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); m_iClip1 = m_iClip1 - 1; LaunchStickyBomb( pPlayer, vecSrc, vecAiming ); AddViewKick(); }
void CASW_Weapon_Stim::InjectStim() { CASW_Marine *pMarine = GetMarine(); if (pMarine) // firing from a marine { //make the proper weapon sound WeaponSound(SINGLE); #ifndef CLIENT_DLL bool bThisActive = (pMarine->GetActiveASWWeapon() == this); #endif // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifndef CLIENT_DLL // make it cause the slow time float fDuration = MarineSkills()->GetBestSkillValue( ASW_MARINE_SKILL_DRUGS ); if (fDuration < 0) fDuration = asw_stim_duration.GetFloat(); //CALL_ATTRIB_HOOK_FLOAT( fDuration, mod_duration ); ASWGameRules()->StartStim( fDuration, pMarine->GetCommander() ); pMarine->OnWeaponFired( this, 1 ); #endif // decrement ammo m_iClip1 -= 1; m_flNextPrimaryAttack = gpGlobals->curtime + 4.0f; if (!m_iClip1 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { // stim weapon is lost when all stims are gone #ifndef CLIENT_DLL if (pMarine) { pMarine->Weapon_Detach(this); if (bThisActive) pMarine->SwitchToNextBestWeapon(NULL); } Kill(); #endif } } }
//----------------------------------------------------------------------------- // Purpose: Tells us we're always a translucent entity //----------------------------------------------------------------------------- bool C_WeaponStunStick::InSwing( void ) { int activity = GetActivity(); // FIXME: This is needed until the actual animation works if ( ShouldDrawUsingViewModel() == false ) return true; // These are the swing activities this weapon can play if ( activity == GetPrimaryAttackActivity() || activity == GetSecondaryAttackActivity() || activity == ACT_VM_MISSCENTER || activity == ACT_VM_MISSCENTER2 ) return true; return false; }
//----------------------------------------------------------------------------- // Purpose: Tells us we're always a translucent entity //----------------------------------------------------------------------------- bool C_WeaponStunStick::InSwing( void ) { int activity = GetActivity(); // FIXME: This is needed until the actual animation works if ( IsCarriedByLocalPlayer() == false || ::input->CAM_IsThirdPerson()) return true; // These are the swing activities this weapon can play if ( activity == GetPrimaryAttackActivity() || activity == GetSecondaryAttackActivity() || activity == ACT_VM_MISSCENTER || activity == ACT_VM_MISSCENTER2 ) return true; return false; }
//----------------------------------------------------------------------------- // 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: Prepare the launcher to fire //----------------------------------------------------------------------------- void CGEWeaponRocketLauncher::PrimaryAttack( void ) { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; // If my clip is empty (and I use clips) start reload if ( UsesClipsForAmmo1() && !m_iClip1 ) { Reload(); return; } // Bring us back to center view pPlayer->ViewPunchReset(); // Note that this is a primary attack and prepare the grenade attack to pause. m_bPreLaunch = true; SendWeaponAnim( GetPrimaryAttackActivity() ); ToGEPlayer(pPlayer)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); m_flRocketSpawnTime = gpGlobals->curtime + GetFireDelay(); m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); }
void CASW_Weapon_T75::PrimaryAttack( void ) { // Only the player fires this way so we can cast CASW_Player *pPlayer = GetCommander(); if (!pPlayer) return; CASW_Marine *pMarine = GetMarine(); #ifndef CLIENT_DLL bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this); #endif // weapon is lost when all charges are gone if ( UsesClipsForAmmo1() && !m_iClip1 ) { //Reload(); #ifndef CLIENT_DLL if (pMarine) { pMarine->Weapon_Detach(this); if (bThisActive) pMarine->SwitchToNextBestWeapon(NULL); } Kill(); #endif return; } if ( !pMarine || pMarine->GetWaterLevel() == 3 ) // firing from a marine return; // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); #ifndef CLIENT_DLL Vector vecSrc = pMarine->Weapon_ShootPosition( ); // TODO: Fix for AI Vector vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f ) { vecSrc.x = pMarine->m_vecOffhandItemSpot.x; vecSrc.y = pMarine->m_vecOffhandItemSpot.y; vecSrc.z += 50.0f; } QAngle ang = pPlayer->EyeAngles(); ang.x = 0; ang.z = 0; CShotManipulator Manipulator( vecAiming ); AngularImpulse rotSpeed(0,0,720); Vector newVel = Manipulator.ApplySpread(GetBulletSpread()); newVel *= ASW_MINE_VELOCITY; if ( !pMarine->IsInhabited() ) { newVel = vec3_origin; } CASW_T75 *pT75 = CASW_T75::ASW_T75_Create( vecSrc, ang, newVel, rotSpeed, pMarine, this ); if ( pT75 && !pMarine->IsInhabited() ) { pT75->ActivateUseIcon( pMarine, ASW_USE_RELEASE_QUICK ); } //pMarine->GetMarineSpeech()->Chatter(CHATTER_MINE_DEPLOYED); #endif // decrement ammo m_iClip1 -= 1; #ifndef CLIENT_DLL DestroyIfEmpty( true ); #endif m_flSoonestPrimaryAttack = gpGlobals->curtime + ASW_FLARES_FASTEST_REFIRE_TIME; if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; }
void CASW_Weapon_Shotgun::PrimaryAttack( void ) { // If my clip is empty (and I use clips) start reload if ( UsesClipsForAmmo1() && !m_iClip1 ) { Reload(); return; } CASW_Player *pPlayer = GetCommander(); CASW_Marine *pMarine = GetMarine(); if (pMarine) // firing from a marine { // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); if (m_iClip1 <= AmmoClickPoint()) { LowAmmoSound(); } m_bIsFiring = true; // tell the marine to tell its weapon to draw the muzzle flash pMarine->DoMuzzleFlash(); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); #ifdef GAME_DLL // check for turning on lag compensation if (pPlayer && pMarine->IsInhabited()) { CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() ); } #endif Vector vecSrc = pMarine->Weapon_ShootPosition( ); // hull trace out to this shoot position, so we can be sure we're not firing from over an alien's head trace_t tr; CTraceFilterSimple tracefilter(pMarine, COLLISION_GROUP_NONE); Vector vecMarineMiddle(pMarine->GetAbsOrigin()); vecMarineMiddle.z = vecSrc.z; AI_TraceHull( vecMarineMiddle, vecSrc, Vector( -10, -10, -20 ), Vector( 10, 10, 10 ), MASK_SHOT, &tracefilter, &tr ); vecSrc = tr.endpos; Vector vecAiming = vec3_origin; if ( pPlayer && pMarine->IsInhabited() ) { vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 } else { #ifndef CLIENT_DLL vecAiming = pMarine->GetActualShootTrajectory( vecSrc ); #endif } if (true) // hitscan pellets { #ifndef CLIENT_DLL if (asw_DebugAutoAim.GetBool()) { NDebugOverlay::Line(vecSrc, vecSrc + vecAiming * asw_weapon_max_shooting_distance.GetFloat(), 64, 0, 64, false, 120.0); } #endif int iPellets = GetNumPellets(); for (int i=0;i<iPellets;i++) { FireBulletsInfo_t info( 1, vecSrc, vecAiming, GetAngularBulletSpread(), asw_weapon_max_shooting_distance.GetFloat(), m_iPrimaryAmmoType ); info.m_pAttacker = pMarine; info.m_iTracerFreq = 1; info.m_nFlags = FIRE_BULLETS_NO_PIERCING_SPARK | FIRE_BULLETS_HULL | FIRE_BULLETS_ANGULAR_SPREAD; info.m_flDamage = GetWeaponDamage(); info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat(); #ifndef CLIENT_DLL if (asw_debug_marine_damage.GetBool()) Msg("Weapon dmg = %f\n", info.m_flDamage); info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale(); #endif // shotgun bullets have a base 50% chance of piercing //float fPiercingChance = 0.5f; //if (pMarine->GetMarineResource() && pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->GetMarineClass() == MARINE_CLASS_SPECIAL_WEAPONS) //fPiercingChance += MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_PIERCING); //pMarine->FirePenetratingBullets(info, 5, fPiercingChance); //pMarine->FirePenetratingBullets(info, 5, 1.0f, i, false ); pMarine->FirePenetratingBullets(info, 0, 1.0f, i, false ); } } else // projectile pellets { #ifndef CLIENT_DLL CShotManipulator Manipulator( vecAiming ); int iPellets = GetNumPellets(); for (int i=0;i<iPellets;i++) { // create a pellet at some random spread direction //CASW_Shotgun_Pellet *pPellet = Vector newVel = Manipulator.ApplySpread(GetBulletSpread()); //Vector newVel = ApplySpread( vecAiming, GetBulletSpread() ); if ( pMarine->GetWaterLevel() == 3 ) newVel *= PELLET_WATER_VELOCITY; else newVel *= PELLET_AIR_VELOCITY; newVel *= (1.0 + (0.1 * random->RandomFloat(-1,1))); CreatePellet(vecSrc, newVel, pMarine); //CASW_Shotgun_Pellet_Predicted::CreatePellet(vecSrc, newVel, pPlayer, pMarine); } #endif } // increment shooting stats #ifndef CLIENT_DLL if (pMarine && pMarine->GetMarineResource()) { pMarine->GetMarineResource()->UsedWeapon(this, 1); pMarine->OnWeaponFired( this, GetNumPellets() ); } #endif // decrement ammo m_iClip1 -= 1; #ifdef GAME_DLL CASW_Marine *pMarine = GetMarine(); if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { // check he doesn't have ammo in an ammo bay CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(0)); if (!pAmmoBag) pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(1)); if (!pAmmoBag || !pAmmoBag->CanGiveAmmoToWeapon(this)) pMarine->OnWeaponOutOfAmmo(true); } #endif } if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; m_fSlowTime = gpGlobals->curtime + 0.1f; }
void CWeaponSMG1::PrimaryAttack( void ) { // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; // Abort here to handle burst and auto fire modes if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; m_nShotsFired++; pPlayer->DoMuzzleFlash(); // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. int iBulletsToFire = 0; float fireRate = GetFireRate(); while ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { // MUST call sound before removing a round from the clip of a CHLMachineGun WeaponSound(SINGLE, m_flNextPrimaryAttack); m_flNextPrimaryAttack = gpGlobals->curtime + fireRate; iBulletsToFire++; } // Make sure we don't fire more than the amount in the clip, if this weapon uses clips if ( UsesClipsForAmmo1() ) { if ( iBulletsToFire > m_iClip1 ) iBulletsToFire = m_iClip1; m_iClip1 -= iBulletsToFire; } CSDKPlayer *pSDKPlayer = ToSDKPlayer( pPlayer ); // Fire the bullets FireBulletsInfo_t info; info.m_iShots = iBulletsToFire; info.m_vecSrc = pSDKPlayer->Weapon_ShootPosition( ); info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); info.m_vecSpread = GetBulletSpread(); info.m_flDistance = MAX_TRACE_LENGTH; info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 2; info.m_iDamage = GetSDKWpnData().m_iDamage; pPlayer->FireBullets( info ); //Factor in the view kick AddViewKick(); if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { // HEV suit - indicate out of ammo condition pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); } SendWeaponAnim( GetPrimaryAttackActivity() ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); }
void CASW_Weapon_Assault_Shotgun::SecondaryAttack() { // Only the player fires this way so we can cast CASW_Player *pPlayer = GetCommander(); if (!pPlayer) return; CASW_Marine *pMarine = GetMarine(); if (!pMarine) return; //Must have ammo bool bUsesSecondary = UsesSecondaryAmmo(); bool bUsesClips = UsesClipsForAmmo2(); int iAmmoCount = pMarine->GetAmmoCount(m_iSecondaryAmmoType); bool bInWater = ( pMarine->GetWaterLevel() == 3 ); if ( (bUsesSecondary && ( ( bUsesClips && m_iClip2 <= 0) || ( !bUsesClips && iAmmoCount<=0 ) ) ) || bInWater || m_bInReload ) { SendWeaponAnim( ACT_VM_DRYFIRE ); BaseClass::WeaponSound( EMPTY ); m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f; return; } BaseClass::WeaponSound( SPECIAL1 ); #ifndef CLIENT_DLL pMarine->GetMarineSpeech()->Chatter(CHATTER_GRENADE); Vector vecSrc = pMarine->Weapon_ShootPosition(); Vector vecThrow; // check for turning on lag compensation if (pPlayer && pMarine->IsInhabited()) { CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() ); } vecThrow = UTIL_LaunchVector(vecSrc, pPlayer->GetCrosshairTracePos(), asw_vindicator_grenade_gravity.GetFloat()) * 8.0f * asw_vindicator_grenade_velocity.GetFloat(); QAngle angAiming = pPlayer->EyeAnglesWithCursorRoll(); float fGrenadeDamage = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_INCENDIARY_DMG); float fGrenadeRadius = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_RADIUS); if (asw_debug_marine_damage.GetBool()) { Msg("Grenade damage = %f radius = %f\n", fGrenadeDamage, fGrenadeRadius); } // check the grenade fits where we want to spawn it Ray_t ray; trace_t pm; ray.Init( pMarine->WorldSpaceCenter(), vecSrc, -Vector(4,4,4), Vector(4,4,4) ); UTIL_TraceRay( ray, MASK_SOLID, pMarine, COLLISION_GROUP_PROJECTILE, &pm ); if (pm.fraction < 1.0f) vecSrc = pm.endpos; CASW_Grenade_Vindicator::Vindicator_Grenade_Create( fGrenadeDamage, fGrenadeRadius, vecSrc, angAiming, vecThrow, AngularImpulse(0,0,0), pMarine, this ); pMarine->OnWeaponFired( this, 1, true ); #endif SendWeaponAnim( GetPrimaryAttackActivity() ); pMarine->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN_PRIMARY ); // Decrease ammo if ( bUsesClips ) { m_iClip2 -= 1; } else { pMarine->RemoveAmmo( 1, m_iSecondaryAmmoType ); } #ifndef CLIENT_DLL ASWFailAdvice()->OnMarineUsedSecondary(); CEffectData data; data.m_vOrigin = GetAbsOrigin(); //data.m_vNormal = dir; //data.m_flScale = (float)amount; CPASFilter filter( data.m_vOrigin ); filter.SetIgnorePredictionCull(true); DispatchParticleEffect( "muzzleflash_grenadelauncher_main", PATTACH_POINT_FOLLOW, this, "muzzle", false, -1, &filter ); #endif // Can shoot again immediately m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f; // Can blow up after a short delay (so have time to release mouse button) m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f; }
//----------------------------------------------------------------------------- // 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 CWarsWeapon::PrimaryAttack( void ) { VPROF_BUDGET( "CWarsWeapon::PrimaryAttack", VPROF_BUDGETGROUP_UNITS ); CUnitBase *pOwner = GetOwner() ? GetOwner()->MyUnitPointer() : NULL; if( !pOwner ) return; #ifndef CLIENT_DLL if( m_bEnableBurst ) { // Auto reset burst shots next time we fire if( m_nBurstShotsRemaining <= 0 ) { m_nBurstShotsRemaining = GetRandomBurst(); } } #endif // CLIENT_DLL pOwner->DoMuzzleFlash(); SendWeaponAnim( GetPrimaryAttackActivity() ); Vector vecShootOrigin, vecShootDir; GetShootOriginAndDirection(vecShootOrigin, vecShootDir); int shots = 0; // Assume still firing if gpGlobals.curtime-nextprimaryattack falss within this range // In the other case reset nextprimaryattack, so we only fire one shot if( (gpGlobals->curtime - m_flNextPrimaryAttack) > m_fFireTimeOut ) m_flNextPrimaryAttack = gpGlobals->curtime; //WeaponSound(SINGLE, m_flNextPrimaryAttack); while( m_flNextPrimaryAttack <= gpGlobals->curtime ) { #ifdef CLIENT_DLL // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE, m_flNextPrimaryAttack); #endif // CLIENT_DLL m_flNextPrimaryAttack = m_flNextPrimaryAttack + m_fFireRate; shots += 1; if( !m_fFireRate ) break; } // Fill in bullets info FireBulletsInfo_t info; info.m_vecSrc = vecShootOrigin; info.m_vecDirShooting = vecShootDir; info.m_iShots = shots; info.m_flDistance = m_fMaxBulletRange; info.m_iAmmoType = GetPrimaryAmmoType(); info.m_iTracerFreq = 2; info.m_vecSpread = m_vBulletSpread; info.m_flDamage = m_fOverrideAmmoDamage; pOwner->FireBullets( info ); #ifndef CLIENT_DLL if( m_bEnableBurst ) { m_nBurstShotsRemaining -= shots; // Dispatch burst finished event if we have no shots left // It's up to the AI to rest if( m_nBurstShotsRemaining <= 0 ) { pOwner->DispatchBurstFinished(); } } #endif // CLIENT_DLL // Add our view kick in AddViewKick(); }
void CASW_Weapon_Buff_Grenade::PrimaryAttack( void ) { // Only the player fires this way so we can cast CASW_Player *pPlayer = GetCommander(); if (!pPlayer) return; CASW_Marine *pMarine = GetMarine(); #ifndef CLIENT_DLL bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this); #endif // mine weapon is lost when all mines are gone if ( UsesClipsForAmmo1() && !m_iClip1 ) { //Reload(); #ifndef CLIENT_DLL if (pMarine) { pMarine->Weapon_Detach(this); if (bThisActive) pMarine->SwitchToNextBestWeapon(NULL); } Kill(); #endif return; } if ( !pMarine || pMarine->GetWaterLevel() == 3 ) return; // MUST call sound before removing a round from the clip of a CMachineGun //WeaponSound(SINGLE); // tell the marine to tell its weapon to draw the muzzle flash //pMarine->DoMuzzleFlash(); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); //pMarine->DoAnimationEvent(PLAYERANIMEVENT_HEAL); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifndef CLIENT_DLL Vector vecSrc = pMarine->Weapon_ShootPosition( ); Vector vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f ) { vecSrc.x = pMarine->m_vecOffhandItemSpot.x; vecSrc.y = pMarine->m_vecOffhandItemSpot.y; vecSrc.z += 50.0f; } QAngle ang = pPlayer->EyeAngles(); ang.x = 0; ang.z = 0; CShotManipulator Manipulator( vecAiming ); AngularImpulse rotSpeed(0,0,720); // create a pellet at some random spread direction Vector newVel = Manipulator.ApplySpread(GetBulletSpread()); newVel *= ASW_MINE_VELOCITY; if ( !pMarine->IsInhabited() ) { newVel = vec3_origin; } float flRadius = asw_damage_amp_radius.GetFloat(); float flDuration = asw_damage_amp_duration.GetFloat(); CASW_BuffGrenade_Projectile::Grenade_Projectile_Create( vecSrc, ang, newVel, rotSpeed, pMarine, flRadius, flDuration ); pMarine->OnWeaponFired( this, 1 ); pMarine->GetMarineSpeech()->Chatter(CHATTER_MINE_DEPLOYED); #endif // decrement ammo m_iClip1 -= 1; #ifndef CLIENT_DLL DestroyIfEmpty( true ); #endif m_flSoonestPrimaryAttack = gpGlobals->curtime + ASW_FLARES_FASTEST_REFIRE_TIME; if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; }
void CASW_Weapon_Flechette::PrimaryAttack() { // If my clip is empty (and I use clips) start reload if ( UsesClipsForAmmo1() && !m_iClip1 ) { Reload(); return; } CASW_Player *pPlayer = GetCommander(); CASW_Marine *pMarine = GetMarine(); if (pMarine) // firing from a marine { m_bIsFiring = true; // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); if (m_iClip1 <= AmmoClickPoint()) { LowAmmoSound(); } // tell the marine to tell its weapon to draw the muzzle flash pMarine->DoMuzzleFlash(); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); Vector vecDir; Vector vecSrc = pMarine->Weapon_ShootPosition( ); if ( pPlayer && pMarine->IsInhabited() ) { vecDir = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 } else { #ifdef CLIENT_DLL Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n"); #else vecDir = pMarine->GetActualShootTrajectory( vecSrc ); #endif } int iShots = 1; // Make sure we don't fire more than the amount in the clip if ( UsesClipsForAmmo1() ) { iShots = MIN( iShots, m_iClip1 ); m_iClip1 -= iShots; #ifdef GAME_DLL CASW_Marine *pMarine = GetMarine(); if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { pMarine->OnWeaponOutOfAmmo(true); } #endif } else { iShots = MIN( iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) ); pMarine->RemoveAmmo( iShots, m_iPrimaryAmmoType ); } /*#ifndef CLIENT_DLL if (asw_debug_marine_damage.GetBool()) Msg("Weapon dmg = %d\n", info.m_flDamage); info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale(); #endif*/ // increment shooting stats #ifndef CLIENT_DLL float fGrenadeDamage = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FLECHETTE_DMG); QAngle vecRocketAngle; VectorAngles(vecDir, vecRocketAngle); vecRocketAngle[YAW] += random->RandomFloat(-10, 10); CASW_Rocket::Create(fGrenadeDamage, vecSrc, vecRocketAngle, GetMarine()); if (pMarine && pMarine->GetMarineResource()) { pMarine->GetMarineResource()->UsedWeapon(this, iShots); pMarine->OnWeaponFired( this, iShots ); } if (ASWGameRules()) ASWGameRules()->m_fLastFireTime = gpGlobals->curtime; #endif m_flNextPrimaryAttack = m_flNextPrimaryAttack + GetFireRate(); } }
void CASW_Weapon_Pistol::PrimaryAttack( void ) { // If my clip is empty (and I use clips) start reload if ( UsesClipsForAmmo1() && !m_iClip1 ) { Reload(); return; } CASW_Player *pPlayer = GetCommander(); CASW_Marine *pMarine = GetMarine(); if (pMarine) // firing from a marine { // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); if (m_iClip1 <= AmmoClickPoint()) BaseClass::WeaponSound( EMPTY ); m_bIsFiring = true; // tell the marine to tell its weapon to draw the muzzle flash pMarine->DoMuzzleFlash(); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifdef GAME_DLL // check for turning on lag compensation if (pPlayer && pMarine->IsInhabited()) { CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() ); } #endif // if (asw_pistol_hitscan.GetBool()) if (true) { FireBulletsInfo_t info; info.m_vecSrc = pMarine->Weapon_ShootPosition( ); if ( pPlayer && pMarine->IsInhabited() ) { info.m_vecDirShooting = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 } else { #ifdef CLIENT_DLL Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n"); #else info.m_vecDirShooting = pMarine->GetActualShootTrajectory( info.m_vecSrc ); #endif } info.m_iShots = 1; // Make sure we don't fire more than the amount in the clip if ( UsesClipsForAmmo1() ) { info.m_iShots = MIN( info.m_iShots, m_iClip1 ); m_iClip1 -= info.m_iShots; #ifdef GAME_DLL CASW_Marine *pMarine = GetMarine(); if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { pMarine->OnWeaponOutOfAmmo(true); } #endif } else { info.m_iShots = MIN( info.m_iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) ); pMarine->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType ); } info.m_flDistance = asw_weapon_max_shooting_distance.GetFloat(); info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 1; info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat(); info.m_vecSpread = GetBulletSpread(); info.m_flDamage = GetWeaponDamage(); #ifndef CLIENT_DLL if (asw_debug_marine_damage.GetBool()) Msg("Weapon dmg = %f\n", info.m_flDamage); info.m_flDamage *= pMarine->OnFired_GetDamageScale(); #endif pMarine->FireBullets( info ); //FireBulletsInfo_t info( 1, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType ); //info.m_pAttacker = pMarine; // Fire the bullets, and force the first shot to be perfectly accuracy //pMarine->FireBullets( info ); } else // projectile pistol { #ifndef CLIENT_DLL Vector vecSrc = pMarine->Weapon_ShootPosition( ); Vector vecAiming = vec3_origin; if ( pPlayer && pMarine->IsInhabited() ) { vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 } else { vecAiming = pMarine->GetActualShootTrajectory( vecSrc ); } CShotManipulator Manipulator( vecAiming ); AngularImpulse rotSpeed(0,0,720); Vector newVel = Manipulator.ApplySpread(GetBulletSpread()); if ( pMarine->GetWaterLevel() == 3 ) newVel *= PELLET_WATER_VELOCITY; else newVel *= PELLET_AIR_VELOCITY; newVel *= (1.0 + (0.1 * random->RandomFloat(-1,1))); CASW_Shotgun_Pellet::Shotgun_Pellet_Create( vecSrc, QAngle(0,0,0), newVel, rotSpeed, pMarine, GetWeaponDamage() ); // decrement ammo m_iClip1 -= 1; CASW_Marine *pMarine = GetMarine(); if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { pMarine->OnWeaponOutOfAmmo(true); } #endif } // increment shooting stats #ifndef CLIENT_DLL if (pMarine && pMarine->GetMarineResource()) { pMarine->GetMarineResource()->UsedWeapon(this, 1); pMarine->OnWeaponFired( this, 1 ); } #endif } if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; m_fSlowTime = gpGlobals->curtime + 0.03f; if ( m_currentPistol == ASW_WEAPON_PISTOL_LEFT ) { m_currentPistol = ASW_WEAPON_PISTOL_RIGHT; } else { m_currentPistol = ASW_WEAPON_PISTOL_LEFT; } }
//----------------------------------------------------------------------------- // Purpose: // // //----------------------------------------------------------------------------- void CHL2MPMachineGun::PrimaryAttack( void ) { // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; // Abort here to handle burst and auto fire modes if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; m_nShotsFired++; // MUST call sound before removing a round from the clip of a CHLMachineGun // FIXME: only called once, will miss multiple sound events per frame if needed // FIXME: m_flNextPrimaryAttack is always in the past, it's not clear what'll happen with sounds WeaponSound(SINGLE, m_flNextPrimaryAttack); // Msg("%.3f\n", m_flNextPrimaryAttack.Get() ); pPlayer->DoMuzzleFlash(); // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. int iBulletsToFire = 0; float fireRate = GetFireRate(); while ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate; iBulletsToFire++; } // Make sure we don't fire more than the amount in the clip, if this weapon uses clips if ( UsesClipsForAmmo1() ) { if ( iBulletsToFire > m_iClip1 ) iBulletsToFire = m_iClip1; m_iClip1 -= iBulletsToFire; } CHL2MP_Player *pHL2MPPlayer = ToHL2MPPlayer( pPlayer ); // Fire the bullets FireBulletsInfo_t info; info.m_iShots = iBulletsToFire; info.m_vecSrc = pHL2MPPlayer->Weapon_ShootPosition( ); info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); info.m_vecSpread = pHL2MPPlayer->GetAttackSpread( this ); info.m_flDistance = MAX_TRACE_LENGTH; info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 2; FireBullets( info ); //Factor in the view kick AddViewKick(); if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { // HEV suit - indicate out of ammo condition pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); } SendWeaponAnim( GetPrimaryAttackActivity() ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); }
//=====================================================================================// // Purpose: Swing the weapon. bIsSecondary determines which Attack() function was used //=====================================================================================// void CTDPWeaponMaul::Swing( int bIsSecondary ) { // Do we have a valid owner holding the weapon? CTDPPlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; // Get the player's position Vector vSwingStart = pPlayer->Weapon_ShootPosition( ); Vector vForward; pPlayer->EyeVectors( &vForward, NULL, NULL ); // Get the attack end position by using the weapon's range Vector vSwingEnd = vSwingStart + vForward * GetRange(); trace_t tr; UTIL_TraceLine( vSwingStart, vSwingEnd, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tr ); // Let's get our animation sequence depending on the attack type Activity nHitActivity = ( bIsSecondary ) ? GetSecondaryAttackActivity() : GetPrimaryAttackActivity(); #if defined( GAME_DLL ) // Like bullets, bludgeon traces have to trace against triggers. CTakeDamageInfo triggerInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB ); TraceAttackToTriggers( triggerInfo, tr.startpos, tr.endpos, vec3_origin ); #endif // We didn't hit anything. Let's check for hull trace now if ( tr.fraction == 1.0f ) { // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM; // Back off by hull "radius" vSwingEnd -= vForward * bludgeonHullRadius; UTIL_TraceHull( vSwingStart, vSwingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tr ); // Check if we hit something and if we have hit an entity if ( tr.fraction < 1.0 && tr.m_pEnt ) { // Get the position of the entity we just hit Vector vToTarget = tr.m_pEnt->GetAbsOrigin() - vSwingStart; VectorNormalize( vToTarget ); float dot = vToTarget.Dot( vForward ); // Make sure they are sort of facing the guy at least... if ( dot < 0.70721f ) { // Force a miss tr.fraction = 1.0f; } else { // We are sort of facing something. Let's see we should impact based on the melee swing trajectory BaseClass::ChooseIntersectionPointAndActivity( tr, g_bludgeonMins, g_bludgeonMaxs, pPlayer ); } } } // See if we happened to hit water along the way BaseClass::ImpactWater( vSwingStart, tr.endpos ); // Check for hit results if ( tr.fraction == 1.0f ) { // We didn't hit anything so let's change the animation sequence to full swing nHitActivity = ( bIsSecondary ) ? GetSecondaryMissActivity() : GetPrimaryMissActivity(); } else { // We hit something. We can keep the same animation sequence. BaseClass::Hit( tr, nHitActivity ); } //Play swing sound WeaponSound( SINGLE ); // Send the anim SendWeaponAnim( nHitActivity ); // Setup our next attack times m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + GetFireRate(); // Setup our next time to idle m_flTimeWeaponIdle = gpGlobals->curtime + GetTime2Idle(); }
void CASW_Weapon::PrimaryAttack( void ) { // If my clip is empty (and I use clips) start reload if ( UsesClipsForAmmo1() && !m_iClip1 ) { Reload(); return; } CASW_Player *pPlayer = GetCommander(); CASW_Marine *pMarine = GetMarine(); if ( !pMarine ) return; m_bIsFiring = true; // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); if (m_iClip1 <= AmmoClickPoint()) { LowAmmoSound(); } // tell the marine to tell its weapon to draw the muzzle flash pMarine->DoMuzzleFlash(); // sets the animation on the weapon model itself SendWeaponAnim( GetPrimaryAttackActivity() ); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifdef GAME_DLL // check for turning on lag compensation if (pPlayer && pMarine->IsInhabited()) { CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() ); } #endif FireBulletsInfo_t info; info.m_vecSrc = pMarine->Weapon_ShootPosition( ); if ( pPlayer && pMarine->IsInhabited() ) { info.m_vecDirShooting = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 } else { #ifdef CLIENT_DLL Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n"); #else info.m_vecDirShooting = pMarine->GetActualShootTrajectory( info.m_vecSrc ); #endif } // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. info.m_iShots = 0; float fireRate = GetFireRate(); while ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate; info.m_iShots++; if ( !fireRate ) break; } // Make sure we don't fire more than the amount in the clip if ( UsesClipsForAmmo1() ) { info.m_iShots = MIN( info.m_iShots, m_iClip1 ); m_iClip1 -= info.m_iShots; #ifdef GAME_DLL CASW_Marine *pMarine = GetMarine(); if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { // check he doesn't have ammo in an ammo bay CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(0)); if (!pAmmoBag) pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(1)); if (!pAmmoBag || !pAmmoBag->CanGiveAmmoToWeapon(this)) pMarine->OnWeaponOutOfAmmo(true); } #endif } else { info.m_iShots = MIN( info.m_iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) ); pMarine->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType ); } info.m_flDistance = asw_weapon_max_shooting_distance.GetFloat(); info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 1; // asw tracer test everytime info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat(); info.m_vecSpread = pMarine->GetActiveWeapon()->GetBulletSpread(); info.m_flDamage = GetWeaponDamage(); #ifndef CLIENT_DLL if (asw_debug_marine_damage.GetBool()) Msg("Weapon dmg = %f\n", info.m_flDamage); info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale(); if (asw_DebugAutoAim.GetBool()) { NDebugOverlay::Line(info.m_vecSrc, info.m_vecSrc + info.m_vecDirShooting * info.m_flDistance, 64, 0, 64, true, 1.0); } #endif pMarine->FireBullets( info ); // increment shooting stats #ifndef CLIENT_DLL if (pMarine && pMarine->GetMarineResource()) { pMarine->GetMarineResource()->UsedWeapon(this, info.m_iShots); pMarine->OnWeaponFired( this, info.m_iShots ); } #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHL2Pistol::PrimaryAttack( void ) { if ( ( gpGlobals->curtime - m_flLastAttackTime ) > 0.5f ) { m_nNumShotsFired = 0; } else { m_nNumShotsFired++; } m_flLastAttackTime = gpGlobals->curtime; m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME; CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if( pOwner ) { // Each time the player fires the pistol, reset the view punch. This prevents // the aim from 'drifting off' when the player fires very quickly. This may // not be the ideal way to achieve this, but it's cheap and it works, which is // great for a feature we're evaluating. (sjb) pOwner->ViewPunchReset(); } // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; // Abort here to handle burst and auto fire modes if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; m_nShotsFired++; pPlayer->DoMuzzleFlash(); // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. int iBulletsToFire = 0; float fireRate = GetFireRate(); while ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { // MUST call sound before removing a round from the clip of a CHLMachineGun WeaponSound(SINGLE, m_flNextPrimaryAttack); m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate; iBulletsToFire++; } // Make sure we don't fire more than the amount in the clip, if this weapon uses clips if ( UsesClipsForAmmo1() ) { if ( iBulletsToFire > m_iClip1 ) iBulletsToFire = m_iClip1; m_iClip1 -= iBulletsToFire; } CSDKPlayer *pSDKPlayer = ToSDKPlayer( pPlayer ); // Fire the bullets FireBulletsInfo_t info; info.m_iShots = iBulletsToFire; info.m_vecSrc = pSDKPlayer->Weapon_ShootPosition( ); info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); info.m_vecSpread = GetBulletSpread(); info.m_flDistance = MAX_TRACE_LENGTH; info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 2; info.m_iDamage = GetSDKWpnData().m_iDamage; pPlayer->FireBullets( info ); //Factor in the view kick AddViewKick(); if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { // HEV suit - indicate out of ammo condition pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); } SendWeaponAnim( GetPrimaryAttackActivity() ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); // Abort here to handle burst and auto fire modes if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pOwner->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; // Add an accuracy penalty which can move past our maximum penalty time if we're really spastic m_flAccuracyPenalty += PISTOL_ACCURACY_SHOT_PENALTY_TIME; }
void CASW_Weapon_HealGrenade::PrimaryAttack( void ) { CASW_Player *pPlayer = GetCommander(); if (!pPlayer) return; CASW_Marine *pMarine = GetMarine(); #ifndef CLIENT_DLL bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this); #endif if ( !pMarine ) return; // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifndef CLIENT_DLL Vector vecSrc = pMarine->Weapon_ShootPosition( ); Vector vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f ) { vecSrc.x = pMarine->m_vecOffhandItemSpot.x; vecSrc.y = pMarine->m_vecOffhandItemSpot.y; vecSrc.z += 50.0f; } QAngle ang = pPlayer->EyeAngles(); ang.x = 0; ang.z = 0; CShotManipulator Manipulator( vecAiming ); AngularImpulse rotSpeed(0,0,720); // create a pellet at some random spread direction Vector newVel = Manipulator.ApplySpread(GetBulletSpread()); if ( pMarine->GetWaterLevel() != 3 ) { CreateProjectile( vecSrc, ang, newVel, rotSpeed, pMarine ); pMarine->OnWeaponFired( this, 1 ); } pMarine->GetMarineSpeech()->Chatter(CHATTER_MEDKIT); #endif // decrement ammo m_iClip1 -= 1; #ifndef CLIENT_DLL // destroy if empty if ( UsesClipsForAmmo1() && !m_iClip1 ) { ASWFailAdvice()->OnMedSatchelEmpty(); pMarine->GetMarineSpeech()->Chatter( CHATTER_MEDS_NONE ); if ( pMarine ) { pMarine->Weapon_Detach(this); if ( bThisActive ) pMarine->SwitchToNextBestWeapon(NULL); } Kill(); return; } #endif m_flSoonestPrimaryAttack = gpGlobals->curtime + GetRefireTime(); if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; //m_flLastFireTime = gpGlobals->curtime; }
void CASW_Weapon_Medkit::SelfHeal() { CASW_Marine *pMarine = GetMarine(); if (pMarine) // firing from a marine { if (pMarine->GetHealth() >= pMarine->GetMaxHealth()) // already on full health return; if (pMarine->GetHealth() <= 0) // aleady dead! return; if (pMarine->m_bSlowHeal) // already healing return; if (pMarine->GetFlags() & FL_FROZEN) // don't allow this if the marine is frozen return; // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); // sets the animation on the weapon model iteself SendWeaponAnim( GetPrimaryAttackActivity() ); // sets the animation on the marine holding this weapon //pMarine->SetAnimation( PLAYER_ATTACK1 ); #ifndef CLIENT_DLL bool bMedic = (pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->CanUseFirstAid()); // put a slow heal onto the marine, play a particle effect if (!pMarine->m_bSlowHeal && pMarine->GetHealth() < pMarine->GetMaxHealth()) { pMarine->AddSlowHeal( GetHealAmount(), 1, pMarine, this ); // Fire event IGameEvent * event = gameeventmanager->CreateEvent( "player_heal" ); if ( event ) { CASW_Player *pPlayer = GetCommander(); event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) ); event->SetInt( "entindex", pMarine->entindex() ); gameeventmanager->FireEvent( event ); } if ( ASWGameRules()->GetInfoHeal() ) { ASWGameRules()->GetInfoHeal()->OnMarineHealed( pMarine, pMarine, this ); } pMarine->OnWeaponFired( this, 1 ); } if (pMarine->IsInfested() && bMedic) { float fCure = GetInfestationCureAmount(); // cure infestation if (fCure < 100) pMarine->CureInfestation(pMarine, fCure); } #endif // decrement ammo m_iClip1 -= 1; #ifndef CLIENT_DLL DestroyIfEmpty( false ); #endif } }
//----------------------------------------------------------------------------- // Purpose: // // //----------------------------------------------------------------------------- void CHLMachineGun::PrimaryAttack( void ) { // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (!pPlayer) return; // Abort here to handle burst and auto fire modes if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; m_nShotsFired++; pPlayer->DoMuzzleFlash(); // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. int iBulletsToFire = 0; float fireRate = GetFireRate(); // MUST call sound before removing a round from the clip of a CHLMachineGun while ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { WeaponSound(SINGLE, m_flNextPrimaryAttack); m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate; iBulletsToFire++; } // Make sure we don't fire more than the amount in the clip, if this weapon uses clips if ( UsesClipsForAmmo1() ) { if ( iBulletsToFire > m_iClip1 ) iBulletsToFire = m_iClip1; m_iClip1 -= iBulletsToFire; } m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); // Fire the bullets FireBulletsInfo_t info; info.m_iShots = iBulletsToFire; info.m_vecSrc = pPlayer->Weapon_ShootPosition( ); info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT ); info.m_vecSpread = pPlayer->GetAttackSpread( this ); info.m_flDistance = MAX_TRACE_LENGTH; info.m_iAmmoType = m_iPrimaryAmmoType; info.m_iTracerFreq = 2; FireBullets( info ); //Factor in the view kick AddViewKick(); CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), SOUNDENT_VOLUME_MACHINEGUN, 0.2, pPlayer ); if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { // HEV suit - indicate out of ammo condition pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); } SendWeaponAnim( GetPrimaryAttackActivity() ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); // Register a muzzleflash for the AI pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 ); }
//----------------------------------------------------------------------------- // 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; }