//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFForceRespawn::ForceRespawn( bool bSwitchTeams ) { int i = 0; // respawn the players for ( i = 1 ; i <= gpGlobals->maxClients ; i++ ) { CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( i ) ); if ( pPlayer ) { pPlayer->RemoveAllOwnedEntitiesFromWorld(); // Ignore players who aren't on an active team if ( pPlayer->GetTeamNumber() != TF_TEAM_RED && pPlayer->GetTeamNumber() != TF_TEAM_BLUE ) { // Let the player spawn immediately when they do pick a class pPlayer->AllowInstantSpawn(); continue; } if ( bSwitchTeams ) { if ( pPlayer->GetTeamNumber() == TF_TEAM_RED ) { pPlayer->ForceChangeTeam( TF_TEAM_BLUE ); } else if ( pPlayer->GetTeamNumber() == TF_TEAM_BLUE ) { pPlayer->ForceChangeTeam( TF_TEAM_RED ); } } // Ignore players who haven't picked a class yet if ( !pPlayer->GetPlayerClass() || pPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_UNDEFINED ) { // Allow them to spawn instantly when they do choose pPlayer->AllowInstantSpawn(); continue; } pPlayer->ForceRespawn(); } } // remove any dropped weapons/ammo packs CBaseEntity *pEnt = NULL; while ( (pEnt = gEntList.FindEntityByClassname( pEnt, "tf_ammo_pack" )) != NULL ) { UTIL_Remove( pEnt ); } // Output. m_outputOnForceRespawn.FireOutput( this, this ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CTFViewModel::GetSkin() { int nSkin = BaseClass::GetSkin(); CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon ) return nSkin; CTFPlayer *pPlayer = ToTFPlayer( GetOwner() ); if ( pPlayer ) { if ( pWeapon->GetTFWpnData().m_bHasTeamSkins_Viewmodel ) { switch( pPlayer->GetTeamNumber() ) { case TF_TEAM_RED: nSkin = 0; break; case TF_TEAM_BLUE: nSkin = 1; break; case TF_TEAM_GREEN: nSkin = 2; break; case TF_TEAM_YELLOW: nSkin = 3; break; } } } return nSkin; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudMenuSpyDisguise::FireGameEvent( IGameEvent *event ) { const char * type = event->GetName(); if ( Q_strcmp(type, "spy_pda_reset") == 0 ) { CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pPlayer ) { bool bShowBlue = ( pPlayer->GetTeamNumber() == TF_TEAM_RED ); for ( int i=0; i<9; i++ ) { m_pClassItems_Red[i]->SetVisible( !bShowBlue ); m_pClassItems_Blue[i]->SetVisible( bShowBlue ); } m_iShowingTeam = ( bShowBlue ) ? TF_TEAM_BLUE : TF_TEAM_RED; } } else { CHudElement::FireGameEvent( event ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CChangeClassZone::Touch( CBaseEntity *pOther ) { if ( !IsDisabled() ) { CTFPlayer *pPlayer = ToTFPlayer( pOther ); if ( pPlayer ) { if ( pPlayer->GetNextChangeClassTime() > gpGlobals->curtime ) return; int iTeam = GetTeamNumber(); if ( iTeam && ( pPlayer->GetTeamNumber() != iTeam ) ) return; // bring up the player's changeclass menu CCommand args; args.Tokenize( "changeclass" ); pPlayer->ClientCommand( args ); pPlayer->SetNextChangeClassTime( gpGlobals->curtime + TF_CHANGECLASS_NEXT_USE_TIME ); CPASAttenuationFilter filter( pOther, TF_CHANGECLASS_SOUND ); EmitSound( filter, pOther->entindex(), TF_CHANGECLASS_SOUND ); } } }
//----------------------------------------------------------------------------- // Purpose: Allow bots etc to use slightly different solid masks //----------------------------------------------------------------------------- unsigned int CTFGameMovement::PlayerSolidMask( bool brushOnly ) { unsigned int uMask = 0; if ( m_pTFPlayer ) { switch( m_pTFPlayer->GetTeamNumber() ) { case TF_TEAM_RED: uMask = CONTENTS_BLUETEAM | CONTENTS_GREENTEAM | CONTENTS_YELLOWTEAM; break; case TF_TEAM_BLUE: uMask = CONTENTS_REDTEAM | CONTENTS_GREENTEAM | CONTENTS_YELLOWTEAM; break; case TF_TEAM_GREEN: uMask = CONTENTS_REDTEAM | CONTENTS_BLUETEAM | CONTENTS_YELLOWTEAM; break; case TF_TEAM_YELLOW: uMask = CONTENTS_REDTEAM | CONTENTS_BLUETEAM | CONTENTS_GREENTEAM; break; } } return ( uMask | BaseClass::PlayerSolidMask( brushOnly ) ); }
//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void CObjectTeleporter::TeleporterTouch( CBaseEntity *pOther ) { if ( IsDisabled() ) { return; } // if it's not a player, ignore if ( !pOther->IsPlayer() ) return; CTFPlayer *pPlayer = ToTFPlayer( pOther ); CTFPlayer *pBuilder = GetBuilder(); Assert( pBuilder ); if ( !pBuilder ) { return; } // if its not a teammate of the builder, notify the builder if ( pBuilder->GetTeamNumber() != pOther->GetTeamNumber() ) { // Don't teleport enemies return; } // is this an entrance and do we have an exit? if ( GetType() == OBJ_TELEPORTER_ENTRANCE ) { if ( ( m_iState == TELEPORTER_STATE_READY ) ) { // are we able to teleport? if ( pPlayer->HasTheFlag() ) { // If they have the flag, print a warning that you can't tele with the flag CSingleUserRecipientFilter filter( pPlayer ); TFGameRules()->SendHudNotification( filter, HUD_NOTIFY_NO_TELE_WITH_FLAG ); return; } // get the velocity of the player touching the teleporter if ( pPlayer->GetAbsVelocity().Length() < 5.0 ) { CObjectTeleporter *pDest = GetMatchingTeleporter(); if ( pDest ) { TeleporterSend( pPlayer ); } } } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFFlameThrower::RestartParticleEffect( void ) { CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); if ( !pOwner ) return; if ( m_pFlameEffect && m_hFlameEffectHost.Get() ) { m_hFlameEffectHost->ParticleProp()->StopEmission( m_pFlameEffect ); } m_iParticleWaterLevel = pOwner->GetWaterLevel(); int iTeam = pOwner->GetTeamNumber(); // Start the appropriate particle effect const char *pszParticleEffect; if ( pOwner->GetWaterLevel() == WL_Eyes ) { pszParticleEffect = "flamethrower_underwater"; } else { if ( m_bCritFire ) { pszParticleEffect = ConstructTeamParticle( "flamethrower_crit_%s", iTeam, true ); } else { pszParticleEffect = iTeam == TF_TEAM_RED ? "flamethrower" : ConstructTeamParticle( "flamethrower_%s", pOwner->GetTeamNumber(), true ); } } // Start the effect on the viewmodel if our owner is the local player C_BaseEntity *pModel = GetWeaponForEffect(); if ( pModel ) { m_pFlameEffect = pModel->ParticleProp()->Create( pszParticleEffect, PATTACH_POINT_FOLLOW, "muzzle" ); m_hFlameEffectHost = pModel; } pOwner->m_Shared.SetParticleToMercColor( m_pFlameEffect ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWeaponBuilder::ItemPostFrame( void ) { CTFPlayer *pOwner = ToTFPlayer( GetOwner() ); if ( !pOwner ) return; // If we're building, and our team has lost, stop placing the object if ( m_hObjectBeingBuilt.Get() && TFGameRules()->State_Get() == GR_STATE_TEAM_WIN && pOwner->GetTeamNumber() != TFGameRules()->GetWinningTeam() ) { StopPlacement(); return; } // Check that I still have enough resources to build this item if ( pOwner->CanBuild( m_iObjectType ) != CB_CAN_BUILD ) { SwitchOwnersWeaponToLast(); } if (( pOwner->m_nButtons & IN_ATTACK ) && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { PrimaryAttack(); } if ( pOwner->m_nButtons & IN_ATTACK2 ) { if ( m_flNextSecondaryAttack <= gpGlobals->curtime ) { SecondaryAttack(); } } else { m_bInAttack2 = false; } WeaponIdle(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CTFViewModel::GetSkin() { int nSkin = BaseClass::GetSkin(); CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon ) return nSkin; CTFPlayer *pPlayer = ToTFPlayer( GetOwner() ); if ( pPlayer ) { if ( TFGameRules()->IsDeathmatch() ) { // Merc arms are team colored so use the colored skin for all weapons. nSkin = 4; } else if ( pWeapon->GetTFWpnData().m_bHasTeamSkins_Viewmodel ) { switch ( pPlayer->GetTeamNumber() ) { case TF_TEAM_RED: nSkin = 0; break; case TF_TEAM_BLUE: nSkin = 1; break; case TF_TEAM_GREEN: nSkin = 2; break; case TF_TEAM_YELLOW: nSkin = 3; break; } } } return nSkin; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CWeaponMedigun::AllowedToHealTarget( CBaseEntity *pTarget ) { CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); if ( !pOwner ) return false; CTFPlayer *pTFPlayer = ToTFPlayer( pTarget ); if ( !pTFPlayer ) return false; bool bStealthed = pTFPlayer->m_Shared.InCond( TF_COND_STEALTHED ); bool bDisguised = pTFPlayer->m_Shared.InCond( TF_COND_DISGUISED ); // We can heal teammates and enemies that are disguised as teammates if ( !bStealthed && ( pTFPlayer->InSameTeam( pOwner ) || ( bDisguised && pTFPlayer->m_Shared.GetDisguiseTeam() == pOwner->GetTeamNumber() ) ) ) { return true; } return false; }
// ----------------------------------------------------------------------------- // 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: //----------------------------------------------------------------------------- void CTFFreezePanel::FireGameEvent( IGameEvent * event ) { const char *pEventName = event->GetName(); if ( Q_strcmp( "player_death", pEventName ) == 0 ) { // see if the local player died int iPlayerIndexVictim = engine->GetPlayerForUserID( event->GetInt( "userid" ) ); C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pLocalPlayer && iPlayerIndexVictim == pLocalPlayer->entindex() ) { // the local player is dead, see if this is a new nemesis or a revenge if ( event->GetInt( "dominated" ) > 0 ) { m_iShowNemesisPanel = SHOW_NEW_NEMESIS; } else if ( event->GetInt( "revenge" ) > 0 ) { m_iShowNemesisPanel = SHOW_REVENGE; } else { m_iShowNemesisPanel = SHOW_NO_NEMESIS; } } } else if ( Q_strcmp( "hide_freezepanel", pEventName ) == 0 ) { Hide(); } else if ( Q_strcmp( "freezecam_started", pEventName ) == 0 ) { ShowCalloutsIn( 1.0 ); ShowSnapshotPanelIn( 1.25 ); } else if ( Q_strcmp( "teamplay_win_panel", pEventName ) == 0 ) { Hide(); } else if ( Q_strcmp( "show_freezepanel", pEventName ) == 0 ) { C_TF_PlayerResource *tf_PR = dynamic_cast<C_TF_PlayerResource *>(g_PR); if ( !tf_PR ) { m_pNemesisSubPanel->SetDialogVariable( "nemesisname", NULL ); return; } Show(); ShowSnapshotPanel( false ); m_bHoldingAfterScreenshot = false; if ( m_iBasePanelOriginalX > -1 && m_iBasePanelOriginalY > -1 ) { m_pBasePanel->SetPos( m_iBasePanelOriginalX, m_iBasePanelOriginalY ); } // Get the entity who killed us m_iKillerIndex = event->GetInt( "killer" ); C_BaseEntity *pKiller = ClientEntityList().GetBaseEntity( m_iKillerIndex ); int xp,yp; GetPos( xp, yp ); if ( TFGameRules()->RoundHasBeenWon() ) { SetPos( xp, m_iYBase - YRES(50) ); } else { SetPos( xp, m_iYBase ); } if ( pKiller ) { CTFPlayer *pPlayer = ToTFPlayer ( pKiller ); int iMaxBuffedHealth = 0; if ( pPlayer ) { iMaxBuffedHealth = pPlayer->m_Shared.GetMaxBuffedHealth(); } int iKillerHealth = pKiller->GetHealth(); if ( !pKiller->IsAlive() ) { iKillerHealth = 0; } m_pKillerHealth->SetHealth( iKillerHealth, pKiller->GetMaxHealth(), iMaxBuffedHealth ); if ( pKiller->IsPlayer() ) { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); // Set the BG according to the team they're on m_pFreezePanelBG->SetBGImage( pTFKiller->GetTeamNumber() ); //If this was just a regular kill but this guy is our nemesis then just show it. if ( pVictim && pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Nemesis_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Nemesis" ); } } else { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Killer_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Killer" ); } } m_pBasePanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_iKillerIndex ) ); if ( m_pAvatar ) { m_pAvatar->SetDefaultAvatar( GetDefaultAvatarImage( (C_BasePlayer*)pKiller ) ); m_pAvatar->SetPlayer( (C_BasePlayer*)pKiller ); m_pAvatar->SetShouldDrawFriendIcon( false ); } } else if ( pKiller->IsBaseObject() ) { C_BaseObject *pObj = assert_cast<C_BaseObject *>( pKiller ); C_TFPlayer *pOwner = pObj->GetOwner(); Assert( pOwner && "Why does this object not have an owner?" ); // Set the BG according to the team it's on m_pFreezePanelBG->SetBGImage( pObj->GetTeamNumber() ); if ( pOwner ) { m_iKillerIndex = pOwner->entindex(); m_pBasePanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_iKillerIndex ) ); if ( m_pAvatar ) { m_pAvatar->SetDefaultAvatar( GetDefaultAvatarImage( pOwner ) ); m_pAvatar->SetPlayer( pOwner ); m_pAvatar->SetShouldDrawFriendIcon( false ); } pKiller = pOwner; } if ( m_pFreezeLabel ) { if ( pKiller && !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_KillerObject_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_KillerObject" ); } } const char *pszStatusName = pObj->GetStatusName(); wchar_t *wszLocalized = g_pVGuiLocalize->Find( pszStatusName ); if ( !wszLocalized ) { m_pBasePanel->SetDialogVariable( "objectkiller", pszStatusName ); } else { m_pBasePanel->SetDialogVariable( "objectkiller", wszLocalized ); } } else if ( m_pFreezeLabel ) { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Killer_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Killer" ); } } } // see if we should show nemesis panel const wchar_t *pchNemesisText = NULL; switch ( m_iShowNemesisPanel ) { case SHOW_NO_NEMESIS: { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); //If this was just a regular kill but this guy is our nemesis then just show it. if ( pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { pchNemesisText = g_pVGuiLocalize->Find( "#TF_FreezeNemesis" ); } } break; case SHOW_NEW_NEMESIS: { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); // check to see if killer is still the nemesis of victim; victim may have managed to kill him after victim's // death by grenade or some such, extracting revenge and clearing nemesis condition if ( pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { pchNemesisText = g_pVGuiLocalize->Find( "#TF_NewNemesis" ); } } break; case SHOW_REVENGE: pchNemesisText = g_pVGuiLocalize->Find( "#TF_GotRevenge" ); break; default: Assert( false ); // invalid value break; } m_pNemesisSubPanel->SetDialogVariable( "nemesisname", pchNemesisText ); ShowNemesisPanel( NULL != pchNemesisText ); m_iShowNemesisPanel = SHOW_NO_NEMESIS; } }
void CTFBaseRocket::FlyThink( void ) { if ( gpGlobals->curtime > m_flCollideWithTeammatesTime && m_bCollideWithTeammates == false ) { m_bCollideWithTeammates = true; } if ( tf2c_homing_rockets.GetBool() || ( tf2c_homing_deflected_rockets.GetBool() && m_iDeflected ) ) { // Find the closest visible enemy player. CUtlVector<CTFPlayer *> vecPlayers; int count = CollectPlayers( &vecPlayers, TEAM_ANY, true ); float flClosest = FLT_MAX; Vector vecClosestTarget = vec3_origin; for ( int i = 0; i < count; i++ ) { CTFPlayer *pPlayer = vecPlayers[i]; if ( pPlayer == GetOwnerEntity() ) continue; if ( pPlayer->GetTeamNumber() == GetTeamNumber() && !TFGameRules()->IsDeathmatch() ) continue; Vector vecTarget; QAngle angTarget; if ( GetWeaponID() == TF_WEAPON_COMPOUND_BOW ) { int iBone = pPlayer->LookupBone( "bip_head" ); pPlayer->GetBonePosition( iBone, vecTarget, angTarget );; } else { vecTarget = pPlayer->EyePosition(); } if ( FVisible( vecTarget ) ) { float flDistSqr = ( vecTarget - GetAbsOrigin() ).LengthSqr(); if ( flDistSqr < flClosest ) { flClosest = flDistSqr; vecClosestTarget = vecTarget; } } } // Head towards him. if ( vecClosestTarget != vec3_origin ) { Vector vecTarget = vecClosestTarget; Vector vecDir = vecTarget - GetAbsOrigin(); VectorNormalize( vecDir ); float flSpeed = GetAbsVelocity().Length(); QAngle angForward; VectorAngles( vecDir, angForward ); SetAbsAngles( angForward ); SetAbsVelocity( vecDir * flSpeed ); } } SetNextThink( gpGlobals->curtime + 0.1f ); }