//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWeaponBaseGun::ItemPostFrame( void ) { int iOldBurstSize = m_iBurstSize; CTFPlayer *pOwner = GetTFPlayerOwner(); if ( pOwner ) { if ( m_iBurstSize > 0 ) { // Fake the fire button. pOwner->m_nButtons |= IN_ATTACK; } } BaseClass::ItemPostFrame(); // Stop burst if we run out of ammo. if ( ( UsesClipsForAmmo1() && m_iClip1 <= 0 ) || ( !UsesClipsForAmmo1() && pOwner->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) ) { m_iBurstSize = 0; } if ( iOldBurstSize > 0 && m_iBurstSize == 0 ) { // Delay the next burst. m_flNextPrimaryAttack = gpGlobals->curtime + m_pWeaponInfo->GetWeaponData( TF_WEAPON_PRIMARY_MODE ).m_flBurstDelay; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CItem_DynamicResupply::ComputeAmmoRatios( CItem_DynamicResupply* pMaster, CBasePlayer *pPlayer, int iDebug, SpawnInfo_t *pSpawnInfo ) { #ifdef TF_CLASSIC // TF2 players don't use HL2 ammo and TF2 ammo packs are based on ratios so we act differently here. // We get player's lowest ammo ratio and compare it to the desired ratio. CTFPlayer *pTFPlayer = ToTFPlayer( pPlayer ); float flLowestRatio = 1.0f; for ( int i = 1; i < TF_AMMO_GRENADES1; i++ ) { float flMaxAmmo = pTFPlayer->GetPlayerClass()->GetData()->m_aAmmoMax[i]; float flCurrentAmmo = pTFPlayer->GetAmmoCount( i ); flLowestRatio = min( flLowestRatio, ( flCurrentAmmo / flMaxAmmo ) ); } #endif for ( int i = 0; i < NUM_AMMO_ITEMS; i++ ) { #ifdef TF_CLASSIC flLowestRatio += (pSpawnInfo[i].m_iPotentialItems * g_DynamicResupplyAmmoItems[i].flAmmoRatio); pSpawnInfo[i].m_flCurrentRatio = clamp( flLowestRatio, 0, 1 );; #else // Get the ammodef's int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef ); Assert( iAmmoType != -1 ); // Ignore ammo types if we don't have a weapon that uses it (except for the grenade) if ( (i != DS_GRENADE_INDEX) && !pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) ) { pSpawnInfo[i].m_flCurrentRatio = 1.0; } else { float flMax = GetAmmoDef()->MaxCarry( iAmmoType ); float flCurrentAmmo = pPlayer->GetAmmoCount( iAmmoType ); flCurrentAmmo += (pSpawnInfo[i].m_iPotentialItems * g_DynamicResupplyAmmoItems[i].iAmmoCount); pSpawnInfo[i].m_flCurrentRatio = (flCurrentAmmo / flMax); } #endif // Use the master if we're supposed to pSpawnInfo[i].m_flDesiredRatio = pMaster->m_flDesiredAmmo[i] * sk_dynamic_resupply_modifier.GetFloat(); pSpawnInfo[i].m_flDelta = pSpawnInfo[i].m_flDesiredRatio - pSpawnInfo[i].m_flCurrentRatio; pSpawnInfo[i].m_flDelta = clamp( pSpawnInfo[i].m_flDelta, 0, 1 ); } if ( iDebug ) { Msg("Calculating desired ammo ratios & deltas:\n"); for ( int i = 0; i < NUM_AMMO_ITEMS; i++ ) { Msg(" %s Desired Ratio: %.2f, Current Ratio: %.2f = Delta of %.2f\n", g_DynamicResupplyAmmoItems[i].sEntityName, pSpawnInfo[i].m_flDesiredRatio, pSpawnInfo[i].m_flCurrentRatio, pSpawnInfo[i].m_flDelta ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFCompoundBow::WeaponIdle( void ) { CTFPlayer *pOwner = GetTFPlayerOwner(); if ( m_flChargeBeginTime > 0 && pOwner->GetAmmoCount( GetPrimaryAmmoType() ) > 0 ) { FireArrow(); } else { BaseClass::WeaponIdle(); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFFlameThrower::ItemPostFrame() { if ( m_bLowered ) return; // Get the player owning the weapon. CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); if ( !pOwner ) return; int iAmmo = pOwner->GetAmmoCount( m_iPrimaryAmmoType ); bool bFired = false; if ( ( pOwner->m_nButtons & IN_ATTACK2 ) && m_flNextSecondaryAttack <= gpGlobals->curtime ) { float flAmmoPerSecondaryAttack = TF_FLAMETHROWER_AMMO_PER_SECONDARY_ATTACK; CALL_ATTRIB_HOOK_FLOAT( flAmmoPerSecondaryAttack, mult_airblast_cost ); if ( iAmmo >= flAmmoPerSecondaryAttack ) { SecondaryAttack(); bFired = true; } } else if ( ( pOwner->m_nButtons & IN_ATTACK ) && iAmmo > 0 && m_iWeaponState != FT_STATE_AIRBLASTING ) { PrimaryAttack(); bFired = true; } if ( !bFired ) { if ( m_iWeaponState > FT_STATE_IDLE ) { SendWeaponAnim( ACT_MP_ATTACK_STAND_POSTFIRE ); pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_POST ); m_iWeaponState = FT_STATE_IDLE; m_bCritFire = false; m_bHitTarget = false; } if ( !ReloadOrSwitchWeapons() ) { WeaponIdle(); } } //BaseClass::ItemPostFrame(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFHunterRifle::ZoomIn( void ) { // Start aiming. CTFPlayer *pPlayer = GetTFPlayerOwner(); if ( !pPlayer ) return; if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 || Clip1() <= 0) return; pPlayer->SetFOV(pPlayer, TF_WEAPON_ZOOM_FOV, 0.1f); //BaseClass::ZoomIn(); pPlayer->m_Shared.AddCond( TF_COND_AIMING ); pPlayer->TeamFortress_SetSpeed(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFSniperRifle::ZoomIn( void ) { // Start aiming. CTFPlayer *pPlayer = GetTFPlayerOwner(); if ( !pPlayer ) return; if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) return; BaseClass::ZoomIn(); pPlayer->m_Shared.AddCond( TF_COND_AIMING ); pPlayer->TeamFortress_SetSpeed(); #ifdef GAME_DLL // Create the sniper dot. CreateSniperDot(); pPlayer->ClearExpression(); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFMinigun::SharedAttack() { CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() ); if ( !pPlayer ) return; if ( !CanAttack() ) { WeaponIdle(); return; } if ( pPlayer->m_nButtons & IN_ATTACK ) { m_iWeaponMode = TF_WEAPON_PRIMARY_MODE; } else if ( pPlayer->m_nButtons & IN_ATTACK2 ) { m_iWeaponMode = TF_WEAPON_SECONDARY_MODE; } switch ( m_iWeaponState ) { default: case AC_STATE_IDLE: { // Removed the need for cells to powerup the AC WindUp(); m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; m_flNextSecondaryAttack = gpGlobals->curtime + 1.0; m_flTimeWeaponIdle = gpGlobals->curtime + 1.0; m_flStartedFiringAt = -1; pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRE ); break; } case AC_STATE_STARTFIRING: { // Start playing the looping fire sound if ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { if ( m_iWeaponMode == TF_WEAPON_SECONDARY_MODE ) { m_iWeaponState = AC_STATE_SPINNING; #ifdef GAME_DLL pPlayer->SpeakWeaponFire( MP_CONCEPT_WINDMINIGUN ); #endif } else { m_iWeaponState = AC_STATE_FIRING; #ifdef GAME_DLL pPlayer->SpeakWeaponFire( MP_CONCEPT_FIREMINIGUN ); #endif } m_flNextSecondaryAttack = m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1; } break; } case AC_STATE_FIRING: { if ( m_iWeaponMode == TF_WEAPON_SECONDARY_MODE ) { #ifdef GAME_DLL pPlayer->ClearWeaponFireScene(); pPlayer->SpeakWeaponFire( MP_CONCEPT_WINDMINIGUN ); #endif m_iWeaponState = AC_STATE_SPINNING; m_flNextSecondaryAttack = m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1; } else if ( pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { m_iWeaponState = AC_STATE_DRYFIRE; } else { if ( m_flStartedFiringAt < 0 ) { m_flStartedFiringAt = gpGlobals->curtime; } #ifdef GAME_DLL if ( m_flNextFiringSpeech < gpGlobals->curtime ) { m_flNextFiringSpeech = gpGlobals->curtime + 5.0; pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_MINIGUN_FIREWEAPON ); } #endif // Only fire if we're actually shooting BaseClass::PrimaryAttack(); // fire and do timers CalcIsAttackCritical(); m_bCritShot = IsCurrentAttackACrit(); pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); m_flTimeWeaponIdle = gpGlobals->curtime + 0.2; } break; } case AC_STATE_DRYFIRE: { m_flStartedFiringAt = -1; if ( pPlayer->GetAmmoCount(m_iPrimaryAmmoType) > 0 ) { m_iWeaponState = AC_STATE_FIRING; } else if ( m_iWeaponMode == TF_WEAPON_SECONDARY_MODE ) { m_iWeaponState = AC_STATE_SPINNING; } SendWeaponAnim( ACT_VM_SECONDARYATTACK ); break; } case AC_STATE_SPINNING: { m_flStartedFiringAt = -1; if ( m_iWeaponMode == TF_WEAPON_PRIMARY_MODE ) { if ( pPlayer->GetAmmoCount(m_iPrimaryAmmoType) > 0 ) { #ifdef GAME_DLL pPlayer->ClearWeaponFireScene(); pPlayer->SpeakWeaponFire( MP_CONCEPT_FIREMINIGUN ); #endif m_iWeaponState = AC_STATE_FIRING; } else { m_iWeaponState = AC_STATE_DRYFIRE; } } SendWeaponAnim( ACT_VM_SECONDARYATTACK ); break; } } }