//----------------------------------------------------------------------------- // Purpose: // Input : iActivity - //----------------------------------------------------------------------------- void CWarsWeapon::SendViewModelAnim( int nSequence ) { #if defined( CLIENT_DLL ) if ( !IsPredicted() ) { return; } #endif if ( nSequence < 0 ) return; CBasePlayer *pOwner = ToBasePlayer( GetCommander() ); if ( pOwner == NULL ) { BaseClass::SendViewModelAnim( nSequence ); return; } CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex ); if ( vm == NULL ) { return; } SetViewModel(); Assert( vm->ViewModelIndex() == m_nViewModelIndex ); vm->SendViewModelMatchingSequence( nSequence ); }
void CASW_Weapon::PlaySoundToOthers( const char *szSoundName ) { CASW_Player *pPlayer = GetCommander(); CSoundParameters params; if ( !GetParametersForSound( szSoundName, params, NULL ) ) return; EmitSound_t playparams( params ); // Play weapon sound from the owner if ( GetOwner() ) { CPASAttenuationFilter filter( GetOwner(), params.soundlevel ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } if ( pPlayer ) { filter.RemoveRecipient( pPlayer ); } EmitSound(filter, GetOwner()->entindex(), playparams); } // If no owner play from the weapon (this is used for thrown items) else { CPASAttenuationFilter filter( this, params.soundlevel ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } if ( pPlayer ) { filter.RemoveRecipient( pPlayer ); } EmitSound(filter, entindex(), playparams); } }
void CASW_Weapon::LowAmmoSound() { CASW_Player *pPlayer = GetCommander(); if ( GetOwner() && pPlayer && pPlayer->GetMarine() == GetOwner() ) { CSingleUserRecipientFilter filter( pPlayer ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } CSoundParameters params; if ( !GetParametersForSound( "ASW_Weapon.LowAmmoClick", params, NULL ) ) return; EmitSound_t playparams(params); EmitSound( filter, GetOwner()->entindex(), playparams ); } }
void CASW_Weapon::PlaySoundDirectlyToOwner( const char *szSoundName ) { CASW_Player *pPlayer = GetCommander(); if ( !pPlayer ) return; CSoundParameters params; if ( !GetParametersForSound( szSoundName, params, NULL ) ) return; EmitSound_t playparams( params ); CSingleUserRecipientFilter filter( pPlayer ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound( filter, GetOwner()->entindex(), playparams ); }
void CASW_Weapon_Hornet_Barrage::PrimaryAttack() { CASW_Marine *pMarine = GetMarine(); if ( !pMarine ) return; CASW_Player *pPlayer = GetCommander(); if ( !pPlayer ) return; if ( m_iRocketsToFire.Get() > 0 ) return; // mine weapon is lost when all mines are gone if ( UsesClipsForAmmo1() && !m_iClip1 ) { return; } SetRocketsToFire(); m_flFireInterval = GetRocketFireInterval(); m_flNextLaunchTime = gpGlobals->curtime; const char *pszSound = "ASW_Hornet_Barrage.Fire"; CPASAttenuationFilter filter( this, pszSound ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound( filter, entindex(), pszSound ); // decrement ammo m_iClip1 -= 1; m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); }
void CASW_Weapon::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ ) { //asw hack - don't allow normal reloading sounds to be triggered, since we fire them from the marine's reloading animation anim event if (sound_type == RELOAD) return; if (sound_type == SPECIAL2) sound_type = RELOAD; // If we have some sounds from the weapon classname.txt file, play a random one of them int iPitch = 100; const char *shootsound = GetASWShootSound( sound_type, iPitch ); //Msg("%s:%f WeaponSound %d %s\n", IsServer() ? "S" : "C", gpGlobals->curtime, sound_type, shootsound); if ( !shootsound || !shootsound[0] ) return; CSoundParameters params; if ( !GetParametersForSound( shootsound, params, NULL ) ) return; EmitSound_t playparams(params); if (soundtime != 0) playparams.m_flSoundTime = soundtime; playparams.m_nPitch = params.pitch; CASW_Player *pPlayer = GetCommander(); if ( params.play_to_owner_only ) { // Am I only to play to my owner? if ( GetOwner() && pPlayer && pPlayer->GetMarine() == GetOwner() ) { CSingleUserRecipientFilter filter( pPlayer ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound(filter, GetOwner()->entindex(), playparams); //EmitSound( filter, GetOwner()->entindex(), shootsound, NULL, soundtime ); } } else { // Play weapon sound from the owner if ( GetOwner() ) { CPASAttenuationFilter filter( GetOwner(), params.soundlevel ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound(filter, GetOwner()->entindex(), playparams); #if !defined( CLIENT_DLL ) if( sound_type == EMPTY ) { CSoundEnt::InsertSound( SOUND_COMBAT, GetOwner()->GetAbsOrigin(), SOUNDENT_VOLUME_EMPTY, 0.2, GetOwner() ); } #endif } // If no owner play from the weapon (this is used for thrown items) else { CPASAttenuationFilter filter( this, params.soundlevel ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound( filter, entindex(), shootsound, NULL, soundtime ); } } }
void CASW_Weapon::ItemBusyFrame( void ) { CASW_Marine* pMarine = GetMarine(); if ( !pMarine ) return; bool bAttack1, bAttack2, bReload, bOldReload, bOldAttack1; GetButtons(bAttack1, bAttack2, bReload, bOldReload, bOldAttack1 ); // check for clearing our weapon switching bool if (m_bSwitchingWeapons && gpGlobals->curtime > m_flNextPrimaryAttack) { m_bSwitchingWeapons = false; } // check for clearing our firing bool from reloading if (m_bInReload && gpGlobals->curtime > m_fReloadClearFiringTime) { ClearIsFiring(); } if ( (bReload && !bOldReload) && UsesClipsForAmmo1() && asw_fast_reload_enabled.GetBool() ) { if ( m_bInReload ) { // check for a fast reload //Msg("%f Check for fast reload while busy\n", gpGlobals->curtime); if (gpGlobals->curtime >= m_fFastReloadStart && gpGlobals->curtime <= m_fFastReloadEnd) { // todo: reduce next attack time m_fFastReloadEnd = 0; m_fFastReloadStart = 0; CBaseCombatCharacter *pOwner = GetOwner(); if ( pOwner ) { float flSucceedDelay = gpGlobals->curtime + 0.5f; pOwner->SetNextAttack( flSucceedDelay ); m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSucceedDelay; } // TODO: hook up anim //pMarine->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_SUCCEED ); DispatchParticleEffect( "fast_reload", PATTACH_POINT_FOLLOW, this, "muzzle" ); pMarine->m_flPreventLaserSightTime = gpGlobals->curtime + 2.5f; #ifdef GAME_DLL pMarine->m_nFastReloadsInARow++; IGameEvent * event = gameeventmanager->CreateEvent( "fast_reload" ); if ( event ) { event->SetInt( "marine", pMarine->entindex() ); event->SetInt( "reloads", pMarine->m_nFastReloadsInARow ); gameeventmanager->FireEvent( event ); } if ( pMarine->m_nFastReloadsInARow >= 4 && pMarine->IsInhabited() ) { if ( pMarine->GetMarineResource() ) { pMarine->GetMarineResource()->m_bDidFastReloadsInARow = true; } if ( pMarine->GetCommander() ) { pMarine->GetCommander()->AwardAchievement( ACHIEVEMENT_ASW_FAST_RELOADS_IN_A_ROW ); } } #endif CSoundParameters params; if ( !GetParametersForSound( "FastReload.Success", params, NULL ) ) return; EmitSound_t playparams(params); playparams.m_nPitch = params.pitch; CASW_Player *pPlayer = GetCommander(); if ( pPlayer ) { CSingleUserRecipientFilter filter( pMarine->GetCommander() ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound(filter, entindex(), playparams); } //Msg("%f RELOAD SUCCESS! - bAttack1 = %d, bOldAttack1 = %d\n", gpGlobals->curtime, bAttack1, bOldAttack1 ); //Msg( "S: %f - %f - %f RELOAD SUCCESS! -- Progress = %f\n", gpGlobals->curtime, fFastStart, fFastEnd, flProgress ); #ifdef GAME_DLL pMarine->GetMarineSpeech()->PersonalChatter(CHATTER_SELECTION); #endif m_bFastReloadSuccess = true; m_bFastReloadFailure = false; } else if (m_fFastReloadStart != 0) { CSoundParameters params; if ( !GetParametersForSound( "FastReload.Miss", params, NULL ) ) return; EmitSound_t playparams(params); playparams.m_nPitch = params.pitch; CASW_Player *pPlayer = GetCommander(); if ( pPlayer ) { CSingleUserRecipientFilter filter( pMarine->GetCommander() ); if ( IsPredicted() && CBaseEntity::GetPredictionPlayer() ) { filter.UsePredictionRules(); } EmitSound(filter, entindex(), playparams); } //Msg("%f RELOAD MISSED! - bAttack1 = %d, bOldAttack1 = %d\n", gpGlobals->curtime, bAttack1, bOldAttack1 ); //Msg( "S: %f - %f - %f RELOAD MISSED! -- Progress = %f\n", gpGlobals->curtime, fFastStart, fFastEnd, flProgress ); m_fFastReloadEnd = 0; m_fFastReloadStart = 0; CBaseCombatCharacter *pOwner = GetOwner(); if ( pOwner ) { float flMissDelay = MAX( gpGlobals->curtime + 2.0f, m_flNextPrimaryAttack + 1.0f ); pOwner->SetNextAttack( flMissDelay ); m_flNextPrimaryAttack = m_flNextSecondaryAttack = flMissDelay; m_flReloadFailTime = m_flNextPrimaryAttack - gpGlobals->curtime; } // TODO: hook up anim //pMarine->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_FAIL ); #ifdef GAME_DLL pMarine->m_nFastReloadsInARow = 0; #endif DispatchParticleEffect( "reload_fail", PATTACH_POINT_FOLLOW, this, "muzzle" ); #ifdef GAME_DLL pMarine->GetMarineSpeech()->PersonalChatter(CHATTER_PAIN_SMALL); #endif m_bFastReloadSuccess = false; m_bFastReloadFailure = true; } } } #ifdef CLIENT_DLL if ( m_bInReload ) { float fStart = m_fReloadStart; float fNext = MAX( m_flNextPrimaryAttack, GetOwner() ? GetOwner()->GetNextAttack() : 0 ); float fTotalTime = fNext - fStart; if (fTotalTime <= 0) fTotalTime = 0.1f; m_fReloadProgress = (gpGlobals->curtime - fStart) / fTotalTime; } else { m_fReloadProgress = 0; } //Msg( "S: %f Reload Progress = %f\n", gpGlobals->curtime, m_fReloadProgress ); #endif //CLIENT_DLL }
//----------------------------------------------------------------------------- // Purpose: Plasma sentrygun's fire //----------------------------------------------------------------------------- void CObjectMannedPlasmagun::Fire( ) { if (m_flNextAttack > gpGlobals->curtime) return; // Because the plasma sentrygun always thinks it has ammo (see below) // we might not have ammo here, in which case we should just abort. if ( !m_nAmmoCount ) return; // Make sure we think soon enough in case of firing... float flNextRecharge = gpGlobals->curtime + (HasPowerup(POWERUP_EMP) ? MANNED_PLASMAGUN_RECHARGE_TIME * 1.5 : MANNED_PLASMAGUN_RECHARGE_TIME); SetNextThink( gpGlobals->curtime + flNextRecharge ); // We have to flush the bone cache because it's possible that only the bone controllers // have changed since the bonecache was generated, and bone controllers aren't checked. InvalidateBoneCache(); QAngle vecAng; Vector vecSrc, vecAim; // Alternate barrels when firing if ( m_bFiringLeft ) { // Aliens permanently fire left barrel because they have no right if ( GetTeamNumber() == TEAM_HUMANS ) { m_bFiringLeft = false; } GetAttachment( m_nBarrelAttachment, vecSrc, vecAng ); SetActivity( ACT_VM_PRIMARYATTACK ); } else { m_bFiringLeft = true; GetAttachment( m_nRightBarrelAttachment, vecSrc, vecAng ); SetActivity( ACT_VM_SECONDARYATTACK ); } // Get the distance to the target AngleVectors( vecAng, &vecAim, 0, 0 ); int damageType = GetAmmoDef()->DamageType( m_nAmmoType ); CBasePlasmaProjectile *pPlasma = CBasePlasmaProjectile::CreatePredicted( vecSrc, vecAim, Vector( 0, 0, 0 ), damageType, GetDriverPlayer() ); if ( pPlasma ) { pPlasma->SetDamage( obj_manned_plasmagun_damage.GetFloat() ); pPlasma->m_hOwner = GetDriverPlayer(); //pPlasma->SetOwnerEntity( this ); pPlasma->SetMaxRange( m_flMaxRange ); if ( obj_manned_plasmagun_radius.GetFloat() ) { pPlasma->SetExplosive( obj_manned_plasmagun_radius.GetFloat() ); } } CSoundParameters params; if ( GetParametersForSound( "ObjectMannedPlasmagun.Fire", params, NULL ) ) { CPASAttenuationFilter filter( this, params.soundlevel ); if ( IsPredicted() ) { filter.UsePredictionRules(); } EmitSound( filter, entindex(), "ObjectMannedPlasmagun.Fire" ); } // SetSentryAnim( TFTURRET_ANIM_FIRE ); DoMuzzleFlash(); --m_nAmmoCount; m_flNextIdleTime = gpGlobals->curtime + MANNED_PLASMAGUN_IDLE_TIME; // If I'm EMPed, slow the firing rate down m_flNextAttack = gpGlobals->curtime + ( HasPowerup(POWERUP_EMP) ? 0.3f : 0.1f ); }
/* ===================== CBasePlayerWeapon::ItemPostFrame Handles weapon firing, reloading, etc. ===================== */ void CBasePlayerWeapon::ItemPostFrame( void ) { WeaponTick(); if( ( m_fInReload ) && ( m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) ) { #ifdef SERVER_DLL // FIXME, need ammo on client to make this work right // complete the reload. int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] ); // Add them to the clip m_iClip += j; m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] -= j; #else m_iClip += 10; #endif m_fInReload = false; } #ifdef SERVER_DLL if( !m_pPlayer->GetButtons().Any( IN_ATTACK ) ) { m_flLastFireTime = 0.0f; } #endif if( m_pPlayer->GetButtons().Any( IN_ATTACK2 ) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, IsPredicted() ) ) { if( pszAmmo2() && !m_pPlayer->m_rgAmmo[ SecondaryAmmoIndex() ] ) { m_bFireOnEmpty = true; } SecondaryAttack(); m_pPlayer->GetButtons().ClearFlags( IN_ATTACK2 ); } else if( m_pPlayer->GetButtons().Any( IN_ATTACK ) && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, IsPredicted() ) ) { if( ( m_iClip == 0 && pszAmmo1() ) || ( iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] ) ) { m_bFireOnEmpty = true; } PrimaryAttack(); } else if( m_pPlayer->GetButtons().Any( IN_RELOAD ) && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. Reload(); } else if( !m_pPlayer->GetButtons().Any( IN_ATTACK | IN_ATTACK2 ) ) { // no fire buttons down m_bFireOnEmpty = false; //Only the server checks for weapon switching. - Solokiller #ifdef SERVER_DLL if( !IsUseable() && m_flNextPrimaryAttack < ( IsPredicted() ? 0.0 : gpGlobals->time ) ) { // weapon isn't useable, switch. if( !( iFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY ) && g_pGameRules->GetNextBestWeapon( m_pPlayer, this ) ) { m_flNextPrimaryAttack = ( IsPredicted() ? 0.0 : gpGlobals->time ) + 0.3; return; } } else #endif { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if( m_iClip == 0 && !( iFlags() & ITEM_FLAG_NOAUTORELOAD ) && CanReload( m_flNextPrimaryAttack, gpGlobals->time, IsPredicted() ) ) { Reload(); return; } } WeaponIdle(); return; } // catch all if( ShouldWeaponIdle() ) { WeaponIdle(); } }