//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ float CWeaponCombatShield::GetLoweringTime( void ) { if ((GetShieldState() != SS_DOWN ) && (GetShieldState() != SS_LOWERING)) return 0.0f; return gpGlobals->curtime - m_flShieldDownStartTime; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatShield::GetViewmodelBoneControllers( C_BaseViewModel *pViewModel, float controllers[MAXSTUDIOBONECTRLS]) { // Dial shows the shield power level float flPowerLevel = 1.0; if ( GetShieldState() == SS_UP ) { flPowerLevel = GetShieldHealth(); } else if ( GetShieldState() == SS_RAISING ) { // Bring the power up with the animation float flTotal = m_flShieldRaisedTime - m_flShieldUpStartTime; float flCurrent = (gpGlobals->curtime - m_flShieldUpStartTime); flPowerLevel = flCurrent / flTotal; } else if ( GetShieldState() == SS_LOWERING ) { // Bring the power down with the animation float flTotal = (m_flShieldLoweredTime - m_flShieldDownStartTime); float flCurrent = (gpGlobals->curtime - m_flShieldDownStartTime); flPowerLevel = 1.0 - (flCurrent / flTotal); } // Make the middle point be full power (right of the middle being powered up) // Adjust a little for the perspective. flPowerLevel *= 0.55; // Add some shake flPowerLevel += RandomFloat( -0.02, 0.02 ); controllers[0] = flPowerLevel; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ float CWeaponCombatShield::GetRaisingTime( void ) { if ((GetShieldState() != SS_UP ) && (GetShieldState() != SS_RAISING)) return 0.0f; return gpGlobals->curtime - m_flShieldUpStartTime; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatBaseGrenade::ItemPostFrame( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if (!pOwner) return; AllowShieldPostFrame( !m_flStartedThrowAt ); // Look for button downs if ( (pOwner->m_nButtons & IN_ATTACK) && GetShieldState() == SS_DOWN && !m_flStartedThrowAt && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { m_flStartedThrowAt = gpGlobals->curtime; SendWeaponAnim( ACT_VM_DRAW ); } // Look for button ups if ( (pOwner->m_afButtonReleased & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) && m_flStartedThrowAt ) { m_flNextPrimaryAttack = gpGlobals->curtime; PrimaryAttack(); m_flStartedThrowAt = 0; } // No buttons down? if ( !((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)) ) { WeaponIdle( ); } }
//----------------------------------------------------------------------------- // Purpose: Handle deploying, undeploying, firing, etc. // TODO: Add a deploy to the firing! Currently no reloading! //----------------------------------------------------------------------------- void CWeaponRocketLauncher::ItemPostFrame( void ) { // Get the player. CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); if ( !pPlayer ) return; if ( UsesClipsForAmmo1() ) { CheckReload(); } #if !defined( CLIENT_DLL ) if ( !HasPrimaryAmmo() && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) ) { pPlayer->SwitchToNextBestWeapon( NULL ); } #endif // Handle Firing if ( GetShieldState() == SS_DOWN && !m_bInReload ) { // Attempting to fire. if ( ( pPlayer->m_nButtons & IN_ATTACK ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) ) { if ( m_iClip1 > 0 ) { PrimaryAttack(); } else { Reload(); } } // Reload button (or fire button when we're out of ammo) if ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { if ( pPlayer->m_nButtons & IN_RELOAD ) { Reload(); } else if ( !((pPlayer->m_nButtons & IN_ATTACK) || (pPlayer->m_nButtons & IN_ATTACK2) || (pPlayer->m_nButtons & IN_RELOAD)) ) { if ( !m_iClip1 && HasPrimaryAmmo() ) { Reload(); } } } } // Prevent shield post frame if we're not ready to attack, or we're charging AllowShieldPostFrame( m_flNextPrimaryAttack <= gpGlobals->curtime || m_bInReload ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombatLaserRifle::ItemPostFrame( void ) { CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() ); if (!pOwner) return; if ( UsesClipsForAmmo1() ) { CheckReload(); } RecalculateAccuracy(); // Handle firing if ( GetShieldState() == SS_DOWN && !m_bInReload ) { if ( (pOwner->m_nButtons & IN_ATTACK ) && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { if ( m_iClip1 > 0 ) { // Fire the plasma shot PrimaryAttack(); } else { Reload(); } } // Reload button (or fire button when we're out of ammo) if ( m_flNextPrimaryAttack <= gpGlobals->curtime ) { if ( pOwner->m_nButtons & IN_RELOAD ) { Reload(); } else if ( !((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)) ) { if ( !m_iClip1 && HasPrimaryAmmo() ) { Reload(); } } } } // Prevent shield post frame if we're not ready to attack, or we're charging AllowShieldPostFrame( m_flNextPrimaryAttack <= gpGlobals->curtime || m_bInReload ); }
//----------------------------------------------------------------------------- // Purpose: I've been bashed by another player's shield //----------------------------------------------------------------------------- bool CWeaponCombatShield::TakeShieldBash( CBaseTFPlayer *pBasher ) { CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() ); if ( !pOwner ) return false; // If I'm blocking, drop my block and prevent me from doing anything if ( GetShieldState() == SS_UP || GetShieldState() == SS_RAISING || GetShieldState() == SS_LOWERING ) { // Make the shield unavailable SetShieldState( SS_UNAVAILABLE ); SendWeaponAnim( ACT_VM_HITCENTER ); m_flShieldUnavailableEndTime = gpGlobals->curtime + 2.0; // Play a sound EmitSound( "WeaponCombatShield.TakeBash" ); return true; } return false; }
//----------------------------------------------------------------------------- // Purpose: Get the activity the other weapon in our twohanded container should // play instead of the one it's attempting to play. //----------------------------------------------------------------------------- int CWeaponCombatShield::ReplaceOtherWeaponsActivity( int iActivity ) { switch ( iActivity ) { case ACT_VM_IDLE: // If I'm active, don't let it idle if ( GetShieldState() != SS_DOWN ) return -1; default: break; }; return BaseClass::ReplaceOtherWeaponsActivity(iActivity); }
//----------------------------------------------------------------------------- // Purpose: Attempt to block the incoming attack, and return the damage it // should do after the block, if any. //----------------------------------------------------------------------------- float CWeaponCombatShield::AttemptToBlock( float flDamage ) { CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); if ( !pPlayer || !weapon_combat_shield_factor.GetFloat() ) return 0; // Block as much of the damage as we can float flPowerNeeded = flDamage * weapon_combat_shield_factor.GetFloat(); flPowerNeeded = RemapVal( flPowerNeeded, 0, weapon_combat_shield_health.GetFloat(), 0, 1 ); float flPowerUsed = min( flPowerNeeded, GetShieldHealth() ); #ifndef CLIENT_DLL RemoveShieldHealth( flPowerUsed ); // Start recharging shortly after taking damage SetThink( ShieldRechargeThink ); SetNextThink( gpGlobals->curtime + weapon_combat_shield_rechargetime.GetFloat() ); #endif // Failed to block it all? if ( flPowerUsed < flPowerNeeded ) { #ifndef CLIENT_DLL // Force the shield to drop if it's up if ( GetShieldState() == SS_UP ) { // Play sound & anim SendWeaponAnim( ACT_VM_HAULBACK ); WeaponSound( SPECIAL2 ); SetShieldState( SS_LOWERING ); } #endif return ( flDamage - (flPowerUsed * (1.0 / weapon_combat_shield_factor.GetFloat())) ); } return 0; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCombat_ChargeablePlasma::ItemPostFrame( void ) { CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() ); if (!pOwner) return; if ( UsesClipsForAmmo1() ) { CheckReload(); } // If burst shots are firing, ignore input if ( m_iBurstShotsRemaining > 0 ) { if ( gpGlobals->curtime < m_flNextBurstShotTime ) return; if ( m_iClip1 > 0 ) { PrimaryAttack(); } m_iBurstShotsRemaining--; m_flNextBurstShotTime = gpGlobals->curtime + BURST_FIRE_RATE; m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); return; } // Handle charge firing if ( m_iClip1 > 0 && GetShieldState() == SS_DOWN && !m_bInReload ) { if ( (pOwner->m_nButtons & IN_ATTACK ) ) { if (m_bHasCharge) { if ( !m_bCharging && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { m_bCharging = true; m_flChargeStartTime = gpGlobals->curtime; // Get a lock target right now m_hLockTarget = GetLockTarget(); } } else { // Fire the plasma shot if (m_flNextPrimaryAttack <= gpGlobals->curtime) PrimaryAttack(); } } else if ( m_bCharging ) { m_bCharging = false; // Fire the plasma shot PrimaryAttack(); // We might be firing a burst shot if (m_bHasBurstShot) { if ( m_flPower >= (MAX_CHARGED_TIME * 0.5) ) { if ( m_flPower >= MAX_CHARGED_TIME ) { m_iBurstShotsRemaining = 2; } else { m_iBurstShotsRemaining = 1; } m_flNextBurstShotTime = gpGlobals->curtime + BURST_FIRE_RATE; } } } } // Reload button if ( m_iBurstShotsRemaining == 0 && !m_bCharging ) { if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload ) { Reload(); } } // Prevent shield post frame if we're not ready to attack, or we're charging AllowShieldPostFrame( !m_bCharging && ((m_flNextPrimaryAttack <= gpGlobals->curtime) || m_bInReload) ); }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool CWeaponCombatShield::IsUp( void ) { return ( GetShieldState() == SS_UP ); }
//----------------------------------------------------------------------------- // Purpose: Handle the shield input //----------------------------------------------------------------------------- void CWeaponCombatShield::ShieldPostFrame( void ) { CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() ); if (!pOwner) return; UpdateShieldState(); CheckReload(); // Store off EMP state bool isEMPed = IsOwnerEMPed(); // If the shield's unavailable, just abort if ( GetShieldState() == SS_UNAVAILABLE ) return; if ( m_flNextPrimaryAttack > gpGlobals->curtime ) return; bool shieldRaised = ( GetShieldState() == SS_UP ); bool shieldRaising = ( GetShieldState() == SS_RAISING ); // GetShieldState() == SS_LOWERING ); // If my shield's out of power, I can't do anything with it if ( !GetShieldHealth() ) return; // Was the shield button just pressed? if ( GetShieldState() == SS_DOWN && !isEMPed && pOwner->m_nButtons & IN_ATTACK2 ) { // Play sound & anim WeaponSound( SPECIAL1 ); SendWeaponAnim( ACT_VM_SECONDARYATTACK ); SetShieldState( SS_RAISING ); // Abort any reloads in progess pOwner->AbortReload(); } else if ( ( shieldRaised || shieldRaising ) && !FBitSet( pOwner->m_nButtons, IN_ATTACK2 ) ) { // Shield button was just released, check to see if we were parrying bool shouldParry = (gpGlobals->curtime < (m_flShieldUpStartTime + PARRY_DETECTION_TIME )); if ( m_bHasShieldParry && shouldParry ) { // Parry! // Play sound & anim WeaponSound( SPECIAL2 ); SendWeaponAnim( ACT_VM_SWINGHIT ); SetShieldState( SS_PARRYING ); // Bash enemies in front of me ShieldBash(); } else { // Player's just lowered his shield // Play sound & anim WeaponSound( SPECIAL2 ); SendWeaponAnim( ACT_VM_HAULBACK ); SetShieldState( SS_LOWERING ); m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); } } else if ( GetShieldState() == SS_UP && ( pOwner->m_nButtons & IN_ATTACK2 ) && ( isEMPed ) ) { // We've got our shield up, and we were just EMPed, so drop it // Play sound & anim SendWeaponAnim( ACT_VM_HAULBACK ); WeaponSound( SPECIAL2 ); SetShieldState( SS_LOWERING ); } }