//----------------------------------------------------------------------------- // Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received //----------------------------------------------------------------------------- bool C_BaseCombatWeapon::ShouldDrawPickup( void ) { if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP ) return false; if ( m_bJustRestored ) return false; return true; }
//----------------------------------------------------------------------------- // Purpose: Return true if this weapon has some ammo //----------------------------------------------------------------------------- bool CASW_Weapon::HasAmmo( void ) { // Weapons with no ammo types can always be selected if ( m_iPrimaryAmmoType == -1 && m_iSecondaryAmmoType == -1 ) return true; if ( GetWeaponFlags() & ITEM_FLAG_SELECTONEMPTY ) return true; CBaseCombatCharacter *pOwner = GetOwner(); if ( !pOwner ) return false; return ( m_iClip1 > 0 || pOwner->GetAmmoCount( m_iPrimaryAmmoType ) || m_iClip2 > 0 || pOwner->GetAmmoCount( m_iSecondaryAmmoType ) ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponDODBase::ItemBusyFrame() { if( ShouldAutoReload() && !m_bInReload ) { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 == 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { Reload(); } } BaseClass::ItemBusyFrame(); }
//----------------------------------------------------------------------------- // Purpose: If the current weapon has more ammo, reload it. Otherwise, switch // to the next best weapon we've got. Returns true if it took any action. //----------------------------------------------------------------------------- bool CASW_Weapon::ReloadOrSwitchWeapons( void ) { CASW_Player *pPlayer = NULL; CASW_Marine *pMarine = NULL; bool bAutoReload = true; pMarine = dynamic_cast<CASW_Marine*>(GetOwner()); if (pMarine) { if (pMarine->GetCommander() && pMarine->IsInhabited()) { pPlayer = pMarine->GetCommander(); bAutoReload = pPlayer->ShouldAutoReload(); } } // if (HasAnyAmmo()) // asw add later! m_bFireOnEmpty = false; if ( UsesClipsForAmmo1() && (m_iClip1 == 0) && (GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) == false && bAutoReload && m_flNextPrimaryAttack < gpGlobals->curtime && m_flNextSecondaryAttack < gpGlobals->curtime && !m_bInReload) { // if we're successfully reloading, we're done if ( Reload() ) { return true; } else { ClearIsFiring(); } } return false; }
//----------------------------------------------------------------------------- // Purpose: Override so shotgun can do mulitple reloads in a row //----------------------------------------------------------------------------- void CWeaponShotgun::ItemPostFrame( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if (!pOwner) { return; } if ( m_bNeedPump && ( pOwner->m_nButtons & IN_RELOAD ) ) { m_bDelayedReload = true; } if (m_bInReload) { // If I'm primary firing and have one round stop reloading and fire if ((pOwner->m_nButtons & IN_ATTACK ) && (m_iClip1 >=1) && !m_bNeedPump ) { m_bInReload = false; m_bNeedPump = false; m_bDelayedFire1 = true; } // If I'm secondary firing and have two rounds stop reloading and fire else if ((pOwner->m_nButtons & IN_ATTACK2 ) && (m_iClip1 >=2) && !m_bNeedPump ) { m_bInReload = false; m_bNeedPump = false; m_bDelayedFire2 = true; } else if (m_flNextPrimaryAttack <= gpGlobals->curtime) { // If out of ammo end reload if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <=0) { FinishReload(); return; } // If clip not full reload again if (m_iClip1 < GetMaxClip1()) { Reload(); return; } // Clip full, stop reloading else { FinishReload(); return; } } } else { // Make shotgun shell invisible SetBodygroup(1,1); } if ((m_bNeedPump) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) { Pump(); return; } // Shotgun uses same timing and ammo for secondary attack if ((m_bDelayedFire2 || pOwner->m_nButtons & IN_ATTACK2)&&(m_flNextPrimaryAttack <= gpGlobals->curtime)) { m_bDelayedFire2 = false; if ( (m_iClip1 <= 1 && UsesClipsForAmmo1())) { // If only one shell is left, do a single shot instead if ( m_iClip1 == 1 ) { PrimaryAttack(); } else if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType)) { DryFire(); } else { StartReload(); } } // Fire underwater? else if (GetOwner()->GetWaterLevel() == 3 && m_bFiresUnderwater == false) { WeaponSound(EMPTY); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; return; } else { // If the firing button was just pressed, reset the firing time if ( pOwner->m_afButtonPressed & IN_ATTACK ) { m_flNextPrimaryAttack = gpGlobals->curtime; } SecondaryAttack(); } } else if ( (m_bDelayedFire1 || pOwner->m_nButtons & IN_ATTACK) && m_flNextPrimaryAttack <= gpGlobals->curtime) { m_bDelayedFire1 = false; if ( (m_iClip1 <= 0 && UsesClipsForAmmo1()) || ( !UsesClipsForAmmo1() && !pOwner->GetAmmoCount(m_iPrimaryAmmoType) ) ) { if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType)) { DryFire(); } else { StartReload(); } } // Fire underwater? else if (pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false) { WeaponSound(EMPTY); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; return; } else { // If the firing button was just pressed, reset the firing time CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( pPlayer && pPlayer->m_afButtonPressed & IN_ATTACK ) { m_flNextPrimaryAttack = gpGlobals->curtime; } PrimaryAttack(); } } if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. StartReload(); } else { // no fire buttons down m_bFireOnEmpty = false; if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime ) { // weapon isn't useable, switch. if ( !(GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && pOwner->SwitchToNextBestWeapon( this ) ) { m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; return; } } else { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 <= 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { if (StartReload()) { // if we've successfully started to reload, we're done return; } } } WeaponIdle( ); return; } }
//----------------------------------------------------------------------------- // Purpose: Overloaded to handle the zoom functionality. //----------------------------------------------------------------------------- void CWeaponSniperRifle::ItemPostFrame( void ) { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if (pPlayer == NULL) { return; } if ((m_bInReload) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) { FinishReload(); m_bInReload = false; } if (pPlayer->m_nButtons & IN_ATTACK2) { if (m_fNextZoom <= gpGlobals->curtime) { Zoom(); pPlayer->m_nButtons &= ~IN_ATTACK2; } } else if ((pPlayer->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) { if ( (m_iClip1 == 0 && UsesClipsForAmmo1()) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) { m_bFireOnEmpty = true; } // Fire underwater? if (pPlayer->GetWaterLevel() == 3 && m_bFiresUnderwater == false) { WeaponSound(EMPTY); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; return; } else { // If the firing button was just pressed, reset the firing time if ( pPlayer && pPlayer->m_afButtonPressed & IN_ATTACK ) { m_flNextPrimaryAttack = gpGlobals->curtime; } PrimaryAttack(); } } // ----------------------- // Reload pressed / Clip Empty // ----------------------- if ( pPlayer->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. Reload(); } // ----------------------- // No buttons down // ----------------------- if (!((pPlayer->m_nButtons & IN_ATTACK) || (pPlayer->m_nButtons & IN_ATTACK2) || (pPlayer->m_nButtons & IN_RELOAD))) { // no fire buttons down m_bFireOnEmpty = false; if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime ) { // weapon isn't useable, switch. if ( !(GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && pPlayer->SwitchToNextBestWeapon( this ) ) { m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; return; } } else { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 == 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { Reload(); return; } } WeaponIdle( ); return; } }
void CWeaponDODBase::ItemPostFrame() { if ( m_flSmackTime > 0 && gpGlobals->curtime > m_flSmackTime ) { Smack(); m_flSmackTime = -1; } CBasePlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; #ifdef _DEBUG CDODGameRules *mp = DODGameRules(); #endif assert( mp ); if ((m_bInReload) && (pPlayer->m_flNextAttack <= gpGlobals->curtime)) { // complete the reload. int j = min( GetMaxClip1() - m_iClip1, pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) ); // Add them to the clip m_iClip1 += j; pPlayer->RemoveAmmo( j, m_iPrimaryAmmoType ); m_bInReload = false; FinishReload(); } if ((pPlayer->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) { if ( m_iClip2 != -1 && !pPlayer->GetAmmoCount( GetSecondaryAmmoType() ) ) { m_bFireOnEmpty = TRUE; } SecondaryAttack(); pPlayer->m_nButtons &= ~IN_ATTACK2; } else if ((pPlayer->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime ) && !m_bInAttack ) { if ( (m_iClip1 == 0/* && pszAmmo1()*/) || (GetMaxClip1() == -1 && !pPlayer->GetAmmoCount( GetPrimaryAmmoType() ) ) ) { m_bFireOnEmpty = TRUE; } if( CanAttack() ) PrimaryAttack(); } else if ( pPlayer->m_nButtons & IN_RELOAD && GetMaxClip1() != WEAPON_NOCLIP && !m_bInReload && m_flNextPrimaryAttack < gpGlobals->curtime) { // reload when reload is pressed, or if no buttons are down and weapon is empty. Reload(); } else if ( !(pPlayer->m_nButtons & (IN_ATTACK|IN_ATTACK2) ) ) { // no fire buttons down m_bFireOnEmpty = false; m_bInAttack = false; //reset semi-auto if ( !IsUseable() && m_flNextPrimaryAttack < gpGlobals->curtime ) { // Intentionally blank -- used to switch weapons here } else if( ShouldAutoReload() ) { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 == 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { Reload(); return; } } WeaponIdle( ); return; } }
//----------------------------------------------------------------------------- // Purpose: Override so shotgun can do mulitple reloads in a row //----------------------------------------------------------------------------- void CWeaponShotgun::ItemPostFrame( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if (!pOwner) { return; } //Create our trace_t class to hold the end result trace_t WallTR; //Create Vectors for the start, stop, and direction Vector vecAbsStart, vecAbsEnd, vecDir; //Take the Player's EyeAngles and turn it into a direction AngleVectors( pOwner->EyeAngles(), &vecDir ); //Get the Start/End vecAbsStart = pOwner->EyePosition(); vecAbsEnd = vecAbsStart + (vecDir * 32.0); //Do the TraceLine, and write our results to our trace_t class, tr. UTIL_TraceLine( vecAbsStart, vecAbsEnd, MASK_ALL, pOwner, COLLISION_GROUP_NONE, &WallTR ); if (WallTR.DidHit()) { bLowered = true; SendWeaponAnim( ACT_VM_IDLE_LOWERED ); m_fLoweredReady = gpGlobals->curtime + GetViewModelSequenceDuration(); m_flNextPrimaryAttack = m_fLoweredReady; } else if ( !bLowered && (pOwner->m_nButtons & IN_SPEED ) ) { bLowered = true; SendWeaponAnim( ACT_VM_IDLE_LOWERED ); m_fLoweredReady = gpGlobals->curtime + GetViewModelSequenceDuration(); m_flNextPrimaryAttack = m_fLoweredReady; } else if ( bLowered && !(pOwner->m_nButtons & IN_SPEED ) ) { bLowered = false; SendWeaponAnim( ACT_VM_IDLE ); m_fLoweredReady = gpGlobals->curtime + GetViewModelSequenceDuration(); m_flNextPrimaryAttack = m_fLoweredReady; } if ( pOwner->m_nButtons & IN_ALT1 && !bLowered ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. EnableIronsights(); } else if ( !( pOwner->m_nButtons & IN_ALT1) || bLowered ) { DisableIronsights(); } if ( bLowered ) { if ( gpGlobals->curtime > m_fLoweredReady ) { bLowered = true; SendWeaponAnim( ACT_VM_IDLE_LOWERED ); m_fLoweredReady = gpGlobals->curtime + GetViewModelSequenceDuration(); } return; } else if ( bLowered ) { if ( gpGlobals->curtime > m_fLoweredReady ) { bLowered = false; SendWeaponAnim( ACT_VM_IDLE ); m_fLoweredReady = gpGlobals->curtime + GetViewModelSequenceDuration(); } return; } if (m_bInReload) { // If I'm primary firing and have one round stop reloading and fire if ((pOwner->m_nButtons & IN_ATTACK ) && (m_iClip1 >=1)) { m_bInReload = false; m_bNeedPump = false; m_bDelayedFire1 = true; } // If I'm secondary firing and have one round stop reloading and fire else if ((pOwner->m_nButtons & IN_ATTACK2 ) && (m_iClip1 >=2)) { m_bInReload = false; m_bNeedPump = false; m_bDelayedFire2 = true; } else if (m_flNextPrimaryAttack <= gpGlobals->curtime) { // If out of ammo end reload if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <=0) { FinishReload(); return; } // If clip not full reload again if (m_iClip1 < GetMaxClip1()) { Reload(); return; } // Clip full, stop reloading else { FinishReload(); return; } } } else { // Make shotgun shell invisible SetBodygroup(1,1); } if ((m_bNeedPump) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) { Pump(); return; } // Shotgun uses same timing and ammo for secondary attack if ((m_bDelayedFire2 || pOwner->m_nButtons & IN_ATTACK2)&&(m_flNextPrimaryAttack <= gpGlobals->curtime)) { m_bDelayedFire2 = false; if ( (m_iClip1 <= 1 && UsesClipsForAmmo1())) { // If only one shell is left, do a single shot instead if ( m_iClip1 == 1 ) { PrimaryAttack(); } else if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType)) { DryFire(); } else { StartReload(); } } // Fire underwater? else if (GetOwner()->GetWaterLevel() == 3 && m_bFiresUnderwater == false) { WeaponSound(EMPTY); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; return; } else { // If the firing button was just pressed, reset the firing time if ( pOwner->m_afButtonPressed & IN_ATTACK ) { m_flNextPrimaryAttack = gpGlobals->curtime; } SecondaryAttack(); } } else if ( (m_bDelayedFire1 || pOwner->m_nButtons & IN_ATTACK) && m_flNextPrimaryAttack <= gpGlobals->curtime) { m_bDelayedFire1 = false; if ( (m_iClip1 <= 0 && UsesClipsForAmmo1()) || ( !UsesClipsForAmmo1() && !pOwner->GetAmmoCount(m_iPrimaryAmmoType) ) ) { if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType)) { DryFire(); } else { StartReload(); } } // Fire underwater? else if (pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false) { WeaponSound(EMPTY); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; return; } else { // If the firing button was just pressed, reset the firing time CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( pPlayer && pPlayer->m_afButtonPressed & IN_ATTACK ) { m_flNextPrimaryAttack = gpGlobals->curtime; } PrimaryAttack(); } } if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. StartReload(); } else { // no fire buttons down m_bFireOnEmpty = false; if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime ) { // weapon isn't useable, switch. if ( !(GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && pOwner->SwitchToNextBestWeapon( this ) ) { m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; return; } } else { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 <= 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { if (StartReload()) { // if we've successfully started to reload, we're done return; } } } WeaponIdle( ); return; } }