//----------------------------------------------------------------------------- // Purpose: // Input : *idealActivity - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CTFPlayerAnimState::HandleDucking( Activity &idealActivity ) { if (GetBasePlayer()->GetFlags() & FL_DUCKING) { if ( GetOuterXYSpeed() < MOVING_MINIMUM_SPEED || m_pTFPlayer->m_Shared.IsLoser() ) { idealActivity = ACT_MP_CROUCH_IDLE; if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) || m_flHoldDeployedPoseUntilTime > gpGlobals->curtime ) { idealActivity = ACT_MP_CROUCH_DEPLOYED_IDLE; } } else { idealActivity = ACT_MP_CROUCHWALK; if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) ) { // Don't do this for the heavy! we don't usually let him deployed crouch walk bool bIsMinigun = false; CTFPlayer *pPlayer = GetTFPlayer(); if ( pPlayer && pPlayer->GetActiveTFWeapon() ) { bIsMinigun = ( pPlayer->GetActiveTFWeapon()->GetWeaponID() == TF_WEAPON_MINIGUN ); } if ( !bIsMinigun ) { idealActivity = ACT_MP_CROUCH_DEPLOYED; } } } return true; } return false; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CHudMenuEngyBuild::ShouldDraw( void ) { CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return false; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); if ( !pWpn ) return false; // Don't show the menu for first person spectator if ( pPlayer != pWpn->GetOwner() ) return false; if ( !CHudElement::ShouldDraw() ) return false; return ( pWpn->GetWeaponID() == TF_WEAPON_PDA_ENGINEER_BUILD ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CHudMenuSpyDisguise::ShouldDraw( void ) { CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return false; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); if ( !pWpn ) return false; // Don't show the menu for first person spectator if ( pPlayer != pWpn->GetOwner() ) return false; if ( pPlayer->m_Shared.InCond( TF_COND_TAUNTING ) ) return false; return ( pWpn->GetWeaponID() == TF_WEAPON_PDA_SPY ); }
// ----------------------------------------------------------------------------- // Purpose: // Note: Think function to delay the impact decal until the animation is finished // playing. // ----------------------------------------------------------------------------- void CTFWeaponBaseMelee::Smack( void ) { trace_t trace; CBasePlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; #if !defined (CLIENT_DLL) // Move other players back to history positions based on local player's lag lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() ); #endif // We hit, setup the smack. if ( DoSwingTrace( trace ) ) { // Hit sound - immediate. if( trace.m_pEnt->IsPlayer() ) { WeaponSound( MELEE_HIT ); } else { WeaponSound( MELEE_HIT_WORLD ); } // Get the current player. CTFPlayer *pPlayer = GetTFPlayerOwner(); if ( !pPlayer ) return; Vector vecForward; AngleVectors( pPlayer->EyeAngles(), &vecForward ); Vector vecSwingStart = pPlayer->Weapon_ShootPosition(); Vector vecSwingEnd = vecSwingStart + vecForward * 48; #ifndef CLIENT_DLL // Do Damage. int iCustomDamage = TF_DMG_CUSTOM_NONE; float flDamage = GetMeleeDamage( trace.m_pEnt, iCustomDamage ); int iDmgType = DMG_BULLET | DMG_NEVERGIB | DMG_CLUB; if ( IsCurrentAttackACrit() ) { // TODO: Not removing the old critical path yet, but the new custom damage is marking criticals as well for melee now. iDmgType |= DMG_CRITICAL; } CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); CTFUbersaw *pUbersaw = dynamic_cast<CTFUbersaw*>(pWpn); CWeaponMedigun *pMedigun = static_cast<CWeaponMedigun*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_MEDIGUN)); if (pMedigun && pUbersaw) { if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber()) { pMedigun->AddCharge(); } } CWeaponKritzkrieg *pKritzkrieg = static_cast<CWeaponKritzkrieg*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_KRITZKRIEG)); if (pKritzkrieg && pUbersaw) { if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber()) { pKritzkrieg->AddCharge(); } } CTakeDamageInfo info( pPlayer, pPlayer, flDamage, iDmgType, iCustomDamage ); CalculateMeleeDamageForce( &info, vecForward, vecSwingEnd, 1.0f / flDamage * tf_meleeattackforcescale.GetFloat() ); trace.m_pEnt->DispatchTraceAttack( info, vecForward, &trace ); ApplyMultiDamage(); OnEntityHit( trace.m_pEnt ); #endif // Don't impact trace friendly players or objects if ( trace.m_pEnt && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber() ) { #ifdef CLIENT_DLL UTIL_ImpactTrace( &trace, DMG_CLUB ); #endif m_bConnected = true; } } #if !defined (CLIENT_DLL) lagcompensation->FinishLagCompensation( pPlayer ); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CTFDroppedWeapon::MyTouch( CBasePlayer *pPlayer ) { bool bSuccess = false; CTFPlayer *pTFPlayer = dynamic_cast<CTFPlayer *>( pPlayer ); if ( ValidTouch( pTFPlayer ) && pTFPlayer->IsPlayerClass( TF_CLASS_MERCENARY ) ) { // Don't remove weapon while a player is standing over it. SetThink( NULL ); #ifndef DM_WEAPON_BUCKET int iSlot = m_Item.GetStaticData()->GetLoadoutSlot( TF_CLASS_MERCENARY ); CTFWeaponBase *pWeapon = (CTFWeaponBase *)pTFPlayer->GetEntityForLoadoutSlot( iSlot ); const char *pszWeaponName = m_Item.GetEntityName(); int iAmmoType = m_pWeaponInfo->iAmmoType; if ( pWeapon ) { if ( pWeapon->GetItemID() == m_Item.GetItemDefIndex() ) { // Give however many ammo we have if ( pTFPlayer->GiveAmmo( m_iAmmo, iAmmoType, true, TF_AMMO_SOURCE_AMMOPACK ) ) bSuccess = true; } else if ( !(pTFPlayer->m_nButtons & IN_ATTACK) && ( pTFPlayer->m_nButtons & IN_USE ) ) // Check Use button { // Drop a usable weapon pTFPlayer->DropWeapon( pWeapon ); if ( pWeapon == pTFPlayer->GetActiveTFWeapon() ) { pWeapon->Holster(); } pTFPlayer->Weapon_Detach( pWeapon ); UTIL_Remove( pWeapon ); pWeapon = NULL; } else { pTFPlayer->m_Shared.SetDesiredWeaponIndex( m_Item.GetItemDefIndex() ); } } #else CTFWeaponBase *pWeapon = pTFPlayer->Weapon_OwnsThisID( m_nWeaponID ); if ( pWeapon ) { if ( pTFPlayer->GiveAmmo( 999, GetTFWeaponInfo( m_nWeaponID )->iAmmoType ) ); bSuccess = true; } #endif if ( !pWeapon ) { CTFWeaponBase *pNewWeapon = (CTFWeaponBase *)pTFPlayer->GiveNamedItem( pszWeaponName, 0, &m_Item ); if ( pNewWeapon ) { pPlayer->SetAmmoCount( m_iAmmo, iAmmoType ); pNewWeapon->DefaultTouch( pPlayer ); if ( pPlayer == GetOwnerEntity() ) { // If this is the same guy who dropped it restore old clip size to avoid exploiting swapping // weapons for faster reload. pNewWeapon->m_iClip1 = m_iClip; } pTFPlayer->m_Shared.SetDesiredWeaponIndex( -1 ); bSuccess = true; } } if ( bSuccess ) { CSingleUserRecipientFilter user( pPlayer ); user.MakeReliable(); UserMessageBegin( user, "ItemPickup" ); WRITE_STRING( GetClassname() ); MessageEnd(); pPlayer->EmitSound( "BaseCombatCharacter.AmmoPickup" ); } } return bSuccess; }
//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void CObjectTeleporter::TeleporterThink( void ) { SetContextThink( &CObjectTeleporter::TeleporterThink, gpGlobals->curtime + BUILD_TELEPORTER_NEXT_THINK, TELEPORTER_THINK_CONTEXT ); // At any point, if our match is not ready, revert to IDLE if ( IsDisabled() || IsRedeploying() || IsMatchingTeleporterReady() == false ) { ShowDirectionArrow( false ); if ( GetState() != TELEPORTER_STATE_IDLE && !IsUpgrading() ) { SetState( TELEPORTER_STATE_IDLE ); CObjectTeleporter *pMatch = GetMatchingTeleporter(); if ( !pMatch ) { // The other end has been destroyed. Revert back to L1. m_iUpgradeLevel = 1; // We need to adjust for any damage received if we downgraded float flHealthPercentage = GetHealth() / GetMaxHealthForCurrentLevel(); SetMaxHealth( GetMaxHealthForCurrentLevel() ); SetHealth( (int)( GetMaxHealthForCurrentLevel() * flHealthPercentage ) ); m_iUpgradeMetal = 0; } } return; } if ( m_flMyNextThink && m_flMyNextThink > gpGlobals->curtime ) return; // pMatch is not NULL and is not building CObjectTeleporter *pMatch = GetMatchingTeleporter(); Assert( pMatch ); Assert( pMatch->m_iState != TELEPORTER_STATE_BUILDING ); switch ( m_iState ) { // Teleporter is not yet active, do nothing case TELEPORTER_STATE_BUILDING: case TELEPORTER_STATE_UPGRADING: ShowDirectionArrow( false ); break; default: case TELEPORTER_STATE_IDLE: // Do we have a match that is active? // Make sure both ends wait through full recharge time in case they get upgraded while recharging. if ( IsMatchingTeleporterReady() && !IsUpgrading() && gpGlobals->curtime > m_flRechargeTime ) { SetState( TELEPORTER_STATE_READY ); EmitSound( "Building_Teleporter.Ready" ); if ( GetObjectMode() == TELEPORTER_TYPE_ENTRANCE ) { ShowDirectionArrow( true ); } } break; case TELEPORTER_STATE_READY: break; case TELEPORTER_STATE_SENDING: { pMatch->TeleporterReceive( m_hTeleportingPlayer, 1.0 ); m_flRechargeTime = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEOUT_TIME + BUILD_TELEPORTER_FADEIN_TIME + g_flTeleporterRechargeTimes[ GetUpgradeLevel() - 1] ); // change state to recharging... SetState( TELEPORTER_STATE_RECHARGING ); } break; case TELEPORTER_STATE_RECEIVING: { // get the position we'll move the player to Vector newPosition = GetAbsOrigin(); newPosition.z += TELEPORTER_MAXS.z + 1; // Telefrag anyone in the way CBaseEntity *pEnts[256]; Vector mins, maxs; Vector expand( 4, 4, 4 ); mins = newPosition + VEC_HULL_MIN - expand; maxs = newPosition + VEC_HULL_MAX + expand; CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get(); // move the player if ( pTeleportingPlayer ) { CUtlVector<CBaseEntity*> hPlayersToKill; bool bClear = true; // Telefrag any players in the way int numEnts = UTIL_EntitiesInBox( pEnts, 256, mins, maxs, 0 ); if ( numEnts ) { //Iterate through the list and check the results for ( int i = 0; i < numEnts && bClear; i++ ) { if ( pEnts[i] == NULL ) continue; if ( pEnts[i] == this ) continue; // kill players if ( pEnts[i]->IsPlayer() ) { if ( !pTeleportingPlayer->InSameTeam(pEnts[i]) ) { hPlayersToKill.AddToTail( pEnts[i] ); } continue; } if ( pEnts[i]->IsBaseObject() ) continue; // Solid entities will prevent a teleport if ( pEnts[i]->IsSolid() && pEnts[i]->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), MASK_ALL ) && g_pGameRules->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), pEnts[i]->GetCollisionGroup() ) ) { // We're going to teleport into something solid. Abort & destroy this exit. bClear = false; } } } if ( bClear ) { // Telefrag all enemy players we've found for ( int player = 0; player < hPlayersToKill.Count(); player++ ) { CTakeDamageInfo info( this, pTeleportingPlayer, 1000, DMG_CRUSH, TF_DMG_TELEFRAG ); hPlayersToKill[player]->TakeDamage( info ); } pTeleportingPlayer->Teleport( &newPosition, &(GetAbsAngles()), &vec3_origin ); // Unzoom if we are a sniper zoomed! if ( ( pTeleportingPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_SNIPER ) && pTeleportingPlayer->m_Shared.InCond( TF_COND_AIMING ) ) { CTFWeaponBase *pWpn = pTeleportingPlayer->GetActiveTFWeapon(); if ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE ) { CTFSniperRifle *pRifle = static_cast<CTFSniperRifle*>( pWpn ); pRifle->ToggleZoom(); } } pTeleportingPlayer->SetFOV( pTeleportingPlayer, 0, tf_teleporter_fov_time.GetFloat(), tf_teleporter_fov_start.GetInt() ); color32 fadeColor = {255,255,255,100}; UTIL_ScreenFade( pTeleportingPlayer, fadeColor, 0.25, 0.4, FFADE_IN ); } else { DetonateObject(); } } SetState( TELEPORTER_STATE_RECEIVING_RELEASE ); m_flMyNextThink = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEIN_TIME ); } break; case TELEPORTER_STATE_RECEIVING_RELEASE: { CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get(); if ( pTeleportingPlayer ) { int iTeam = GetBuilder() ? GetBuilder()->GetTeamNumber() : GetTeamNumber(); pTeleportingPlayer->m_Shared.SetTeleporterEffectColor( iTeam ); pTeleportingPlayer->TeleportEffect(); pTeleportingPlayer->m_Shared.RemoveCond( TF_COND_SELECTED_TO_TELEPORT ); if ( !m_bWasMapPlaced && GetBuilder() ) CTF_GameStats.Event_PlayerUsedTeleport( GetBuilder(), pTeleportingPlayer ); IGameEvent * event = gameeventmanager->CreateEvent( "player_teleported" ); if ( event ) { event->SetInt( "userid", pTeleportingPlayer->GetUserID() ); if ( GetBuilder() ) event->SetInt( "builderid", GetBuilder()->GetUserID() ); Vector vecOrigin = GetAbsOrigin(); Vector vecDestinationOrigin = GetMatchingTeleporter()->GetAbsOrigin(); Vector vecDifference = Vector( vecOrigin.x - vecDestinationOrigin.x, vecOrigin.y - vecDestinationOrigin.y, vecOrigin.z - vecDestinationOrigin.z ); float flDist = sqrtf( pow( vecDifference.x, 2 ) + pow( vecDifference.y, 2 ) + pow( vecDifference.z, 2 ) ); event->SetFloat( "dist", flDist ); gameeventmanager->FireEvent( event, true ); } // Don't thank ourselves. if ( pTeleportingPlayer != GetBuilder() ) pTeleportingPlayer->SpeakConceptIfAllowed( MP_CONCEPT_TELEPORTED ); } // reset the pointers to the player now that we're done teleporting SetTeleportingPlayer( NULL ); pMatch->SetTeleportingPlayer( NULL ); SetState( TELEPORTER_STATE_RECHARGING ); m_flMyNextThink = gpGlobals->curtime + ( g_flTeleporterRechargeTimes[ GetUpgradeLevel() - 1 ] ); } break; case TELEPORTER_STATE_RECHARGING: // If we are finished recharging, go active if ( gpGlobals->curtime > m_flRechargeTime ) { SetState( TELEPORTER_STATE_READY ); EmitSound( "Building_Teleporter.Ready" ); } break; } }
//----------------------------------------------------------------------------- // Purpose: // Input : event - //----------------------------------------------------------------------------- void CTFPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) { Activity iGestureActivity = ACT_INVALID; switch( event ) { case PLAYERANIMEVENT_ATTACK_PRIMARY: { CTFPlayer *pPlayer = GetTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN ); bool bIsSniperRifle = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE ); // Heavy weapons primary fire. if ( bIsMinigun ) { // Play standing primary fire. iGestureActivity = ACT_MP_ATTACK_STAND_PRIMARYFIRE; if ( m_bInSwim ) { // Play swimming primary fire. iGestureActivity = ACT_MP_ATTACK_SWIM_PRIMARYFIRE; } else if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { // Play crouching primary fire. iGestureActivity = ACT_MP_ATTACK_CROUCH_PRIMARYFIRE; } if ( !IsGestureSlotPlaying( GESTURE_SLOT_ATTACK_AND_RELOAD, TranslateActivity(iGestureActivity) ) ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity ); } } else if ( bIsSniperRifle && pPlayer->m_Shared.InCond( TF_COND_ZOOMED ) ) { // Weapon primary fire, zoomed in if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE_DEPLOYED ); } else { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE_DEPLOYED ); } iGestureActivity = ACT_VM_PRIMARYATTACK; // Hold our deployed pose for a few seconds m_flHoldDeployedPoseUntilTime = gpGlobals->curtime + 2.0; } else { // Weapon primary fire. if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ); } else { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE ); } iGestureActivity = ACT_VM_PRIMARYATTACK; } break; } case PLAYERANIMEVENT_VOICE_COMMAND_GESTURE: { if ( !IsGestureSlotActive( GESTURE_SLOT_ATTACK_AND_RELOAD ) ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, (Activity)nData ); } break; } case PLAYERANIMEVENT_ATTACK_SECONDARY: { // Weapon secondary fire. if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_SECONDARYFIRE ); } else { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_SECONDARYFIRE ); } iGestureActivity = ACT_VM_PRIMARYATTACK; break; } case PLAYERANIMEVENT_ATTACK_PRE: { CTFPlayer *pPlayer = GetTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN ); bool bAutoKillPreFire = false; if ( bIsMinigun ) { bAutoKillPreFire = true; } if ( m_bInSwim && bIsMinigun ) { // Weapon pre-fire. Used for minigun windup while swimming iGestureActivity = ACT_MP_ATTACK_SWIM_PREFIRE; } else if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { // Weapon pre-fire. Used for minigun windup, sniper aiming start, etc in crouch. iGestureActivity = ACT_MP_ATTACK_CROUCH_PREFIRE; } else { // Weapon pre-fire. Used for minigun windup, sniper aiming start, etc. iGestureActivity = ACT_MP_ATTACK_STAND_PREFIRE; } RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity, bAutoKillPreFire ); break; } case PLAYERANIMEVENT_ATTACK_POST: { CTFPlayer *pPlayer = GetTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN ); if ( m_bInSwim && bIsMinigun ) { // Weapon pre-fire. Used for minigun winddown while swimming iGestureActivity = ACT_MP_ATTACK_SWIM_POSTFIRE; } else if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { // Weapon post-fire. Used for minigun winddown in crouch. iGestureActivity = ACT_MP_ATTACK_CROUCH_POSTFIRE; } else { // Weapon post-fire. Used for minigun winddown. iGestureActivity = ACT_MP_ATTACK_STAND_POSTFIRE; } RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity ); break; } case PLAYERANIMEVENT_RELOAD: { // Weapon reload. if ( m_bInAirWalk ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK ); } else { BaseClass::DoAnimationEvent( event, nData ); } break; } case PLAYERANIMEVENT_RELOAD_LOOP: { // Weapon reload. if ( m_bInAirWalk ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_LOOP ); } else { BaseClass::DoAnimationEvent( event, nData ); } break; } case PLAYERANIMEVENT_RELOAD_END: { // Weapon reload. if ( m_bInAirWalk ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_END ); } else { BaseClass::DoAnimationEvent( event, nData ); } break; } case PLAYERANIMEVENT_DOUBLEJUMP: { // Check to see if we are jumping! if ( !m_bJumping ) { m_bJumping = true; m_bFirstJumpFrame = true; m_flJumpStartTime = gpGlobals->curtime; RestartMainSequence(); } // Force the air walk off. m_bInAirWalk = false; // Player the air dash gesture. if (GetBasePlayer()->GetFlags() & FL_DUCKING) { RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_DOUBLEJUMP_CROUCH ); } else { RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_DOUBLEJUMP ); } break; } default: { BaseClass::DoAnimationEvent( event, nData ); break; } } #ifdef CLIENT_DLL // Make the weapon play the animation as well if (iGestureActivity != ACT_INVALID && GetBasePlayer() != C_BasePlayer::GetLocalPlayer()) { CBaseCombatWeapon *pWeapon = GetTFPlayer()->GetActiveWeapon(); if ( pWeapon ) { pWeapon->SendWeaponAnim( iGestureActivity ); pWeapon->DoAnimationEvents(pWeapon->GetModelPtr()); } } #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CWeaponSpawner::MyTouch(CBasePlayer *pPlayer) { bool bSuccess = false; CTFPlayer *pTFPlayer = dynamic_cast<CTFPlayer *>(pPlayer); if ( ValidTouch( pTFPlayer ) && pTFPlayer->IsPlayerClass( TF_CLASS_MERCENARY ) ) { #ifndef DM_WEAPON_BUCKET int iSlot = m_Item.GetStaticData()->GetLoadoutSlot( TF_CLASS_MERCENARY ); CTFWeaponBase *pWeapon = (CTFWeaponBase *)pTFPlayer->GetEntityForLoadoutSlot( iSlot ); const char *pszWeaponName = m_Item.GetEntityName(); int iAmmoType = m_pWeaponInfo->iAmmoType; if ( pWeapon ) { if ( pTFPlayer->ItemsMatch( pWeapon->GetItem(), &m_Item, pWeapon ) ) { if ( pTFPlayer->GiveAmmo( pWeapon->GetInitialAmmo(), iAmmoType, true, TF_AMMO_SOURCE_AMMOPACK ) ) bSuccess = true; } else if ( !(pTFPlayer->m_nButtons & IN_ATTACK) && (pTFPlayer->m_nButtons & IN_USE || pWeapon->GetWeaponID() == TF_WEAPON_PISTOL) ) { // Drop a usable weapon pTFPlayer->DropWeapon( pWeapon ); // Check Use button, always replace pistol if ( pWeapon == pTFPlayer->GetActiveTFWeapon() ) { pWeapon->Holster(); } pTFPlayer->Weapon_Detach( pWeapon ); UTIL_Remove( pWeapon ); pWeapon = NULL; } else { pTFPlayer->m_Shared.SetDesiredWeaponIndex( m_nItemID ); } } #else CTFWeaponBase *pWeapon = pTFPlayer->Weapon_OwnsThisID( m_nWeaponID ); const char *pszWeaponName = WeaponIdToClassname( m_nWeaponID ); if ( pWeapon ) { if ( pPlayer->GiveAmmo(999, m_pWeaponInfo->iAmmoType) ) bSuccess = true; } #endif if ( !pWeapon ) { CTFWeaponBase *pNewWeapon = (CTFWeaponBase *)pTFPlayer->GiveNamedItem( pszWeaponName, 0, &m_Item ); if ( pNewWeapon ) { pPlayer->SetAmmoCount( pNewWeapon->GetInitialAmmo(), iAmmoType ); pNewWeapon->DefaultTouch( pPlayer ); pTFPlayer->m_Shared.SetDesiredWeaponIndex( -1 ); bSuccess = true; } } if ( bSuccess ) { CSingleUserRecipientFilter user( pPlayer ); user.MakeReliable(); UserMessageBegin( user, "ItemPickup" ); WRITE_STRING( GetClassname() ); MessageEnd(); pPlayer->EmitSound( "BaseCombatCharacter.AmmoPickup" ); } } return bSuccess; }
//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void CObjectTeleporter::TeleporterThink( void ) { SetContextThink( &CObjectTeleporter::TeleporterThink, gpGlobals->curtime + BUILD_TELEPORTER_NEXT_THINK, TELEPORTER_THINK_CONTEXT ); // At any point, if our match is not ready, revert to IDLE if ( IsDisabled() || IsMatchingTeleporterReady() == false ) { if ( GetState() != TELEPORTER_STATE_IDLE ) { SetState( TELEPORTER_STATE_IDLE ); ShowDirectionArrow( false ); } return; } if ( m_flMyNextThink && m_flMyNextThink > gpGlobals->curtime ) return; // pMatch is not NULL and is not building CObjectTeleporter *pMatch = GetMatchingTeleporter(); Assert( pMatch ); Assert( pMatch->m_iState != TELEPORTER_STATE_BUILDING ); switch ( m_iState ) { // Teleporter is not yet active, do nothing case TELEPORTER_STATE_BUILDING: break; default: case TELEPORTER_STATE_IDLE: // Do we have a match that is active? if ( IsMatchingTeleporterReady() ) { SetState( TELEPORTER_STATE_READY ); EmitSound( "Building_Teleporter.Ready" ); if ( GetType() == OBJ_TELEPORTER_ENTRANCE ) { ShowDirectionArrow( true ); } } break; case TELEPORTER_STATE_READY: break; case TELEPORTER_STATE_SENDING: { pMatch->TeleporterReceive( m_hTeleportingPlayer, 1.0 ); m_flRechargeTime = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEOUT_TIME + BUILD_TELEPORTER_FADEIN_TIME + TELEPORTER_RECHARGE_TIME ); // change state to recharging... SetState( TELEPORTER_STATE_RECHARGING ); } break; case TELEPORTER_STATE_RECEIVING: { // get the position we'll move the player to Vector newPosition = GetAbsOrigin(); newPosition.z += TELEPORTER_MAXS.z + 1; // Telefrag anyone in the way CBaseEntity *pEnts[256]; Vector mins, maxs; Vector expand( 4, 4, 4 ); mins = newPosition + VEC_HULL_MIN - expand; maxs = newPosition + VEC_HULL_MAX + expand; CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get(); // move the player if ( pTeleportingPlayer ) { CUtlVector<CBaseEntity*> hPlayersToKill; bool bClear = true; // Telefrag any players in the way int numEnts = UTIL_EntitiesInBox( pEnts, 256, mins, maxs, 0 ); if ( numEnts ) { //Iterate through the list and check the results for ( int i = 0; i < numEnts && bClear; i++ ) { if ( pEnts[i] == NULL ) continue; if ( pEnts[i] == this ) continue; // kill players and NPCs if ( pEnts[i]->IsPlayer() || pEnts[i]->IsNPC() ) { if ( !pTeleportingPlayer->InSameTeam(pEnts[i]) ) { hPlayersToKill.AddToTail( pEnts[i] ); } continue; } if ( pEnts[i]->IsBaseObject() ) continue; // Solid entities will prevent a teleport if ( pEnts[i]->IsSolid() && pEnts[i]->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), MASK_ALL ) && g_pGameRules->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), pEnts[i]->GetCollisionGroup() ) ) { // We're going to teleport into something solid. Abort & destroy this exit. bClear = false; } } } if ( bClear ) { // Telefrag all enemy players we've found for ( int player = 0; player < hPlayersToKill.Count(); player++ ) { hPlayersToKill[player]->TakeDamage( CTakeDamageInfo( pTeleportingPlayer, this, 1000, DMG_CRUSH ) ); } pTeleportingPlayer->Teleport( &newPosition, &(GetAbsAngles()), &vec3_origin ); // Unzoom if we are a sniper zoomed! if ( ( pTeleportingPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_SNIPER ) && pTeleportingPlayer->m_Shared.InCond( TF_COND_AIMING ) ) { CTFWeaponBase *pWpn = pTeleportingPlayer->GetActiveTFWeapon(); if ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE ) { CTFSniperRifle *pRifle = static_cast<CTFSniperRifle*>( pWpn ); pRifle->ToggleZoom(); } } pTeleportingPlayer->SetFOV( pTeleportingPlayer, 0, tf_teleporter_fov_time.GetFloat(), tf_teleporter_fov_start.GetInt() ); color32 fadeColor = {255,255,255,100}; UTIL_ScreenFade( pTeleportingPlayer, fadeColor, 0.25, 0.4, FFADE_IN ); } else { DetonateObject(); } } SetState( TELEPORTER_STATE_RECEIVING_RELEASE ); m_flMyNextThink = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEIN_TIME ); } break; case TELEPORTER_STATE_RECEIVING_RELEASE: { CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get(); if ( pTeleportingPlayer ) { pTeleportingPlayer->TeleportEffect(); pTeleportingPlayer->m_Shared.RemoveCond( TF_COND_SELECTED_TO_TELEPORT ); CTF_GameStats.Event_PlayerUsedTeleport( GetBuilder(), pTeleportingPlayer ); pTeleportingPlayer->SpeakConceptIfAllowed( MP_CONCEPT_TELEPORTED ); } // reset the pointers to the player now that we're done teleporting SetTeleportingPlayer( NULL ); pMatch->SetTeleportingPlayer( NULL ); SetState( TELEPORTER_STATE_RECHARGING ); m_flMyNextThink = gpGlobals->curtime + ( TELEPORTER_RECHARGE_TIME ); } break; case TELEPORTER_STATE_RECHARGING: // If we are finished recharging, go active if ( gpGlobals->curtime > m_flRechargeTime ) { SetState( TELEPORTER_STATE_READY ); EmitSound( "Building_Teleporter.Ready" ); } break; } }