summaryrefslogtreecommitdiff
path: root/game/shared/tf/achievements_tf_scout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/tf/achievements_tf_scout.cpp')
-rw-r--r--game/shared/tf/achievements_tf_scout.cpp1732
1 files changed, 1732 insertions, 0 deletions
diff --git a/game/shared/tf/achievements_tf_scout.cpp b/game/shared/tf/achievements_tf_scout.cpp
new file mode 100644
index 0000000..b26a8fc
--- /dev/null
+++ b/game/shared/tf/achievements_tf_scout.cpp
@@ -0,0 +1,1732 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+
+#include "cbase.h"
+
+#ifdef CLIENT_DLL
+
+#include "achievementmgr.h"
+#include "baseachievement.h"
+#include "tf_hud_statpanel.h"
+#include "c_tf_team.h"
+#include "c_tf_player.h"
+#include "c_tf_playerresource.h"
+#include "tf_gamerules.h"
+#include "achievements_tf.h"
+#include "c_tf_objective_resource.h"
+#include "tf_weapon_shotgun.h"
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_FirstBlood : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for getting first blood.
+ if ( event->GetInt( "death_flags" ) & TF_DEATH_FIRST_BLOOD )
+ {
+ IncrementCount();
+ }
+ }
+
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_FirstBlood, ACHIEVEMENT_TF_SCOUT_FIRST_BLOOD, "TF_SCOUT_FIRST_BLOOD", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_FirstBloodKill : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 5 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ CTFPlayer *pAttackerPlayer = ToTFPlayer( pAttacker );
+
+ // Achievement for accumulating 5 kills over several matches with the first blood crit boost.
+ bool bFirstBlood = event->GetInt( "death_flags" ) & TF_DEATH_FIRST_BLOOD;
+ if ( pAttackerPlayer->m_Shared.IsFirstBloodBoosted() &&
+ pAttackerPlayer->m_Shared.InCond( TF_COND_CRITBOOSTED_FIRST_BLOOD ) &&
+ !bFirstBlood )
+ {
+ IncrementCount();
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_FirstBloodKill, ACHIEVEMENT_TF_SCOUT_FIRST_BLOOD_KILL, "TF_SCOUT_FIRST_BLOOD_KILL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_WellEarlyKill : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for getting a kill in cp_well during the setup phase.
+ if ( FStrEq( m_pAchievementMgr->GetMapName(), "cp_well" ) &&
+ TFGameRules() && (TFGameRules()->State_Get() == GR_STATE_RND_RUNNING) &&
+ TFGameRules()->InSetup() )
+ {
+ IncrementCount();
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_WellEarlyKill, ACHIEVEMENT_TF_SCOUT_WELL_EARLY_KILL, "TF_SCOUT_WELL_EARLY_KILL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_LifetimeKills : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 2004 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for getting 2004 lifetime kills!
+ IncrementCount();
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_LifetimeKills, ACHIEVEMENT_TF_SCOUT_LIFETIME_KILLS, "TF_SCOUT_LIFETIME_KILLS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_IronManKills : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+
+ ResetTracking();
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+
+ ResetTracking();
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ ResetTracking();
+ }
+ }
+
+ void ResetTracking()
+ {
+ m_bKillOnGround = false;
+ m_bKillInAir = false;
+ m_bKillInWater = false;
+
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for getting a kill while on the ground, in the air, and in the water in a single life.
+ CTFPlayer *pAttackerPlayer = ToTFPlayer( pAttacker );
+ if ( !pAttackerPlayer )
+ return;
+
+ if ( pAttackerPlayer->GetWaterLevel() == WL_Eyes )
+ {
+ m_bKillInWater = true;
+ }
+ else if ( !(pAttackerPlayer->GetFlags() & FL_ONGROUND) )
+ {
+ m_bKillInAir = true;
+ }
+ else
+ {
+ m_bKillOnGround = true;
+ }
+
+ if ( m_bKillOnGround && m_bKillInAir && m_bKillInWater )
+ {
+ IncrementCount();
+ }
+ }
+
+ bool m_bKillOnGround;
+ bool m_bKillInAir;
+ bool m_bKillInWater;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_IronManKills, ACHIEVEMENT_TF_SCOUT_IRON_MAN_KILLS, "TF_SCOUT_IRON_MAN_KILLS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DestroyTeleporters : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 3 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "object_destroyed" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "object_destroyed" ) == 0 )
+ {
+ int iIndex = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
+ CBaseEntity *pDestroyer = UTIL_PlayerByIndex( iIndex );
+ C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pDestroyer == pTFPlayer )
+ {
+ // Only count teleporters.
+ int iType = event->GetInt( "objecttype" );
+ if ( iType == OBJ_TELEPORTER )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DestroyTeleporters, ACHIEVEMENT_TF_SCOUT_DESTROY_TELEPORTERS, "TF_SCOUT_DESTROY_TELEPORTERS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DestroyBuildingsBeingBuilt : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 3 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "object_destroyed" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "object_destroyed" ) == 0 )
+ {
+ int iIndex = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
+ CBaseEntity *pDestroyer = UTIL_PlayerByIndex( iIndex );
+ C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pDestroyer == pTFPlayer )
+ {
+ // Only count buildings being built.
+ if ( event->GetBool( "was_building" ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DestroyBuildingsBeingBuilt, ACHIEVEMENT_TF_SCOUT_DESTROY_BUILDINGS_BEING_BUILT, "TF_SCOUT_DESTROY_BUILDINGS_BEING_BUILT", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DestroySentryWithPistol : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "object_destroyed" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "object_destroyed" ) == 0 )
+ {
+ int iIndex = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
+ CBaseEntity *pDestroyer = UTIL_PlayerByIndex( iIndex );
+ C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pDestroyer == pTFPlayer )
+ {
+ // Only count active sentries destroyed with a pistol.
+ int iType = event->GetInt( "objecttype" );
+ int iWeaponID = event->GetInt( "weaponid" );
+ if ( (iType == OBJ_SENTRYGUN) &&
+ (iWeaponID == TF_WEAPON_PISTOL_SCOUT) &&
+ !event->GetBool( "was_building" ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DestroySentryWithPistol, ACHIEVEMENT_TF_SCOUT_DESTROY_SENTRY_WITH_PISTOL, "TF_SCOUT_DESTROY_SENTRY_WITH_PISTOL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DoubleJumps : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1000 );
+ SetStoreProgressInSteam( true );
+
+ m_bScoredJump = false;
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "air_dash" );
+ ListenForGameEvent( "landed" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ // Achievement for getting 1000 double jumps.
+ if ( Q_strcmp( event->GetName(), "air_dash" ) == 0 )
+ {
+ int iJumperID = event->GetInt( "player" );
+ C_TFPlayer *pJumper = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( iJumperID ) ) );
+ if ( pJumper == C_TFPlayer::GetLocalTFPlayer() && !m_bScoredJump )
+ {
+ m_bScoredJump = true;
+ IncrementCount();
+ }
+ }
+ else if ( (Q_strcmp( event->GetName(), "landed" ) == 0) ||
+ (Q_strcmp( event->GetName(), "localplayer_respawn" ) == 0) ||
+ (Q_strcmp( event->GetName(), "teamplay_round_active" ) == 0) )
+ {
+ m_bScoredJump = false;
+ }
+ }
+
+private:
+ bool m_bScoredJump;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DoubleJumps, ACHIEVEMENT_TF_SCOUT_DOUBLE_JUMPS, "TF_SCOUT_DOUBLE_JUMPS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_AssistChargeMedic : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ m_bCharged = false;
+ m_iAssists = 0;
+ m_iMedic = -1;
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "player_chargedeployed" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "player_chargedeployed" ) == 0 )
+ {
+ m_iMedic = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
+ CBaseEntity *pMedic = UTIL_PlayerByIndex( m_iMedic );
+ int iTarget = engine->GetPlayerForUserID( event->GetInt( "targetid" ) );
+ CBaseEntity *pTarget = UTIL_PlayerByIndex( iTarget );
+
+ if ( pMedic && pTarget && pTarget == C_TFPlayer::GetLocalTFPlayer() )
+ {
+ m_bCharged = true;
+ m_iAssists = 0;
+ }
+ }
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
+ if ( iAssisterIndex > 0 && iAssisterIndex == m_iMedic )
+ {
+ C_TFPlayer *pMedic = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
+ if ( pMedic && pMedic->MedicIsReleasingCharge() )
+ {
+ m_iAssists++;
+ if ( m_iAssists >= 3 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+
+private:
+ bool m_bCharged;
+ int m_iAssists;
+ int m_iMedic;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_AssistChargeMedic, ACHIEVEMENT_TF_SCOUT_ASSIST_MEDIC, "TF_SCOUT_ASSIST_MEDIC", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StealSandwich : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ m_iHeavyID = -1;
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "player_stealsandvich" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ // If we died or respawned, reset...
+ m_iHeavyID = -1;
+ return;
+ }
+ else if ( Q_strcmp( event->GetName(), "player_stealsandvich" ) == 0 )
+ {
+ int iOwner = engine->GetPlayerForUserID( event->GetInt( "owner" ) );
+ if ( iOwner != m_iHeavyID )
+ return;
+
+ int iTarget = engine->GetPlayerForUserID( event->GetInt( "target" ) );
+ CBaseEntity *pTarget = UTIL_PlayerByIndex( iTarget );
+
+ if ( pTarget && pTarget == C_TFPlayer::GetLocalTFPlayer() )
+ {
+ IncrementCount();
+ }
+ }
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for killing a Heavy and taking his sandvich.
+ C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
+ {
+ // Track the heavy: we have to be responsible for his death.
+ m_iHeavyID = engine->GetPlayerForUserID( pTFVictim->GetUserID() );
+ }
+ }
+
+private:
+ int m_iHeavyID;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StealSandwich, ACHIEVEMENT_TF_SCOUT_STEAL_SANDWICH, "TF_SCOUT_STEAL_SANDWICH", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_KillChargedMedic : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+ // client fires an event for this achievement, no other code within achievement necessary
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_KillChargedMedic, ACHIEVEMENT_TF_SCOUT_KILL_CHARGED_MEDICS, "TF_SCOUT_KILL_CHARGED_MEDICS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_SurviveDamage : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "player_damaged" );
+ ListenForGameEvent( "teamplay_round_active" );
+ ListenForGameEvent( "localplayer_respawn" );
+ m_iDamageTotal = 0;
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "player_damaged" ) == 0 )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ m_iDamageTotal += event->GetInt( "amount" );
+
+ if ( pLocalPlayer && pLocalPlayer->IsAlive() && m_iDamageTotal >= 500 )
+ {
+ IncrementCount();
+ }
+ }
+ else if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
+ {
+ m_iDamageTotal = 0;
+ }
+ else if ( FStrEq( event->GetName(), "localplayer_respawn" ) )
+ {
+ m_iDamageTotal = 0;
+ }
+ }
+
+private:
+ int m_iDamageTotal;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_SurviveDamage, ACHIEVEMENT_TF_SCOUT_SURVIVE_DAMAGE, "TF_SCOUT_SURVIVE_DAMAGE", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_ThreeFlagCaptures : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "teamplay_flag_event" );
+ ListenForGameEvent( "teamplay_round_active" );
+ m_iFlagCaps = 0;
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "teamplay_flag_event" ) == 0 && event->GetInt( "eventtype" ) == TF_FLAGEVENT_CAPTURE )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pLocalPlayer && pLocalPlayer->entindex() == event->GetInt( "player" ))
+ {
+ m_iFlagCaps++;
+
+ if ( m_iFlagCaps >= 3 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ else if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
+ {
+ m_iFlagCaps = 0;
+ }
+ }
+
+private:
+ int m_iFlagCaps;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_ThreeFlagCaptures, ACHIEVEMENT_TF_SCOUT_THREE_FLAGCAPS, "TF_SCOUT_THREE_FLAGCAPS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DoubleJumpKill : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 20 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ C_TFPlayer *pKiller = ToTFPlayer( pAttacker );
+ int iDoubleJumpKill = pKiller->m_Shared.GetAirDash();
+
+ if ( iDoubleJumpKill > 0 )
+ {
+ IncrementCount();
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DoubleJumpKill, ACHIEVEMENT_TF_SCOUT_DOUBLEJUMP_KILL, "TF_SCOUT_DOUBLEJUMP_KILL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_FlagCapGrind : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 25 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "teamplay_flag_event" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ if ( Q_strcmp( event->GetName(), "teamplay_flag_event" ) == 0 && event->GetInt( "eventtype" ) == TF_FLAGEVENT_CAPTURE )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pLocalPlayer && pLocalPlayer->entindex() == event->GetInt( "player" ))
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_FlagCapGrind, ACHIEVEMENT_TF_SCOUT_FLAG_CAP_GRIND, "TF_SCOUT_FLAG_CAP_GRIND", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_DodgeDamage : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ m_iDamageDodged = 0;
+ }
+
+ virtual void ListenForEvents()
+ {
+ ListenForGameEvent( "player_damage_dodged" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ // If we died or respawned, reset...
+ m_iDamageDodged = 0;
+ return;
+ }
+ else if ( Q_strcmp( event->GetName(), "player_damage_dodged" ) == 0 )
+ {
+ m_iDamageDodged += event->GetInt( "damage" );
+
+ if ( m_iDamageDodged > 1000 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+
+private:
+ int m_iDamageDodged;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_DodgeDamage, ACHIEVEMENT_TF_SCOUT_DODGE_DAMAGE, "TF_SCOUT_DODGE_DAMAGE", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_KnockIntoTrain : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( !pTFVictim )
+ return;
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( CBasePlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( pTFVictim->m_Shared.GetWeaponKnockbackID() == pLocalPlayer->GetUserID() )
+ {
+ int custom = event->GetInt( "customkill" );
+ int damagebits = event->GetInt( "damagebits" );
+ if ( ( damagebits & DMG_VEHICLE ) || // They were hit by a freakin' train!
+ ( pAttacker && pAttacker->IsBrushModel() ) || // They were smashed by the world! Gah!
+ ( !pAttacker || (pAttacker == pVictim) ) || // He killed himself!
+ ( custom == TF_DMG_CUSTOM_SUICIDE ) ||
+ ( custom == TF_DMG_CUSTOM_TRIGGER_HURT ) ) // A trigger-hurt got him!
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_KnockIntoTrain, ACHIEVEMENT_TF_SCOUT_KNOCK_INTO_TRAIN, "TF_SCOUT_KNOCK_INTO_TRAIN", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_KillStunned : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
+ SetGoal( 50 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( !pTFVictim )
+ return;
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( pAttacker != pLocalPlayer )
+ {
+ int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
+ if ( iAssisterIndex <= 0 )
+ return;
+
+ CTFPlayer *pAssister = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
+ if ( pAssister != pLocalPlayer )
+ return;
+ }
+
+ int iStunFlags = event->GetInt( "stun_flags" );
+ if ( ((iStunFlags & TF_STUN_CONTROLS) != 0) || ((iStunFlags & TF_STUN_LOSER_STATE) != 0) )
+ {
+ IncrementCount();
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_KillStunned, ACHIEVEMENT_TF_SCOUT_KILL_STUNNED, "TF_SCOUT_KILL_STUNNED", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StunIntoTrain : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( !pTFVictim )
+ return;
+
+ // Achievement for causing someone we stunned to die by the environment.
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ int iStunFlags = event->GetInt( "stun_flags" );
+ bool bLegalStun = ((iStunFlags & TF_STUN_CONTROLS) != 0) || ((iStunFlags & TF_STUN_LOSER_STATE) != 0);
+ if ( bLegalStun && (pTFVictim->m_Shared.GetStunner() == pLocalPlayer) )
+ {
+ int custom = event->GetInt( "customkill" );
+ int damagebits = event->GetInt( "damagebits" );
+ if ( ( damagebits & DMG_VEHICLE ) || // They were hit by a freakin' train!
+ ( pAttacker && pAttacker->IsBrushModel() ) || // They were smashed by the world! Gah!
+ ( !pAttacker || (pAttacker == pVictim) ) || // He killed himself!
+ ( custom == TF_DMG_CUSTOM_SUICIDE ) ||
+ ( custom == TF_DMG_CUSTOM_TRIGGER_HURT ) ) // A trigger-hurt got him!
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StunIntoTrain, ACHIEVEMENT_TF_SCOUT_STUN_INTO_TRAIN, "TF_SCOUT_STUN_INTO_TRAIN", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StunUberEnemies : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 2 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "player_stunned" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "player_stunned" ) )
+ {
+ CTFPlayer *pStunner = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "stunner" ) ) ) );
+ CTFPlayer *pVictim = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "victim" ) ) ) );
+
+ if ( pStunner == pLocalPlayer )
+ {
+ if ( pVictim && pVictim->IsPlayerClass( TF_CLASS_MEDIC ) && pVictim->MedicGetChargeLevel() >= 1.0 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StunUberEnemies, ACHIEVEMENT_TF_SCOUT_STUN_UBER_ENEMIES, "TF_SCOUT_STUN_UBER_ENEMIES", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StunCappingEnemies : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 50 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "player_stunned" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "player_stunned" ) )
+ {
+ CTFPlayer *pStunner = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "stunner" ) ) ) );
+ CTFPlayer *pVictim = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "victim" ) ) ) );
+
+ if ( (pStunner == pLocalPlayer) &&
+ pVictim && event->GetBool( "victim_capping" ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StunCappingEnemies, ACHIEVEMENT_TF_SCOUT_STUN_CAPPING_ENEMIES, "TF_SCOUT_STUN_CAPPING_ENEMIES", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_MaxStuns : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "player_stunned" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "player_stunned" ) )
+ {
+ CTFPlayer *pStunner = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "stunner" ) ) ) );
+ CTFPlayer *pVictim = ToTFPlayer( UTIL_PlayerByIndex( engine->GetPlayerForUserID( event->GetInt( "victim" ) ) ) );
+
+ if ( (pStunner == pLocalPlayer) &&
+ pVictim && event->GetBool( "big_stun" ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_MaxStuns, ACHIEVEMENT_TF_SCOUT_MAX_STUNS, "TF_SCOUT_MAX_STUNS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StunScoutWithTheirBall : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+ // server awards this achievement, no other code within achievement necessary
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StunScoutWithTheirBall, ACHIEVEMENT_TF_SCOUT_STUN_SCOUT_WITH_THEIR_BALL, "TF_SCOUT_STUN_SCOUT_WITH_THEIR_BALL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_KillInDodgeCooldown : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 1 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for killing another scout under the effect Crit-a-Cola
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+
+ if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SCOUT ) && pTFVictim->m_Shared.InCond( TF_COND_ENERGY_BUFF ) )
+ {
+ IncrementCount();
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_KillInDodgeCooldown, ACHIEVEMENT_TF_SCOUT_KILL_IN_DODGE_COOLDOWN, "TF_SCOUT_KILL_IN_DODGE_COOLDOWN", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_KillFromBehind : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
+ SetGoal( 50 );
+ SetStoreProgressInSteam( true );
+ }
+
+ // Shamelessly stolen from the knife!
+ float DotProductToTarget( CBaseEntity *pAttacker, CBaseEntity *pTarget )
+ {
+ Assert( pTarget );
+
+ // Get the forward view vector of the target, ignore Z
+ Vector vecVictimForward;
+ AngleVectors( pTarget->EyeAngles(), &vecVictimForward, NULL, NULL );
+ vecVictimForward.z = 0.0f;
+ vecVictimForward.NormalizeInPlace();
+
+ // Get a vector from my origin to my targets origin
+ Vector vecToTarget;
+ vecToTarget = pTarget->WorldSpaceCenter() - pAttacker->WorldSpaceCenter();
+ vecToTarget.z = 0.0f;
+ vecToTarget.NormalizeInPlace();
+
+ return DotProduct( vecVictimForward, vecToTarget );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ // Achievement for killing a bunch of enemies from behind with the scattergun double.
+ if ( event->GetInt( "weaponid" ) == TF_WEAPON_SCATTERGUN )
+ {
+ CTFScatterGun *pScattergun = (CTFScatterGun *)ToTFPlayer( C_TFPlayer::GetLocalPlayer() )->Weapon_OwnsThisID( TF_WEAPON_SCATTERGUN );
+ if ( pScattergun && pScattergun->HasKnockback() &&
+ ( DotProductToTarget( pAttacker, pVictim ) > -0.1 ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_KillFromBehind, ACHIEVEMENT_TF_SCOUT_KILL_FROM_BEHIND, "TF_SCOUT_KILL_FROM_BEHIND", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_CaptureLastPoint : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+
+ m_bRecentCapper = false;
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_point_captured" );
+ ListenForGameEvent( "teamplay_round_win" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "teamplay_point_captured" ) )
+ {
+ m_bRecentCapper = false;
+ int iTeam = event->GetInt( "team" );
+ if ( iTeam == pLocalPlayer->GetTeamNumber() )
+ {
+ const char *cappers = event->GetString( "cappers" );
+ for ( int i=0; i<Q_strlen( cappers ); i++ )
+ {
+ int iPlayerIndex = (int) cappers[i];
+ CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayerIndex ) );
+ if ( pPlayer == pLocalPlayer )
+ {
+ m_bRecentCapper = true;
+ }
+ }
+ }
+ }
+ else if ( FStrEq( pszEventName, "teamplay_round_win" ) )
+ {
+ // If we're the winners and we were involved in capping the last point, we get this achievement.
+ int iTeam = event->GetInt( "team" );
+ if ( (iTeam == pLocalPlayer->GetTeamNumber()) &&
+ m_bRecentCapper &&
+ (TFGameRules()->GetGameType() == TF_GAMETYPE_CP) )
+ {
+ IncrementCount();
+ }
+ m_bRecentCapper = false;
+ }
+ }
+
+ bool m_bRecentCapper;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_CaptureLastPoint, ACHIEVEMENT_TF_SCOUT_CAPTURE_LAST_POINT, "TF_SCOUT_CAPTURE_LAST_POINT", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_CaptureThreePoints : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+
+ m_iPointsCapped = 0;
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_point_captured" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ // only on maps with capture points
+ if ( TFGameRules() && TFGameRules()->GetGameType() != TF_GAMETYPE_CP && TFGameRules()->GetGameType() != TF_GAMETYPE_ARENA )
+ return;
+
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active") )
+ {
+ m_iPointsCapped = 0;
+ }
+ else if ( FStrEq( pszEventName, "teamplay_point_captured" ) )
+ {
+ int iTeam = event->GetInt( "team" );
+ if ( iTeam == pLocalPlayer->GetTeamNumber() )
+ {
+ const char *cappers = event->GetString( "cappers" );
+ for ( int i=0; i<Q_strlen( cappers ); i++ )
+ {
+ int iPlayerIndex = (int) cappers[i];
+ CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayerIndex ) );
+ if ( pPlayer == pLocalPlayer )
+ {
+ m_iPointsCapped++;
+ }
+ }
+ }
+
+ if ( m_iPointsCapped == 3 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+
+ int m_iPointsCapped;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_CaptureThreePoints, ACHIEVEMENT_TF_SCOUT_CAPTURE_THREE_POINTS, "TF_SCOUT_CAPTURE_THREE_POINTS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_FastCap : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_point_startcapture" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ // only on maps with capture points
+ if ( TFGameRules() && TFGameRules()->GetGameType() != TF_GAMETYPE_CP && TFGameRules()->GetGameType() != TF_GAMETYPE_ARENA )
+ return;
+
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ if ( FStrEq( pszEventName, "teamplay_point_startcapture" ) )
+ {
+ const char *cappers = event->GetString( "cappers" );
+ for ( int i=0; i<Q_strlen( cappers ); i++ )
+ {
+ int iPlayerIndex = (int) cappers[i];
+ CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayerIndex ) );
+ if ( pPlayer == pLocalPlayer )
+ {
+ if ( event->GetFloat( "captime" ) < 1.0 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_FastCap, ACHIEVEMENT_TF_SCOUT_FAST_CAP, "TF_SCOUT_FAST_CAP", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_StartAndFinishCap : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 10 );
+ SetStoreProgressInSteam( true );
+
+ m_Points.Purge();
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_point_startcapture" );
+ ListenForGameEvent( "teamplay_point_captured" );
+ ListenForGameEvent( "teamplay_capture_broken" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ // Achievement for initiating captures that ultimately succeed.
+ if ( FStrEq( pszEventName, "teamplay_point_startcapture" ) )
+ {
+ const char *cappers = event->GetString( "cappers" );
+ for ( int i=0; i<Q_strlen( cappers ); i++ )
+ {
+ int iPlayerIndex = (int) cappers[i];
+ CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayerIndex ) );
+ if ( pPlayer == pLocalPlayer ) // Are we one of the cappers?
+ {
+ // We started capping this point.
+ m_Points.AddToTail( event->GetInt( "cp" ) );
+ }
+ }
+ }
+ else if ( FStrEq( pszEventName, "teamplay_point_captured" ) )
+ {
+ int iIndex = m_Points.Find( event->GetInt( "cp" ) );
+ if ( iIndex > -1 ) // Is the point one we started capping?
+ {
+ int iTeam = event->GetInt( "team" );
+ if ( iTeam == pLocalPlayer->GetTeamNumber() )
+ {
+ m_Points.Remove( iIndex );
+ IncrementCount();
+ }
+ }
+ }
+ else if ( FStrEq( pszEventName, "teamplay_capture_broken" ) )
+ {
+ // Our team failed to complete the capture.
+ int iIndex = m_Points.Find( event->GetInt( "cp" ) );
+ if ( iIndex > -1 )
+ {
+ m_Points.Remove( iIndex );
+ }
+ }
+ else if ( FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ // Reset tracking at the start of a new round.
+ m_Points.Purge();
+ }
+ }
+
+ CUtlVector< int > m_Points;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_StartAndFinishCap, ACHIEVEMENT_TF_SCOUT_START_AND_FINISH_CAP, "TF_SCOUT_START_AND_FINISH_CAP", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_BlockCaps : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 50 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_capture_blocked" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ // Achievement for blocking captures!
+ if ( FStrEq( pszEventName, "teamplay_capture_blocked" ) )
+ {
+ int iBlocker = event->GetInt( "blocker" );
+ if ( (iBlocker == pLocalPlayer->entindex()) &&
+ ((TFGameRules()->GetGameType() == TF_GAMETYPE_CP) ||
+ (TFGameRules()->GetGameType() == TF_GAMETYPE_ARENA)) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_BlockCaps, ACHIEVEMENT_TF_SCOUT_BLOCK_CAPS, "TF_SCOUT_BLOCK_CAPS", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_CarrierKillCarrier : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_flag_event" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ // Achievement for blocking captures!
+ if ( FStrEq( pszEventName, "teamplay_flag_event" ) )
+ {
+ int iType = event->GetInt( "eventtype" );
+ if ( iType == TF_FLAGEVENT_DEFEND )
+ {
+ int iPlayer = event->GetInt( "player" );
+ if ( (iPlayer == pLocalPlayer->entindex()) && pLocalPlayer->HasTheFlag() )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_CarrierKillCarrier, ACHIEVEMENT_TF_SCOUT_CARRIER_KILL_CARRIER, "TF_SCOUT_CARRIER_KILL_CARRIER", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_CapFlagWithoutAttacking : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "teamplay_flag_event" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ // Achievement for capping the flag without shooting anyone.
+ if ( FStrEq( pszEventName, "teamplay_flag_event" ) )
+ {
+ int iType = event->GetInt( "eventtype" );
+ if ( iType == TF_FLAGEVENT_CAPTURE )
+ {
+ int iPlayer = event->GetInt( "player" );
+ if ( (iPlayer == pLocalPlayer->entindex()) && !pLocalPlayer->HasFiredWeapon() )
+ {
+ IncrementCount();
+ }
+ }
+ else if ( iType == TF_FLAGEVENT_PICKUP )
+ {
+ int iPlayer = event->GetInt( "player" );
+ if ( iPlayer == pLocalPlayer->entindex() )
+ {
+ pLocalPlayer->SetFiredWeapon( false );
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_CapFlagWithoutAttacking, ACHIEVEMENT_TF_SCOUT_CAP_FLAG_WITHOUT_ATTACKING, "TF_SCOUT_CAP_FLAG_WITHOUT_ATTACKING", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_LongDistanceRunner : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 25000 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "player_death" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ // Achievement for running ...
+ bool bUpdate = false;
+ if ( FStrEq( pszEventName, "player_death" ) )
+ {
+ int iVictimID = event->GetInt( "userid" );
+ if ( pLocalPlayer && (iVictimID == pLocalPlayer->GetUserID()) )
+ {
+ bUpdate = true;
+ }
+ }
+ else if ( FStrEq( pszEventName, "teamplay_round_win" ) )
+ {
+ bUpdate = true;
+ }
+
+ if ( bUpdate )
+ {
+ float fMeters = pLocalPlayer->GetMetersRan();
+ IncrementCount( ceil( fMeters ) );
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_LongDistanceRunner, ACHIEVEMENT_TF_SCOUT_LONG_DISTANCE_RUNNER, "TF_SCOUT_LONG_DISTANCE_RUNNER", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_TauntKill : public CBaseTFAchievement
+{
+ void Init()
+ {
+ SetFlags( ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+
+ m_iTargetID = 0;
+ m_vSlamOrigin = Vector(0,0,0);
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "scout_grand_slam" );
+ ListenForGameEvent( "scout_slamdoll_landed" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ CTFPlayer *pLocalPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( !pLocalPlayer )
+ return;
+
+ const char *pszEventName = event->GetName();
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ // If we died or respawned, reset...
+ m_iTargetID = 0;
+ m_vSlamOrigin = Vector(0,0,0);
+ return;
+ }
+ else if ( FStrEq( pszEventName, "scout_grand_slam" ) )
+ {
+ int iScoutID = event->GetInt( "scout_id" );
+ if ( pLocalPlayer && (iScoutID == pLocalPlayer->GetUserID()) )
+ {
+ m_iTargetID = event->GetInt( "target_id" ); // target_id is a userid
+ int iTarget = engine->GetPlayerForUserID( m_iTargetID );
+ CBaseEntity *pTarget = UTIL_PlayerByIndex( iTarget );
+ if ( pTarget )
+ {
+ m_vSlamOrigin = pTarget->GetAbsOrigin();
+ }
+ }
+ }
+ else if ( FStrEq( pszEventName, "scout_slamdoll_landed" ) )
+ {
+ int iTargetIndex = event->GetInt( "target_index" ); // target_index is an entindex
+ EHANDLE hPlayer = cl_entitylist->GetNetworkableHandle( iTargetIndex );
+ if ( !hPlayer )
+ return;
+ C_TFPlayer *pPlayer = dynamic_cast< C_TFPlayer* >( hPlayer.Get() );
+ if ( pPlayer && (m_iTargetID == pPlayer->GetUserID()) &&
+ (m_vSlamOrigin != Vector(0,0,0)) )
+ {
+ float x = event->GetFloat( "x" );
+ float y = event->GetFloat( "y" );
+ float z = event->GetFloat( "z" );
+ Vector vHitOrigin = Vector(x,y,z);
+ float fDist = (vHitOrigin - m_vSlamOrigin).Length();
+ if ( fDist > 1000 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+
+ int m_iTargetID;
+ Vector m_vSlamOrigin;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_TauntKill, ACHIEVEMENT_TF_SCOUT_TAUNT_KILL, "TF_SCOUT_TAUNT_KILL", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_AchieveProgress1 : public CAchievement_AchievedCount
+{
+public:
+ DECLARE_CLASS( CAchievementTFScout_AchieveProgress1, CAchievement_AchievedCount );
+ void Init()
+ {
+ BaseClass::Init();
+ SetAchievementsRequired( 10, ACHIEVEMENT_TF_SCOUT_START_RANGE, ACHIEVEMENT_TF_SCOUT_END_RANGE );
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_AchieveProgress1, ACHIEVEMENT_TF_SCOUT_ACHIEVE_PROGRESS1, "TF_SCOUT_ACHIEVE_PROGRESS1", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_AchieveProgress2 : public CAchievement_AchievedCount
+{
+public:
+ DECLARE_CLASS( CAchievementTFScout_AchieveProgress2, CAchievement_AchievedCount );
+ void Init()
+ {
+ BaseClass::Init();
+ SetAchievementsRequired( 16, ACHIEVEMENT_TF_SCOUT_START_RANGE, ACHIEVEMENT_TF_SCOUT_END_RANGE );
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_AchieveProgress2, ACHIEVEMENT_TF_SCOUT_ACHIEVE_PROGRESS2, "TF_SCOUT_ACHIEVE_PROGRESS2", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_AchieveProgress3 : public CAchievement_AchievedCount
+{
+public:
+ DECLARE_CLASS( CAchievementTFScout_AchieveProgress3, CAchievement_AchievedCount );
+ void Init()
+ {
+ BaseClass::Init();
+ SetAchievementsRequired( 22, ACHIEVEMENT_TF_SCOUT_START_RANGE, ACHIEVEMENT_TF_SCOUT_END_RANGE );
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_AchieveProgress3, ACHIEVEMENT_TF_SCOUT_ACHIEVE_PROGRESS3, "TF_SCOUT_ACHIEVE_PROGRESS3", 5 );
+
+// Receive the DamageDodged user message and send out a clientside event for achievements to hook.
+void __MsgFunc_DamageDodged( bf_read &msg )
+{
+ int iDamage = msg.ReadShort();
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "player_damage_dodged" );
+ if ( event )
+ {
+ event->SetInt( "damage", iDamage );
+ gameeventmanager->FireEventClientSide( event );
+ }
+}
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_BackscatterKillSpyGrind : public CBaseTFAchievement
+{
+public:
+ void Init()
+ {
+ SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
+ SetGoal( 20 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ if ( pVictim && ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) )
+ {
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SPY ) )
+ {
+ if ( ( event->GetInt( "weaponid" ) == TF_WEAPON_SCATTERGUN ) && ( event->GetInt( "damagebits" ) & DMG_CRITICAL ) )
+ {
+ CTFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
+ if ( pTFAttacker )
+ {
+ CTFWeaponBase *pWeapon = pTFAttacker->GetActiveTFWeapon();
+ if ( pWeapon )
+ {
+ int iMiniCritBackAttack = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, iMiniCritBackAttack, closerange_backattack_minicrits );
+ if ( iMiniCritBackAttack > 0 )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_BackscatterKillSpyGrind, ACHIEVEMENT_TF_SCOUT_BACKSCATTER_KILL_SPY_GRIND, "TF_SCOUT_BACKSCATTER_KILL_SPY_GRIND", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_BackscatterKillHeavyMedicPair : public CBaseTFAchievement
+{
+public:
+ void Init()
+ {
+ SetFlags( ACH_LISTEN_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
+ SetGoal( 1 );
+ }
+
+ virtual void ListenForEvents( void )
+ {
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "teamplay_round_active" );
+
+ m_hTargets.Purge();
+ }
+
+ void FireGameEvent_Internal( IGameEvent *event )
+ {
+ const char *pszEventName = event->GetName();
+
+ if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
+ FStrEq( pszEventName, "teamplay_round_active" ) )
+ {
+ m_hTargets.Purge();
+ }
+ }
+
+ int GetTargetIndex( CBaseEntity *pTarget )
+ {
+ for ( int i = 0; i < m_hTargets.Count(); i++ )
+ {
+ if ( m_hTargets[i].hTarget == pTarget )
+ return i;
+ }
+ return -1;
+ }
+
+ void AddNewTarget( CBaseEntity *pTarget )
+ {
+ if ( !pTarget )
+ return;
+
+ // see if the target is already in our list or get a new index
+ int iTargetIndex = GetTargetIndex( pTarget );
+ if ( iTargetIndex == -1 )
+ {
+ iTargetIndex = m_hTargets.AddToTail();
+ }
+
+ m_hTargets[iTargetIndex].hTarget = pTarget;
+ m_hTargets[iTargetIndex].flTimeToBeat = gpGlobals->curtime + 20.0f; // 20 seconds to kill the target
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ if ( pVictim && ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) )
+ {
+ if ( event->GetInt( "weaponid" ) == TF_WEAPON_SCATTERGUN )
+ {
+ CTFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
+ if ( pTFAttacker )
+ {
+ CTFWeaponBase *pWeapon = pTFAttacker->GetActiveTFWeapon();
+ if ( pWeapon )
+ {
+ int iMiniCritBackAttack = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, iMiniCritBackAttack, closerange_backattack_minicrits );
+ if ( iMiniCritBackAttack > 0 )
+ {
+ // is this victim in our list of targets?
+ int index = GetTargetIndex( pVictim );
+ if ( index != -1 )
+ {
+ // did we beat the time?
+ if ( m_hTargets[index].flTimeToBeat > gpGlobals->curtime )
+ {
+ IncrementCount();
+ }
+ }
+ else
+ {
+ CTFPlayer *pNewTarget = NULL;
+ CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
+ if ( pTFVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
+ {
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ pNewTarget = ToTFPlayer( UTIL_PlayerByIndex( i ) );
+ if ( pNewTarget && pNewTarget->IsPlayerClass( TF_CLASS_MEDIC ) && ( pNewTarget->MedicGetHealTarget() == pTFVictim ) )
+ {
+ // add all of his Medics to our list of targets (could be more than one Medic)
+ AddNewTarget( pNewTarget );
+ }
+ }
+ }
+ else if ( pTFVictim->IsPlayerClass( TF_CLASS_MEDIC ) )
+ {
+ pNewTarget = ToTFPlayer( pTFVictim->MedicGetHealTarget() );
+ if ( pNewTarget && ( pNewTarget->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) ) )
+ {
+ AddNewTarget( pNewTarget );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // is this victim in our list of targets?
+ int index = GetTargetIndex( pVictim );
+ if ( index != -1 )
+ {
+ m_hTargets.Remove( index );
+ }
+ }
+
+private:
+ struct targets_t
+ {
+ EHANDLE hTarget;
+ float flTimeToBeat;
+ };
+
+ CUtlVector<targets_t> m_hTargets;
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_BackscatterKillHeavyMedicPair, ACHIEVEMENT_TF_SCOUT_BACKSCATTER_KILL_HEAVY_MEDIC_PAIR, "TF_SCOUT_BACKSCATTER_KILL_HEAVY_MEDIC_PAIR", 5 );
+
+//----------------------------------------------------------------------------------------------------------------
+class CAchievementTFScout_BackscatterKillFriendsGrind : public CBaseTFAchievement
+{
+public:
+ void Init()
+ {
+ SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
+ SetGoal( 20 );
+ SetStoreProgressInSteam( true );
+ }
+
+ virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
+ {
+ if ( pVictim && ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) )
+ {
+ if ( ( event->GetInt( "weaponid" ) == TF_WEAPON_SCATTERGUN ) && ( event->GetInt( "damagebits" ) & DMG_CRITICAL ) )
+ {
+ CTFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
+ if ( pTFAttacker )
+ {
+ CTFWeaponBase *pWeapon = pTFAttacker->GetActiveTFWeapon();
+ if ( pWeapon )
+ {
+ int iMiniCritBackAttack = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, iMiniCritBackAttack, closerange_backattack_minicrits );
+ if ( iMiniCritBackAttack > 0 )
+ {
+ if ( !steamapicontext->SteamFriends() || !steamapicontext->SteamUtils() || !g_pGameRules->IsMultiplayer() )
+ return;
+
+ player_info_t pi;
+ if ( !engine->GetPlayerInfo( pVictim->entindex(), &pi ) )
+ return;
+
+ if ( !pi.friendsID )
+ return;
+
+ // check and see if they're on the local player's friends list
+ CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
+ if ( steamapicontext->SteamFriends()->HasFriend( steamID, k_EFriendFlagImmediate ) )
+ {
+ IncrementCount();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+};
+DECLARE_ACHIEVEMENT( CAchievementTFScout_BackscatterKillFriendsGrind, ACHIEVEMENT_TF_SCOUT_BACKSCATTER_KILL_FRIENDS_GRIND, "TF_SCOUT_BACKSCATTER_KILL_FRIENDS_GRIND", 5 );
+
+#endif // CLIENT_DLL
+
+
+