Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1448 lines
44 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #ifdef CLIENT_DLL
  8. #include "achievementmgr.h"
  9. #include "baseachievement.h"
  10. #include "tf_hud_statpanel.h"
  11. #include "c_tf_team.h"
  12. #include "c_tf_player.h"
  13. #include "c_tf_playerresource.h"
  14. #include "tf_gamerules.h"
  15. #include "achievements_tf.h"
  16. #include "c_tf_objective_resource.h"
  17. //======================================================================================================================================
  18. // SNIPER ACHIEVEMENT PACK
  19. //======================================================================================================================================
  20. //----------------------------------------------------------------------------------------------------------------
  21. class CAchievementTFSniper_JarateDominated : public CBaseTFAchievement
  22. {
  23. void Init()
  24. {
  25. SetFlags( ACH_SAVE_GLOBAL );
  26. SetGoal( 1 );
  27. }
  28. // Jarate an enemy that you're dominating
  29. virtual void ListenForEvents( void )
  30. {
  31. ListenForGameEvent( "player_jarated" );
  32. }
  33. void FireGameEvent_Internal( IGameEvent *event )
  34. {
  35. if ( FStrEq( event->GetName(), "player_jarated" ) )
  36. {
  37. CTFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  38. if ( !pLocalPlayer )
  39. return;
  40. int iVictim = event->GetInt( "victim_entindex" );
  41. if ( pLocalPlayer->m_Shared.IsPlayerDominated(iVictim) )
  42. {
  43. IncrementCount();
  44. }
  45. }
  46. }
  47. };
  48. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateDominated, ACHIEVEMENT_TF_SNIPER_JARATE_DOMINATED, "TF_SNIPER_JARATE_DOMINATED", 5 );
  49. //----------------------------------------------------------------------------------------------------------------
  50. //Capture the flag as a sniper.
  51. //----------------------------------------------------------------------------------------------------------------
  52. class CAchievementTFSniper_CaptureTheFlag : public CBaseTFAchievement
  53. {
  54. void Init()
  55. {
  56. SetFlags( ACH_SAVE_GLOBAL );
  57. SetGoal( 1 );
  58. }
  59. virtual void ListenForEvents( void )
  60. {
  61. ListenForGameEvent( "teamplay_flag_event" );
  62. }
  63. void FireGameEvent_Internal( IGameEvent *event )
  64. {
  65. if ( FStrEq( event->GetName(), "teamplay_flag_event" ) )
  66. {
  67. int iCapper = event->GetInt( "player" );
  68. int iType = event->GetInt( "eventtype" );
  69. if ( iCapper == GetLocalPlayerIndex() && iType == TF_FLAGEVENT_CAPTURE )
  70. {
  71. IncrementCount();
  72. }
  73. }
  74. }
  75. };
  76. DECLARE_ACHIEVEMENT( CAchievementTFSniper_CaptureTheFlag, ACHIEVEMENT_TF_SNIPER_CAPTURE_FLAG, "TF_SNIPER_CAPTURE_FLAG", 5 );
  77. //----------------------------------------------------------------------------------------------------------------
  78. //Kill an invisible spy.
  79. //----------------------------------------------------------------------------------------------------------------
  80. class CAchievementTFSniper_InvisibleSpyKill : public CBaseTFAchievement
  81. {
  82. void Init()
  83. {
  84. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  85. SetGoal( 1 );
  86. }
  87. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  88. {
  89. if ( !pVictim || !pVictim->IsPlayer() )
  90. return;
  91. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  92. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SPY ) && pTFVictim->m_Shared.InCond( TF_COND_STEALTHED ) )
  93. {
  94. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  95. {
  96. if ( pTFVictim->GetPercentInvisible() == 1.0f )
  97. {
  98. IncrementCount();
  99. }
  100. }
  101. }
  102. }
  103. };
  104. DECLARE_ACHIEVEMENT( CAchievementTFSniper_InvisibleSpyKill, ACHIEVEMENT_TF_SNIPER_KILL_INVIS_SPY, "TF_SNIPER_KILL_INVIS_SPY", 5 );
  105. //----------------------------------------------------------------------------------------------------------------
  106. //Headshot X enemy snipers
  107. //----------------------------------------------------------------------------------------------------------------
  108. class CAchievementTFSniper_HeadShotSnipers: public CBaseTFAchievement
  109. {
  110. void Init()
  111. {
  112. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  113. SetGoal( 10 );
  114. SetStoreProgressInSteam( true );
  115. }
  116. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  117. {
  118. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  119. if ( pTFVictim && ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) && ( IsHeadshot( event->GetInt( "customkill" ) ) ) && pTFVictim->IsPlayerClass( TF_CLASS_SNIPER ) )
  120. {
  121. IncrementCount();
  122. }
  123. }
  124. };
  125. DECLARE_ACHIEVEMENT( CAchievementTFSniper_HeadShotSnipers, ACHIEVEMENT_TF_SNIPER_HEADSHOT_SNIPERS, "TF_SNIPER_HEADSHOT_SNIPERS", 5 );
  126. //----------------------------------------------------------------------------------------------------------------
  127. //Headshot an enemy demoman
  128. //----------------------------------------------------------------------------------------------------------------
  129. class CAchievementTFSniper_HeadShotDemoman: public CBaseTFAchievement
  130. {
  131. void Init()
  132. {
  133. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  134. SetGoal( 1 );
  135. }
  136. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  137. {
  138. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  139. if ( pTFVictim && ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) && ( IsHeadshot( event->GetInt( "customkill" ) ) ) && pTFVictim->IsPlayerClass( TF_CLASS_DEMOMAN ) )
  140. {
  141. IncrementCount();
  142. }
  143. }
  144. };
  145. DECLARE_ACHIEVEMENT( CAchievementTFSniper_HeadShotDemoman, ACHIEVEMENT_TF_SNIPER_HEADSHOT_DEMOMAN, "TF_SNIPER_HEADSHOT_DEMOMAN", 5 );
  146. //----------------------------------------------------------------------------------------------------------------
  147. //Kill X spies with the kukri
  148. //----------------------------------------------------------------------------------------------------------------
  149. class CAchievementTFSniper_SpyKukriKills: public CBaseTFAchievement
  150. {
  151. void Init()
  152. {
  153. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  154. SetGoal( 10 );
  155. SetStoreProgressInSteam( true );
  156. }
  157. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  158. {
  159. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  160. if ( pAttacker == pLocalPlayer )
  161. {
  162. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  163. if ( pTFVictim && pTFVictim->IsPlayerClass(TF_CLASS_SPY) && event->GetInt( "weaponid" ) == TF_WEAPON_CLUB )
  164. {
  165. IncrementCount();
  166. }
  167. }
  168. }
  169. };
  170. DECLARE_ACHIEVEMENT( CAchievementTFSniper_SpyKukriKills, ACHIEVEMENT_TF_SNIPER_KILL_SPIES_MELEE, "TF_SNIPER_KILL_SPIES_MELEE", 5 );
  171. //----------------------------------------------------------------------------------------------------------------
  172. //Kill a scout in midair
  173. //----------------------------------------------------------------------------------------------------------------
  174. class CAchievementTFSniper_ScoutMidairKill: public CBaseTFAchievement
  175. {
  176. void Init()
  177. {
  178. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  179. SetGoal( 1 );
  180. }
  181. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  182. {
  183. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  184. {
  185. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  186. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SCOUT ) && WeaponID_IsSniperRifleOrBow( event->GetInt( "weaponid" ) ) )
  187. {
  188. if ( !(pTFVictim->GetFlags() & FL_ONGROUND) )
  189. {
  190. IncrementCount();
  191. }
  192. }
  193. }
  194. }
  195. };
  196. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ScoutMidairKill, ACHIEVEMENT_TF_SNIPER_KILL_MIDAIR_SCOUT, "TF_SNIPER_KILL_MIDAIR_SCOUT", 5 );
  197. //----------------------------------------------------------------------------------------------------------------
  198. //Kill a fully charged medic
  199. //----------------------------------------------------------------------------------------------------------------
  200. //----------------------------------------------------------------------------------------------------------------
  201. class CAchievementTFSniper_KillChargedMedic : public CBaseTFAchievement
  202. {
  203. void Init()
  204. {
  205. SetFlags( ACH_SAVE_GLOBAL );
  206. SetGoal( 1 );
  207. }
  208. // client fires an event for this achievement, no other code within achievement necessary
  209. };
  210. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillChargedMedic, ACHIEVEMENT_TF_SNIPER_KILL_CHARGED_MEDIC, "TF_SNIPER_KILL_CHARGED_MEDIC", 5 );
  211. //----------------------------------------------------------------------------------------------------------------
  212. //Consolation prize for getting backstabbed
  213. //----------------------------------------------------------------------------------------------------------------
  214. class CAchievementTFSniper_Consolation_Backstabs: public CBaseTFAchievement
  215. {
  216. void Init()
  217. {
  218. SetFlags( ACH_LISTEN_KILL_EVENTS | ACH_SAVE_GLOBAL );
  219. SetGoal( 50 );
  220. SetStoreProgressInSteam( true );
  221. }
  222. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  223. {
  224. if ( pVictim == C_BasePlayer::GetLocalPlayer() )
  225. {
  226. C_TFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
  227. if ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_SPY ) && ( event->GetInt( "customkill" ) == TF_DMG_CUSTOM_BACKSTAB ) )
  228. {
  229. IncrementCount();
  230. }
  231. }
  232. }
  233. };
  234. DECLARE_ACHIEVEMENT( CAchievementTFSniper_Consolation_Backstabs, ACHIEVEMENT_TF_SNIPER_GET_BACKSTABBED, "TF_SNIPER_GET_BACKSTABBED", 5 );
  235. //----------------------------------------------------------------------------------------------------------------
  236. //Dominate an enemy sniper - NOTE: This will probably be iffy if the player you dominated just switched to sniper for that death
  237. //----------------------------------------------------------------------------------------------------------------
  238. class CAchievementTFSniper_DominateEnemySniper : public CBaseTFAchievement
  239. {
  240. void Init()
  241. {
  242. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  243. SetGoal( 1 );
  244. }
  245. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  246. {
  247. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  248. bool bDomination = event->GetInt( "death_flags" ) & TF_DEATH_DOMINATION;
  249. if ( pTFVictim && pAttacker == C_TFPlayer::GetLocalTFPlayer() && pTFVictim->IsPlayerClass( TF_CLASS_SNIPER ) && bDomination == true )
  250. {
  251. IncrementCount();
  252. }
  253. }
  254. };
  255. DECLARE_ACHIEVEMENT( CAchievementTFSniper_DominateEnemySniper, ACHIEVEMENT_TF_SNIPER_DOMINATE_SNIPER, "TF_SNIPER_DOMINATE_SNIPER", 5 );
  256. //----------------------------------------------------------------------------------------------------------------
  257. //Kill a rocket jumping soldier/demo
  258. //----------------------------------------------------------------------------------------------------------------
  259. class CAchievementTFSniper_KillRocketJumper : public CBaseTFAchievement
  260. {
  261. void Init()
  262. {
  263. SetFlags( ACH_SAVE_GLOBAL );
  264. SetGoal( 1 );
  265. }
  266. // client fires an event for this achievement, no other code within achievement necessary
  267. };
  268. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillRocketJumper, ACHIEVEMENT_TF_SNIPER_KILL_RJER, "TF_SNIPER_KILL_RJER", 5 );
  269. //----------------------------------------------------------------------------------------------------------------
  270. //No scope, bro
  271. //----------------------------------------------------------------------------------------------------------------
  272. class CAchievementTFSniper_KillNoScope : public CBaseTFAchievement
  273. {
  274. void Init()
  275. {
  276. SetFlags( ACH_SAVE_GLOBAL );
  277. SetGoal( 5 );
  278. SetStoreProgressInSteam( true );
  279. }
  280. };
  281. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillNoScope, ACHIEVEMENT_TF_SNIPER_KILL_UNSCOPED, "TF_SNIPER_KILL_UNSCOPED", 5 );
  282. //----------------------------------------------------------------------------------------------------------------
  283. //Kill an enemy while you're dead
  284. //----------------------------------------------------------------------------------------------------------------
  285. class CAchievementTFSniper_KillWhileDead: public CBaseTFAchievement
  286. {
  287. void Init()
  288. {
  289. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  290. SetGoal( 1 );
  291. }
  292. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  293. {
  294. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  295. if ( pTFVictim && pAttacker == C_TFPlayer::GetLocalTFPlayer() && pAttacker->IsAlive() == false )
  296. {
  297. IncrementCount();
  298. }
  299. }
  300. };
  301. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillWhileDead, ACHIEVEMENT_TF_SNIPER_BOW_KILL_WHILEDEAD, "TF_SNIPER_BOW_KILL_WHILEDEAD", 5 );
  302. //----------------------------------------------------------------------------------------------------------------
  303. //Extinguish a burning team mate with the jarate
  304. //----------------------------------------------------------------------------------------------------------------
  305. class CAchievementTFSniper_JarateExtinguish : public CBaseTFAchievement
  306. {
  307. void Init()
  308. {
  309. SetFlags( ACH_SAVE_GLOBAL );
  310. SetGoal( 1 );
  311. }
  312. virtual void ListenForEvents( void )
  313. {
  314. ListenForGameEvent( "player_extinguished" );
  315. }
  316. void FireGameEvent_Internal( IGameEvent *event )
  317. {
  318. if ( FStrEq( event->GetName(), "player_extinguished" ) )
  319. {
  320. CTFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  321. if ( !pLocalPlayer )
  322. return;
  323. int iTargetIndex = event->GetInt( "victim" );
  324. int iHealerIndex = event->GetInt( "healer" );
  325. //Extinguishing myself doesn't count.
  326. if ( pLocalPlayer->entindex() == iHealerIndex && pLocalPlayer->entindex() != iTargetIndex )
  327. {
  328. IncrementCount();
  329. }
  330. }
  331. }
  332. };
  333. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateExtinguish, ACHIEVEMENT_TF_SNIPER_JARATE_EXTINGUISH, "TF_SNIPER_JARATE_EXTINGUISH", 5 );
  334. //----------------------------------------------------------------------------------------------------------------
  335. //Topped the scoreboard
  336. //----------------------------------------------------------------------------------------------------------------
  337. class CAchievementTFSniper_TopScoreboard : public CAchievementTopScoreboard
  338. {
  339. void Init()
  340. {
  341. SetFlags( ACH_SAVE_GLOBAL | ACH_FILTER_FULL_ROUND_ONLY );
  342. SetGoal( 10 );
  343. SetStoreProgressInSteam( true );
  344. }
  345. };
  346. DECLARE_ACHIEVEMENT( CAchievementTFSniper_TopScoreboard, ACHIEVEMENT_TF_SNIPER_TOP_SCOREBOARD_GRIND, "TF_SNIPER_TOP_SCOREBOARD_GRIND", 5 );
  347. //----------------------------------------------------------------------------------------------------------------
  348. //Kill an opponent within the first second of a round.
  349. //----------------------------------------------------------------------------------------------------------------
  350. class CAchievementTFSniper_KillRoundStart: public CBaseTFAchievement
  351. {
  352. void Init()
  353. {
  354. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  355. SetGoal( 1 );
  356. m_flRoundStartTime = -1;
  357. }
  358. virtual void ListenForEvents( void )
  359. {
  360. ListenForGameEvent( "teamplay_setup_finished" );
  361. ListenForGameEvent( "arena_round_start" );
  362. }
  363. void FireGameEvent_Internal( IGameEvent *event )
  364. {
  365. if ( FStrEq( event->GetName(), "teamplay_setup_finished" ) || FStrEq( event->GetName(), "arena_round_start" ) )
  366. {
  367. m_flRoundStartTime = gpGlobals->curtime + 1.0f;
  368. }
  369. }
  370. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  371. {
  372. if ( pAttacker == C_TFPlayer::GetLocalTFPlayer() )
  373. {
  374. if ( m_flRoundStartTime > 0.0f && m_flRoundStartTime >= gpGlobals->curtime )
  375. {
  376. IncrementCount();
  377. }
  378. }
  379. }
  380. private:
  381. float m_flRoundStartTime;
  382. };
  383. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillRoundStart, ACHIEVEMENT_TF_SNIPER_KILL_AT_ROUNDSTART, "TF_SNIPER_KILL_AT_ROUNDSTART", 5 );
  384. class CAchievementTFSniper_FreezecamHat : public CBaseTFAchievement
  385. {
  386. void Init()
  387. {
  388. SetFlags( ACH_SAVE_GLOBAL );
  389. SetGoal( 1 );
  390. }
  391. // server awards this achievement, no other code within achievement necessary
  392. };
  393. DECLARE_ACHIEVEMENT( CAchievementTFSniper_FreezecamHat, ACHIEVEMENT_TF_SNIPER_FREEZECAM_HAT, "TF_SNIPER_FREEZECAM_HAT", 5 );
  394. //----------------------------------------------------------------------------------------------------------------
  395. class CAchievementTFSniper_FreezecamWave : public CBaseTFAchievement
  396. {
  397. void Init()
  398. {
  399. SetFlags( ACH_SAVE_GLOBAL );
  400. SetGoal( 1 );
  401. }
  402. // server awards this achievement, no other code within achievement necessary
  403. };
  404. DECLARE_ACHIEVEMENT( CAchievementTFSniper_FreezecamWave, ACHIEVEMENT_TF_SNIPER_FREEZECAM_WAVE, "TF_SNIPER_FREEZECAM_WAVE", 5 );
  405. //----------------------------------------------------------------------------------------------------------------
  406. //Kill an opponent with 3 different weapons in one round
  407. //----------------------------------------------------------------------------------------------------------------
  408. class CAchievementTFSniper_DifferentWeaponsKill: public CBaseTFAchievement
  409. {
  410. void Init()
  411. {
  412. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  413. SetGoal( 1 );
  414. m_Weapons.Purge();
  415. }
  416. virtual void ListenForEvents( void )
  417. {
  418. ListenForGameEvent( "teamplay_round_active" );
  419. }
  420. void FireGameEvent_Internal( IGameEvent *event )
  421. {
  422. if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  423. {
  424. m_Weapons.Purge();
  425. }
  426. }
  427. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  428. {
  429. if ( pAttacker == C_TFPlayer::GetLocalTFPlayer() )
  430. {
  431. int iWeaponID = event->GetInt( "weaponid" );
  432. if ( m_Weapons.Find( iWeaponID ) == -1 )
  433. {
  434. m_Weapons.AddToTail( iWeaponID );
  435. if ( m_Weapons.Count() == 3 )
  436. {
  437. IncrementCount();
  438. }
  439. }
  440. }
  441. }
  442. private:
  443. CUtlVector< int > m_Weapons;
  444. };
  445. DECLARE_ACHIEVEMENT( CAchievementTFSniper_DifferentWeaponsKill, ACHIEVEMENT_TF_SNIPER_KILL_WEAPONS, "TF_SNIPER_KILL_WEAPONS", 5 );
  446. //----------------------------------------------------------------------------------------------------------------
  447. //Kill grind
  448. //----------------------------------------------------------------------------------------------------------------
  449. class CAchievementTFSniper_KillEnemyGrind: public CBaseTFAchievement
  450. {
  451. void Init()
  452. {
  453. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  454. SetGoal( 1000 );
  455. SetStoreProgressInSteam( true );
  456. }
  457. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  458. {
  459. if ( pAttacker == C_TFPlayer::GetLocalTFPlayer() && pVictim && pVictim->IsPlayer() )
  460. {
  461. IncrementCount();
  462. }
  463. }
  464. };
  465. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillEnemyGrind, ACHIEVEMENT_TF_SNIPER_KILL_GRIND, "TF_SNIPER_KILL_GRIND", 5 );
  466. //----------------------------------------------------------------------------------------------------------------
  467. //Destroy 3 enemy sentries
  468. //----------------------------------------------------------------------------------------------------------------
  469. class CAchievementTFSniper_DestroySentry : public CBaseTFAchievement
  470. {
  471. void Init()
  472. {
  473. SetFlags( ACH_SAVE_GLOBAL );
  474. SetGoal( 3 );
  475. SetStoreProgressInSteam( true );
  476. }
  477. virtual void ListenForEvents()
  478. {
  479. ListenForGameEvent( "object_destroyed" );
  480. }
  481. void FireGameEvent_Internal( IGameEvent *event )
  482. {
  483. if ( Q_strcmp( event->GetName(), "object_destroyed" ) == 0 )
  484. {
  485. int iIndex = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
  486. if ( UTIL_PlayerByIndex( iIndex ) == C_TFPlayer::GetLocalTFPlayer() )
  487. {
  488. if ( event->GetInt( "objecttype" ) == OBJ_SENTRYGUN )
  489. {
  490. IncrementCount();
  491. }
  492. }
  493. }
  494. }
  495. };
  496. DECLARE_ACHIEVEMENT( CAchievementTFSniper_DestroySentry, ACHIEVEMENT_TF_SNIPER_DESTROY_SENTRYGUNS, "TF_SNIPER_DESTROY_SENTRYGUNS", 5 );
  497. //----------------------------------------------------------------------------------------------------------------
  498. //Kill enemies doing important stuff.
  499. //----------------------------------------------------------------------------------------------------------------
  500. class CAchievementTFSniper_KillEnemiesImportant : public CBaseTFAchievement
  501. {
  502. void Init()
  503. {
  504. SetFlags( ACH_SAVE_GLOBAL );
  505. SetGoal( 1 );
  506. m_iObjectivesDefended = 0;
  507. }
  508. virtual void ListenForEvents( void )
  509. {
  510. ListenForGameEvent( "teamplay_flag_event" );
  511. ListenForGameEvent( "localplayer_respawn" );
  512. ListenForGameEvent( "teamplay_capture_blocked" );
  513. }
  514. void FireGameEvent_Internal( IGameEvent *event )
  515. {
  516. if ( FStrEq( event->GetName(), "localplayer_respawn" ) )
  517. {
  518. m_iObjectivesDefended = 0;
  519. return;
  520. }
  521. if ( FStrEq( event->GetName(), "teamplay_capture_blocked" ) )
  522. {
  523. int iBlocker = event->GetInt( "blocker" );
  524. if ( iBlocker == GetLocalPlayerIndex() )
  525. {
  526. m_iObjectivesDefended++;
  527. }
  528. }
  529. if ( FStrEq( event->GetName(), "teamplay_flag_event" ) && event->GetInt( "eventtype" ) == TF_FLAGEVENT_DEFEND )
  530. {
  531. int iIndex = event->GetInt( "player" );
  532. if ( GetLocalPlayerIndex() == iIndex )
  533. {
  534. m_iObjectivesDefended++;
  535. }
  536. }
  537. if ( m_iObjectivesDefended >= 3 )
  538. {
  539. IncrementCount();
  540. }
  541. }
  542. private:
  543. int m_iObjectivesDefended;
  544. };
  545. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillEnemiesImportant, ACHIEVEMENT_TF_SNIPER_KILL_OBJECTIVES, "TF_SNIPER_KILL_OBJECTIVES", 5 );
  546. //----------------------------------------------------------------------------------------------------------------
  547. //Kill someone the moment they leave invul
  548. //----------------------------------------------------------------------------------------------------------------
  549. class CAchievementTFSniper_HeadShotPostInvuln: public CBaseTFAchievement
  550. {
  551. void Init()
  552. {
  553. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  554. SetGoal( 1 );
  555. }
  556. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  557. {
  558. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  559. if ( pAttacker == C_TFPlayer::GetLocalTFPlayer() && pTFVictim && IsHeadshot ( event->GetInt( "customkill" ) ) )
  560. {
  561. if ( pTFVictim->m_Shared.GetInvulOffTime() > 0.0f && (gpGlobals->curtime - pTFVictim->m_Shared.GetInvulOffTime() ) <= 1.0f )
  562. {
  563. IncrementCount();
  564. }
  565. }
  566. }
  567. };
  568. DECLARE_ACHIEVEMENT( CAchievementTFSniper_HeadShotPostInvuln, ACHIEVEMENT_TF_SNIPER_HEADSHOT_POST_INVULN, "TF_SNIPER_HEADSHOT_POST_INVULN", 5 );
  569. //----------------------------------------------------------------------------------------------------------------
  570. //Baseclass for jarate/group related stuff
  571. //----------------------------------------------------------------------------------------------------------------
  572. class CAchievementTFSniper_BaseJarateGroup : public CBaseTFAchievement
  573. {
  574. public:
  575. DECLARE_CLASS( CAchievementTFSniper_BaseJarateGroup, CBaseTFAchievement );
  576. void Init()
  577. {
  578. m_flJarateTime = 0.0f;
  579. m_JaratedPlayers.Purge();
  580. }
  581. virtual void ListenForEvents( void )
  582. {
  583. ListenForGameEvent( "player_jarated" );
  584. ListenForGameEvent( "player_jarated_fade" );
  585. }
  586. virtual void AddedJaratedPlayer( void )
  587. {
  588. }
  589. virtual void RemoveJaratedPlayer( void )
  590. {
  591. }
  592. void FireGameEvent_Internal( IGameEvent *event )
  593. {
  594. if ( FStrEq( event->GetName(), "player_jarated_fade" ) )
  595. {
  596. int iThrower = event->GetInt( "thrower_entindex" );
  597. int iVictim = event->GetInt( "victim_entindex" );
  598. if ( GetLocalPlayerIndex() != iThrower )
  599. return;
  600. m_JaratedPlayers.FindAndRemove( iVictim );
  601. RemoveJaratedPlayer();
  602. }
  603. else if ( FStrEq( event->GetName(), "player_jarated" ) )
  604. {
  605. int iThrower = event->GetInt( "thrower_entindex" );
  606. int iVictim = event->GetInt( "victim_entindex" );
  607. if ( GetLocalPlayerIndex() != iThrower )
  608. return;
  609. if ( m_flJarateTime <= gpGlobals->curtime )
  610. {
  611. m_flJarateTime = gpGlobals->curtime + 0.5;
  612. m_JaratedPlayers.Purge();
  613. }
  614. if ( m_JaratedPlayers.Find( iVictim ) == m_JaratedPlayers.InvalidIndex() )
  615. {
  616. m_JaratedPlayers.AddToTail( iVictim );
  617. }
  618. AddedJaratedPlayer();
  619. }
  620. }
  621. CUtlVector< int > m_JaratedPlayers;
  622. float m_flJarateTime;
  623. };
  624. //----------------------------------------------------------------------------------------------------------------
  625. //Jarate 4 players with the same jar.
  626. //----------------------------------------------------------------------------------------------------------------
  627. class CAchievementTFSniper_JaratePack : public CAchievementTFSniper_BaseJarateGroup
  628. {
  629. void Init()
  630. {
  631. SetFlags( ACH_SAVE_GLOBAL );
  632. SetGoal( 1 );
  633. m_flJarateTime = 0.0f;
  634. m_JaratedPlayers.Purge();
  635. }
  636. virtual void AddedJaratedPlayer( void )
  637. {
  638. if ( m_JaratedPlayers.Count() == 4 )
  639. {
  640. IncrementCount();
  641. }
  642. }
  643. };
  644. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JaratePack, ACHIEVEMENT_TF_SNIPER_JARATE_GROUP, "TF_SNIPER_JARATE_GROUP", 5 );
  645. //----------------------------------------------------------------------------------------------------------------
  646. //Jarate a medic and his heal target
  647. //----------------------------------------------------------------------------------------------------------------
  648. class CAchievementTFSniper_JarateMedicPair : public CAchievementTFSniper_BaseJarateGroup
  649. {
  650. void Init()
  651. {
  652. SetFlags( ACH_SAVE_GLOBAL );
  653. SetGoal( 1 );
  654. m_flJarateTime = 0.0f;
  655. m_JaratedPlayers.Purge();
  656. }
  657. virtual void AddedJaratedPlayer( void )
  658. {
  659. for ( int i = 0; i < m_JaratedPlayers.Count(); i++ )
  660. {
  661. CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( m_JaratedPlayers[i] ) );
  662. if ( pPlayer && pPlayer->IsPlayerClass( TF_CLASS_MEDIC ) )
  663. {
  664. CTFPlayer *pHealTarget = ToTFPlayer( pPlayer->MedicGetHealTarget() );
  665. if ( pHealTarget && m_JaratedPlayers.Find( pHealTarget->entindex() ) != -1 )
  666. {
  667. IncrementCount();
  668. }
  669. }
  670. }
  671. }
  672. };
  673. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateMedicPair, ACHIEVEMENT_TF_SNIPER_JARATE_MEDIC_PAIR, "TF_SNIPER_JARATE_MEDIC_PAIR", 5 );
  674. //----------------------------------------------------------------------------------------------------------------
  675. //Jarated an invisible spy
  676. //----------------------------------------------------------------------------------------------------------------
  677. class CAchievementTFSniper_JarateReveal : public CBaseTFAchievement
  678. {
  679. void Init()
  680. {
  681. SetFlags( ACH_SAVE_GLOBAL );
  682. SetGoal( 1 );
  683. }
  684. };
  685. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateReveal, ACHIEVEMENT_TF_SNIPER_JARATE_REVEAL_SPY, "TF_SNIPER_JARATE_REVEAL_SPY", 5 );
  686. //----------------------------------------------------------------------------------------------------------------
  687. //Pin heavy by the head
  688. //----------------------------------------------------------------------------------------------------------------
  689. class CAchievementTFSniper_PinHeavy : public CBaseTFAchievement
  690. {
  691. void Init()
  692. {
  693. SetFlags( ACH_SAVE_GLOBAL );
  694. SetGoal( 1 );
  695. }
  696. virtual void ListenForEvents( void )
  697. {
  698. ListenForGameEvent( "player_pinned" );
  699. }
  700. void FireGameEvent_Internal( IGameEvent *event )
  701. {
  702. if ( FStrEq( event->GetName(), "player_pinned" ) )
  703. {
  704. IncrementCount();
  705. }
  706. }
  707. };
  708. DECLARE_ACHIEVEMENT( CAchievementTFSniper_PinHeavy, ACHIEVEMENT_TF_SNIPER_BOW_PIN_HEAVY, "TF_SNIPER_BOW_PIN_HEAVY", 5 );
  709. //----------------------------------------------------------------------------------------------------------------
  710. //Kill 3 jarated enemies with your kukri
  711. //----------------------------------------------------------------------------------------------------------------
  712. class CAchievementTFSniper_JarateKillMelee : public CAchievementTFSniper_BaseJarateGroup
  713. {
  714. void Init()
  715. {
  716. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  717. SetGoal( 1 );
  718. m_JaratedPlayers.Purge();
  719. m_iKilled = 0;
  720. }
  721. void RemoveJaratedPlayer( void )
  722. {
  723. if ( m_JaratedPlayers.Count() == 0 )
  724. {
  725. m_iKilled = 0;
  726. }
  727. }
  728. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  729. {
  730. if ( pVictim && pAttacker == C_TFPlayer::GetLocalTFPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_CLUB )
  731. {
  732. if ( m_JaratedPlayers.Find( pVictim->entindex() ) != m_JaratedPlayers.InvalidIndex() )
  733. {
  734. m_iKilled++;
  735. if ( m_iKilled == 3 )
  736. {
  737. IncrementCount();
  738. }
  739. }
  740. }
  741. }
  742. private:
  743. int m_iKilled;
  744. };
  745. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateKillMelee, ACHIEVEMENT_TF_SNIPER_JARATE_KILL_MELEE, "TF_SNIPER_JARATE_KILL_MELEE", 5 );
  746. //----------------------------------------------------------------------------------------------------------------
  747. //Kill a spy that just failed a backstab because of the shield
  748. //----------------------------------------------------------------------------------------------------------------
  749. class CAchievementTFSniper_ShieldFailedSpy : public CBaseTFAchievement
  750. {
  751. void Init()
  752. {
  753. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  754. SetGoal( 1 );
  755. m_iAttackerIndex = 0;
  756. m_flAttackTime = 0.0f;
  757. }
  758. virtual void ListenForEvents( void )
  759. {
  760. ListenForGameEvent( "player_shield_blocked" );
  761. }
  762. void FireGameEvent_Internal( IGameEvent *event )
  763. {
  764. if ( FStrEq( event->GetName(), "player_shield_blocked" ) )
  765. {
  766. int iAttacker = event->GetInt( "attacker_entindex" );
  767. int iBlocker = event->GetInt( "blocker_entindex" );
  768. if ( GetLocalPlayerIndex() != iBlocker )
  769. return;
  770. m_iAttackerIndex = iAttacker;
  771. m_flAttackTime = gpGlobals->curtime + 10.0f;
  772. }
  773. }
  774. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  775. {
  776. if ( m_flAttackTime <= gpGlobals->curtime )
  777. {
  778. m_iAttackerIndex = 0;
  779. }
  780. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  781. if ( pTFVictim && pTFVictim->entindex() == m_iAttackerIndex && pAttacker == C_TFPlayer::GetLocalTFPlayer() )
  782. {
  783. IncrementCount();
  784. }
  785. }
  786. private:
  787. int m_iAttackerIndex;
  788. float m_flAttackTime;
  789. };
  790. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ShieldFailedSpy, ACHIEVEMENT_TF_SNIPER_KILL_FAILED_SPY, "TF_SNIPER_KILL_FAILED_SPY", 5 );
  791. //----------------------------------------------------------------------------------------------------------------
  792. // Kill a medic/heavy pair with the bow.
  793. //----------------------------------------------------------------------------------------------------------------
  794. class CAchievementTFSniper_KillMedicPair : public CBaseTFAchievement
  795. {
  796. void Init()
  797. {
  798. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  799. SetGoal( 1 );
  800. }
  801. virtual void ListenForEvents( void )
  802. {
  803. ListenForGameEvent( "localplayer_respawn" );
  804. ListenForGameEvent( "teamplay_round_active" );
  805. m_hTargets.Purge();
  806. }
  807. void FireGameEvent_Internal( IGameEvent *event )
  808. {
  809. const char *pszEventName = event->GetName();
  810. if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
  811. FStrEq( pszEventName, "teamplay_round_active" ) )
  812. {
  813. m_hTargets.Purge();
  814. }
  815. }
  816. int GetTargetIndex( CBaseEntity *pTarget )
  817. {
  818. for ( int i = 0; i < m_hTargets.Count(); i++ )
  819. {
  820. if ( m_hTargets[i].hTarget == pTarget )
  821. return i;
  822. }
  823. return -1;
  824. }
  825. void AddNewTarget( CBaseEntity *pTarget )
  826. {
  827. if ( !pTarget )
  828. return;
  829. // see if the target is already in our list or get a new index
  830. int iTargetIndex = GetTargetIndex( pTarget );
  831. if ( iTargetIndex == -1 )
  832. {
  833. iTargetIndex = m_hTargets.AddToTail();
  834. }
  835. m_hTargets[iTargetIndex].hTarget = pTarget;
  836. m_hTargets[iTargetIndex].flTimeToBeat = gpGlobals->curtime + 15.0f; // 15 seconds to kill the target
  837. }
  838. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  839. {
  840. if ( !pVictim || !pVictim->IsPlayer() )
  841. return;
  842. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  843. if ( pLocalPlayer == pAttacker && event->GetInt( "weaponid" ) == TF_WEAPON_COMPOUND_BOW )
  844. {
  845. // is this victim in our list of targets?
  846. int index = GetTargetIndex( pVictim );
  847. if ( index != -1 )
  848. {
  849. // did we beat the time?
  850. if ( m_hTargets[index].flTimeToBeat > gpGlobals->curtime )
  851. {
  852. IncrementCount();
  853. }
  854. }
  855. else
  856. {
  857. C_TFPlayer *pNewTarget = NULL;
  858. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  859. if ( pTFVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  860. {
  861. for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
  862. {
  863. pNewTarget = ToTFPlayer( UTIL_PlayerByIndex( i ) );
  864. if ( pNewTarget && pNewTarget->IsPlayerClass( TF_CLASS_MEDIC ) && pNewTarget->MedicGetHealTarget() == pTFVictim )
  865. {
  866. // add all of his Medics to our list of targets (could be more than one Medic)
  867. AddNewTarget( pNewTarget );
  868. }
  869. }
  870. }
  871. else if ( pTFVictim->IsPlayerClass( TF_CLASS_MEDIC ) )
  872. {
  873. pNewTarget = ToTFPlayer( pTFVictim->MedicGetHealTarget() );
  874. if ( pNewTarget && pNewTarget->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  875. {
  876. AddNewTarget( pNewTarget );
  877. }
  878. }
  879. }
  880. }
  881. // is this victim in our list of targets?
  882. int index_ = GetTargetIndex( pVictim );
  883. if ( index_ != -1 )
  884. {
  885. m_hTargets.Remove( index_ );
  886. }
  887. }
  888. private:
  889. struct targets_t
  890. {
  891. EHANDLE hTarget;
  892. float flTimeToBeat;
  893. };
  894. CUtlVector<targets_t> m_hTargets;
  895. };
  896. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillMedicPair, ACHIEVEMENT_TF_SNIPER_BOW_KILL_MEDIC_PAIR, "TF_SNIPER_BOW_KILL_MEDIC_PAIR", 5 );
  897. //----------------------------------------------------------------------------------------------------------------
  898. //Kill 3 jarated enemies with your kukri
  899. //----------------------------------------------------------------------------------------------------------------
  900. class CAchievementTFSniper_JarateAssists : public CAchievementTFSniper_BaseJarateGroup
  901. {
  902. DECLARE_CLASS( CAchievementTFSniper_JarateAssists, CAchievementTFSniper_BaseJarateGroup );
  903. void Init()
  904. {
  905. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  906. SetGoal( 1 );
  907. m_JaratedPlayers.Purge();
  908. m_iAssists = 0;
  909. }
  910. virtual void ListenForEvents( void )
  911. {
  912. ListenForGameEvent( "teamplay_round_active" );
  913. BaseClass::ListenForEvents();
  914. }
  915. void FireGameEvent_Internal( IGameEvent *event )
  916. {
  917. if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  918. {
  919. m_JaratedPlayers.Purge();
  920. m_iAssists = 0;
  921. }
  922. BaseClass::FireGameEvent_Internal( event );
  923. }
  924. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  925. {
  926. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  927. if ( iAssisterIndex > 0 )
  928. {
  929. C_TFPlayer *pTFAssister = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
  930. if ( pVictim && pTFAssister == C_TFPlayer::GetLocalTFPlayer() )
  931. {
  932. if ( m_JaratedPlayers.Find( pVictim->entindex() ) != m_JaratedPlayers.InvalidIndex() )
  933. {
  934. m_iAssists++;
  935. if ( m_iAssists == 5 )
  936. {
  937. IncrementCount();
  938. }
  939. }
  940. }
  941. }
  942. }
  943. private:
  944. int m_iAssists;
  945. };
  946. DECLARE_ACHIEVEMENT( CAchievementTFSniper_JarateAssists, ACHIEVEMENT_TF_SNIPER_JARATE_ASSISTS, "TF_SNIPER_JARATE_ASSISTS", 5 );
  947. //----------------------------------------------------------------------------------------------------------------
  948. //Kill an enemy carrying your flag with the bow
  949. //----------------------------------------------------------------------------------------------------------------
  950. class CAchievementTFSniper_KillFlagCarrierBow : public CBaseTFAchievement
  951. {
  952. void Init()
  953. {
  954. SetFlags( ACH_SAVE_GLOBAL );
  955. SetGoal( 1 );
  956. }
  957. // server awards this achievement, no other code within achievement necessary
  958. };
  959. DECLARE_ACHIEVEMENT( CAchievementTFSniper_KillFlagCarrierBow, ACHIEVEMENT_TF_SNIPER_BOW_KILL_FLAGCARRIER, "TF_SNIPER_BOW_KILL_FLAGCARRIER", 5 );
  960. //----------------------------------------------------------------------------------------------------------------
  961. //Boromir someone
  962. //----------------------------------------------------------------------------------------------------------------
  963. class CAchievementTFSniper_Pincushion : public CBaseTFAchievement
  964. {
  965. void Init()
  966. {
  967. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  968. SetGoal( 1 );
  969. m_hTargets.Purge();
  970. }
  971. virtual void ListenForEvents( void )
  972. {
  973. ListenForGameEvent( "arrow_impact" );
  974. ListenForGameEvent( "teamplay_round_active" );
  975. ListenForGameEvent( "localplayer_respawn" );
  976. }
  977. void FireGameEvent_Internal( IGameEvent *event )
  978. {
  979. if ( FStrEq( event->GetName(), "teamplay_round_active" ) || FStrEq( event->GetName(), "localplayer_respawn" ) )
  980. {
  981. m_hTargets.Purge();
  982. }
  983. else if ( FStrEq( event->GetName(), "arrow_impact" ) )
  984. {
  985. int iEntity = event->GetInt( "attachedEntity" );
  986. int iShooter = event->GetInt( "shooter" );
  987. if ( iShooter == GetLocalPlayerIndex() )
  988. {
  989. int iTargetIndex = GetTargetIndex( UTIL_PlayerByIndex( iEntity ) );
  990. if ( iTargetIndex == -1 )
  991. {
  992. AddNewTarget( UTIL_PlayerByIndex( iEntity ) );
  993. }
  994. else
  995. {
  996. m_hTargets[iTargetIndex].iArrows++;
  997. if ( m_hTargets[iTargetIndex].iArrows >= 3 )
  998. {
  999. IncrementCount();
  1000. m_hTargets.Purge();
  1001. }
  1002. }
  1003. }
  1004. }
  1005. }
  1006. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1007. {
  1008. if ( pAttacker == C_TFPlayer::GetLocalTFPlayer() )
  1009. {
  1010. int iTargetIndex = GetTargetIndex( pVictim );
  1011. if ( iTargetIndex != -1 )
  1012. {
  1013. m_hTargets.Remove( iTargetIndex );
  1014. }
  1015. }
  1016. }
  1017. int GetTargetIndex( CBaseEntity *pTarget )
  1018. {
  1019. for ( int i = 0; i < m_hTargets.Count(); i++ )
  1020. {
  1021. if ( m_hTargets[i].hTarget == pTarget )
  1022. return i;
  1023. }
  1024. return -1;
  1025. }
  1026. void AddNewTarget( CBaseEntity *pTarget )
  1027. {
  1028. if ( !pTarget )
  1029. return;
  1030. if ( pTarget->IsAlive() == false )
  1031. return;
  1032. // see if the target is already in our list or get a new index
  1033. int iTargetIndex = GetTargetIndex( pTarget );
  1034. if ( iTargetIndex == -1 )
  1035. {
  1036. iTargetIndex = m_hTargets.AddToTail();
  1037. }
  1038. m_hTargets[iTargetIndex].hTarget = pTarget;
  1039. m_hTargets[iTargetIndex].iArrows = 1;
  1040. }
  1041. private:
  1042. struct targets_t
  1043. {
  1044. EHANDLE hTarget;
  1045. int iArrows;
  1046. float flRemoveTime;
  1047. };
  1048. CUtlVector<targets_t> m_hTargets;
  1049. };
  1050. DECLARE_ACHIEVEMENT( CAchievementTFSniper_Pincushion, ACHIEVEMENT_TF_SNIPER_BOW_PINCUSHION, "TF_SNIPER_BOW_PINCUSHION", 5 );
  1051. //----------------------------------------------------------------------------------------------------------------
  1052. class CAchievementTFSniper_SniperTauntKill : public CBaseTFAchievement
  1053. {
  1054. void Init()
  1055. {
  1056. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  1057. SetGoal( 1 );
  1058. }
  1059. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1060. {
  1061. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  1062. {
  1063. // we already know we killed a player because of the ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS flag
  1064. // was this a taunt kill?
  1065. if ( event->GetInt( "customkill" ) == TF_DMG_CUSTOM_TAUNTATK_ARROW_STAB )
  1066. {
  1067. IncrementCount();
  1068. }
  1069. }
  1070. }
  1071. };
  1072. DECLARE_ACHIEVEMENT( CAchievementTFSniper_SniperTauntKill, ACHIEVEMENT_TF_SNIPER_TAUNT_KILL, "TF_SNIPER_TAUNT_KILL", 5 );
  1073. //----------------------------------------------------------------------------------------------------------------
  1074. class CAchievementTFSniper_SniperRifleNoMissing : public CBaseTFAchievement
  1075. {
  1076. void Init()
  1077. {
  1078. SetFlags( ACH_SAVE_GLOBAL );
  1079. SetGoal( 1 );
  1080. }
  1081. // server awards this achievement, no other code within achievement necessary
  1082. };
  1083. DECLARE_ACHIEVEMENT( CAchievementTFSniper_SniperRifleNoMissing, ACHIEVEMENT_TF_SNIPER_RIFLE_NO_MISSING, "TF_SNIPER_RIFLE_NO_MISSING", 5 );
  1084. //----------------------------------------------------------------------------------------------------------------
  1085. class CAchievementTFSniper_AchieveProgress1 : public CAchievement_AchievedCount
  1086. {
  1087. public:
  1088. DECLARE_CLASS( CAchievementTFSniper_AchieveProgress1, CAchievement_AchievedCount );
  1089. void Init()
  1090. {
  1091. BaseClass::Init();
  1092. SetAchievementsRequired( 5, ACHIEVEMENT_TF_SNIPER_START_RANGE, ACHIEVEMENT_TF_SNIPER_END_RANGE );
  1093. }
  1094. };
  1095. DECLARE_ACHIEVEMENT( CAchievementTFSniper_AchieveProgress1, ACHIEVEMENT_TF_SNIPER_ACHIEVE_PROGRESS1, "TF_SNIPER_ACHIEVE_PROGRESS1", 5 );
  1096. //----------------------------------------------------------------------------------------------------------------
  1097. class CAchievementTFSniper_AchieveProgress2 : public CAchievement_AchievedCount
  1098. {
  1099. public:
  1100. DECLARE_CLASS( CAchievementTFSniper_AchieveProgress2, CAchievement_AchievedCount );
  1101. void Init()
  1102. {
  1103. BaseClass::Init();
  1104. SetAchievementsRequired( 11, ACHIEVEMENT_TF_SNIPER_START_RANGE, ACHIEVEMENT_TF_SNIPER_END_RANGE );
  1105. }
  1106. };
  1107. DECLARE_ACHIEVEMENT( CAchievementTFSniper_AchieveProgress2, ACHIEVEMENT_TF_SNIPER_ACHIEVE_PROGRESS2, "TF_SNIPER_ACHIEVE_PROGRESS2", 5 );
  1108. //----------------------------------------------------------------------------------------------------------------
  1109. class CAchievementTFSniper_AchieveProgress3 : public CAchievement_AchievedCount
  1110. {
  1111. public:
  1112. DECLARE_CLASS( CAchievementTFSniper_AchieveProgress3, CAchievement_AchievedCount );
  1113. void Init()
  1114. {
  1115. BaseClass::Init();
  1116. SetAchievementsRequired( 17, ACHIEVEMENT_TF_SNIPER_START_RANGE, ACHIEVEMENT_TF_SNIPER_END_RANGE );
  1117. }
  1118. };
  1119. DECLARE_ACHIEVEMENT( CAchievementTFSniper_AchieveProgress3, ACHIEVEMENT_TF_SNIPER_ACHIEVE_PROGRESS3, "TF_SNIPER_ACHIEVE_PROGRESS3", 5 );
  1120. //----------------------------------------------------------------------------------------------------------------
  1121. class CAchievementTFSniper_ClassicRifleNoScopeHeadshot : public CBaseTFAchievement
  1122. {
  1123. public:
  1124. void Init()
  1125. {
  1126. SetFlags( ACH_SAVE_GLOBAL );
  1127. SetGoal( 10 );
  1128. SetStoreProgressInSteam( true );
  1129. }
  1130. // server awards this achievement, no other code within achievement necessary
  1131. };
  1132. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ClassicRifleNoScopeHeadshot, ACHIEVEMENT_TF_SNIPER_CLASSIC_RIFLE_NOSCOPE_HEADSHOT, "TF_SNIPER_CLASSIC_RIFLE_NOSCOPE_HEADSHOT", 5 );
  1133. //----------------------------------------------------------------------------------------------------------------
  1134. class CAchievementTFSniper_ClassicRifleHeadshotJumper : public CBaseTFAchievement
  1135. {
  1136. public:
  1137. void Init()
  1138. {
  1139. SetFlags( ACH_SAVE_GLOBAL );
  1140. SetGoal( 1 );
  1141. }
  1142. // server awards this achievement, no other code within achievement necessary
  1143. };
  1144. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ClassicRifleHeadshotJumper, ACHIEVEMENT_TF_SNIPER_CLASSIC_RIFLE_HEADSHOT_JUMPER, "TF_SNIPER_CLASSIC_RIFLE_HEADSHOT_JUMPER", 5 );
  1145. //----------------------------------------------------------------------------------------------------------------
  1146. class CAchievementTFSniper_ClassicRifleGibGrind : public CBaseTFAchievement
  1147. {
  1148. public:
  1149. void Init()
  1150. {
  1151. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  1152. SetGoal( 1 );
  1153. m_iClassesKilled = 0;
  1154. }
  1155. virtual void ListenForEvents( void )
  1156. {
  1157. ListenForGameEvent( "teamplay_round_active" );
  1158. }
  1159. void FireGameEvent_Internal( IGameEvent *event )
  1160. {
  1161. if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  1162. {
  1163. m_iClassesKilled = 0;
  1164. }
  1165. }
  1166. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1167. {
  1168. if ( pVictim && ( pAttacker == CBasePlayer::GetLocalPlayer() ) )
  1169. {
  1170. if ( event->GetInt( "weaponid" ) == TF_WEAPON_SNIPERRIFLE_CLASSIC )
  1171. {
  1172. if ( event->GetInt( "death_flags" ) & TF_DEATH_GIBBED )
  1173. {
  1174. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  1175. if ( pTFVictim && pTFVictim->GetPlayerClass() )
  1176. {
  1177. int iClass = pTFVictim->GetPlayerClass()->GetClassIndex();
  1178. if ( iClass >= TF_FIRST_NORMAL_CLASS && iClass <= ( TF_LAST_NORMAL_CLASS - 1 ) ) //( TF_LAST_NORMAL_CLASS - 1 ) to exclude the new civilian class
  1179. {
  1180. // yes, the achievement is satisfied for this class, set the corresponding bit
  1181. int iBitNumber = ( iClass - TF_FIRST_NORMAL_CLASS );
  1182. m_iClassesKilled |= ( 1 << iBitNumber );
  1183. if ( m_iClassesKilled == 511 )
  1184. {
  1185. IncrementCount();
  1186. }
  1187. }
  1188. }
  1189. }
  1190. }
  1191. }
  1192. }
  1193. private:
  1194. int m_iClassesKilled;
  1195. };
  1196. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ClassicRifleGibGrind, ACHIEVEMENT_TF_SNIPER_CLASSIC_RIFLE_GIB_GRIND, "TF_SNIPER_CLASSIC_RIFLE_GIB_GRIND", 5 );
  1197. //----------------------------------------------------------------------------------------------------------------
  1198. class CAchievementTFSniper_ParachuteGrind : public CBaseTFAchievement
  1199. {
  1200. public:
  1201. void Init()
  1202. {
  1203. SetFlags( ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS | ACH_SAVE_GLOBAL );
  1204. SetGoal( 25 );
  1205. SetStoreProgressInSteam( true );
  1206. }
  1207. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1208. {
  1209. if ( pVictim && ( pAttacker == CBasePlayer::GetLocalPlayer() ) )
  1210. {
  1211. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  1212. if ( pTFVictim &&
  1213. ( pAttacker == C_TFPlayer::GetLocalTFPlayer() ) &&
  1214. ( IsHeadshot( event->GetInt( "customkill" ) ) ) &&
  1215. ( event->GetInt( "damagebits" ) & DMG_CRITICAL ) &&
  1216. ( pTFVictim->m_Shared.InCond( TF_COND_PARACHUTE_DEPLOYED ) ) )
  1217. {
  1218. IncrementCount();
  1219. }
  1220. }
  1221. }
  1222. };
  1223. DECLARE_ACHIEVEMENT( CAchievementTFSniper_ParachuteGrind, ACHIEVEMENT_TF_SNIPER_PARACHUTE_GRIND, "TF_SNIPER_PARACHUTE_GRIND", 5 );
  1224. #endif // CLIENT_DLL