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.

1217 lines
36 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. class CAchievementTFHeavy_DamageTaken : public CBaseTFAchievement
  19. {
  20. void Init()
  21. {
  22. SetFlags( ACH_SAVE_GLOBAL );
  23. SetGoal( 1 );
  24. }
  25. virtual void ListenForEvents()
  26. {
  27. ListenForGameEvent( "player_damaged" );
  28. ListenForGameEvent( "teamplay_round_active" );
  29. ListenForGameEvent( "localplayer_respawn" );
  30. m_iDamageTotal = 0;
  31. }
  32. void FireGameEvent_Internal( IGameEvent *event )
  33. {
  34. if ( Q_strcmp( event->GetName(), "player_damaged" ) == 0 )
  35. {
  36. m_iDamageTotal += event->GetInt( "amount" );
  37. if ( m_iDamageTotal >= 1000 )
  38. {
  39. IncrementCount();
  40. }
  41. }
  42. else if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  43. {
  44. m_iDamageTotal = 0;
  45. }
  46. else if ( FStrEq( event->GetName(), "localplayer_respawn" ) )
  47. {
  48. m_iDamageTotal = 0;
  49. }
  50. }
  51. private:
  52. int m_iDamageTotal;
  53. };
  54. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_DamageTaken, ACHIEVEMENT_TF_HEAVY_DAMAGE_TAKEN, "TF_HEAVY_DAMAGE_TAKEN", 5 );
  55. //----------------------------------------------------------------------------------------------------------------
  56. class CAchievementTFHeavy_DamageTypesTaken : public CBaseTFAchievement
  57. {
  58. void Init()
  59. {
  60. SetFlags( ACH_SAVE_GLOBAL );
  61. SetGoal( 1 );
  62. }
  63. virtual void ListenForEvents()
  64. {
  65. ListenForGameEvent( "player_damaged" );
  66. ListenForGameEvent( "teamplay_round_active" );
  67. ListenForGameEvent( "localplayer_respawn" );
  68. m_iDamageTypesTaken = 0;
  69. }
  70. void FireGameEvent_Internal( IGameEvent *event )
  71. {
  72. if ( Q_strcmp( event->GetName(), "player_damaged" ) == 0 )
  73. {
  74. int iDmgType = event->GetInt( "type" );
  75. // Melee weapons claim to be bullet & club. If dmg type includes club, ignore the bullet.
  76. if ( iDmgType & (DMG_CLUB|DMG_SLASH) )
  77. {
  78. iDmgType &= ~DMG_BULLET;
  79. }
  80. m_iDamageTypesTaken |= iDmgType;
  81. // Get the achievement once we've been shot, burned, clubbed, and exploded.
  82. if ( (m_iDamageTypesTaken & (DMG_BULLET|DMG_BUCKSHOT)) && (m_iDamageTypesTaken & DMG_BLAST) &&
  83. (m_iDamageTypesTaken & (DMG_BURN|DMG_IGNITE)) && (m_iDamageTypesTaken & (DMG_CLUB|DMG_SLASH)) )
  84. {
  85. IncrementCount();
  86. }
  87. }
  88. else if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  89. {
  90. m_iDamageTypesTaken = 0;
  91. }
  92. else if ( FStrEq( event->GetName(), "localplayer_respawn" ) )
  93. {
  94. m_iDamageTypesTaken = 0;
  95. }
  96. }
  97. private:
  98. int m_iDamageTypesTaken;
  99. };
  100. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_DamageTypesTaken, ACHIEVEMENT_TF_HEAVY_TAKE_MULTI_DAMAGE, "TF_HEAVY_TAKE_MULTI_DAMAGE", 5 );
  101. //----------------------------------------------------------------------------------------------------------------
  102. class CAchievementTFHeavy_SurviveCrocket : public CBaseTFAchievement
  103. {
  104. void Init()
  105. {
  106. SetFlags( ACH_SAVE_GLOBAL );
  107. SetGoal( 1 );
  108. }
  109. // Survive a direct hit from a critical rocket
  110. // server awards this achievement, no other code within achievement necessary
  111. };
  112. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_SurviveCrocket, ACHIEVEMENT_TF_HEAVY_SURVIVE_CROCKET, "TF_HEAVY_SURVIVE_CROCKET", 5 );
  113. //----------------------------------------------------------------------------------------------------------------
  114. class CAchievementTFHeavy_UncoverSpies : public CBaseTFAchievement
  115. {
  116. void Init()
  117. {
  118. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  119. SetGoal( 10 );
  120. SetStoreProgressInSteam( true );
  121. }
  122. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  123. {
  124. if ( !pVictim || !pVictim->IsPlayer() )
  125. return;
  126. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  127. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SPY ) && pTFVictim->m_Shared.InCond( TF_COND_STEALTHED ) )
  128. {
  129. bool bSuccess = false;
  130. // is the local player the killer or the assister?
  131. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  132. {
  133. bSuccess = true;
  134. }
  135. else
  136. {
  137. // did the local player assist in the kill?
  138. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  139. if ( iAssisterIndex > 0 )
  140. {
  141. if ( iAssisterIndex == GetLocalPlayerIndex() )
  142. {
  143. bSuccess = true;
  144. }
  145. }
  146. }
  147. if ( bSuccess )
  148. {
  149. IncrementCount();
  150. }
  151. }
  152. }
  153. };
  154. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_UncoverSpies, ACHIEVEMENT_TF_HEAVY_UNCOVER_SPIES, "TF_HEAVY_UNCOVER_SPIES", 5 );
  155. //----------------------------------------------------------------------------------------------------------------
  156. class CAchievementTFHeavy_AssistGrind : public CBaseTFAchievement
  157. {
  158. void Init()
  159. {
  160. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  161. SetGoal( 1000 );
  162. SetStoreProgressInSteam( true );
  163. }
  164. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  165. {
  166. if ( !pVictim || !pVictim->IsPlayer() )
  167. return;
  168. // did the local player assist in the kill?
  169. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  170. if ( iAssisterIndex > 0 )
  171. {
  172. if ( iAssisterIndex == GetLocalPlayerIndex() )
  173. {
  174. IncrementCount();
  175. }
  176. }
  177. }
  178. };
  179. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AssistGrind, ACHIEVEMENT_TF_HEAVY_ASSIST_GRIND, "TF_HEAVY_ASSIST_GRIND", 5 );
  180. //----------------------------------------------------------------------------------------------------------------
  181. class CAchievementTFHeavy_KillHeaviesGloves : public CBaseTFAchievement
  182. {
  183. void Init()
  184. {
  185. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  186. SetGoal( 10 );
  187. SetStoreProgressInSteam( true );
  188. }
  189. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  190. {
  191. if ( !pVictim || !pVictim->IsPlayer() )
  192. return;
  193. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_FISTS )
  194. {
  195. CTFPlayer *pTFVictim = ToTFPlayer( pVictim );
  196. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  197. {
  198. if ( FStrEq( event->GetString( "weapon_logclassname", "" ), "gloves" ) )
  199. {
  200. IncrementCount();
  201. }
  202. }
  203. }
  204. }
  205. };
  206. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillHeaviesGloves, ACHIEVEMENT_TF_HEAVY_KILL_HEAVIES_GLOVES, "TF_HEAVY_KILL_HEAVIES_GLOVES", 5 );
  207. //----------------------------------------------------------------------------------------------------------------
  208. class CAchievementTFHeavy_AssistHeavyGrind : public CBaseTFAchievement
  209. {
  210. void Init()
  211. {
  212. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  213. SetGoal( 25 );
  214. SetStoreProgressInSteam( true );
  215. }
  216. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  217. {
  218. if ( !pVictim || !pVictim->IsPlayer() )
  219. return;
  220. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  221. if ( pLocalPlayer )
  222. {
  223. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  224. if ( iAssisterIndex > 0 )
  225. {
  226. C_TFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
  227. C_TFPlayer *pTFAssister = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
  228. if ( pTFAssister == pLocalPlayer || pTFAttacker == pLocalPlayer )
  229. {
  230. if ( pTFAssister && pTFAssister->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) && pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  231. {
  232. IncrementCount();
  233. }
  234. }
  235. }
  236. }
  237. }
  238. };
  239. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AssistHeavyGrind, ACHIEVEMENT_TF_HEAVY_ASSIST_HEAVY_GRIND, "TF_HEAVY_ASSIST_HEAVY_GRIND", 5 );
  240. //----------------------------------------------------------------------------------------------------------------
  241. class CAchievementTFHeavy_KillDominated : public CBaseTFAchievement
  242. {
  243. void Init()
  244. {
  245. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  246. SetGoal( 20 );
  247. SetStoreProgressInSteam( true );
  248. }
  249. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  250. {
  251. if ( !pVictim || !pVictim->IsPlayer() )
  252. return;
  253. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  254. {
  255. bool bDomination = event->GetInt( "death_flags" ) & TF_DEATH_DOMINATION;
  256. if ( !bDomination ) // we didn't dominate them with *THIS* kill
  257. {
  258. CTFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
  259. if ( pTFAttacker && pTFAttacker->m_Shared.IsPlayerDominated( pVictim->entindex() ) )
  260. {
  261. IncrementCount();
  262. }
  263. }
  264. }
  265. }
  266. };
  267. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillDominated, ACHIEVEMENT_TF_HEAVY_KILL_DOMINATED, "TF_HEAVY_KILL_DOMINATED", 5 );
  268. //----------------------------------------------------------------------------------------------------------------
  269. class CAchievementTFHeavy_KillCritPunch : public CBaseTFAchievement
  270. {
  271. void Init()
  272. {
  273. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  274. SetGoal( 1 );
  275. }
  276. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  277. {
  278. if ( !pVictim || !pVictim->IsPlayer() )
  279. return;
  280. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_FISTS )
  281. {
  282. if ( event->GetInt( "damagebits" ) & DMG_CRITICAL )
  283. {
  284. IncrementCount();
  285. }
  286. }
  287. }
  288. };
  289. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillCritPunch, ACHIEVEMENT_TF_HEAVY_KILL_CRIT_PUNCH, "TF_HEAVY_KILL_CRIT_PUNCH", 5 );
  290. //----------------------------------------------------------------------------------------------------------------
  291. class CAchievementTFHeavy_KillUnderwater : public CBaseTFAchievement
  292. {
  293. void Init()
  294. {
  295. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  296. SetGoal( 50 );
  297. SetStoreProgressInSteam( true );
  298. }
  299. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  300. {
  301. if ( !pVictim || !pVictim->IsPlayer() )
  302. return;
  303. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  304. if ( pAttacker == pLocalPlayer && pVictim != pLocalPlayer )
  305. {
  306. if ( pLocalPlayer->GetWaterLevel() >= WL_Eyes && pVictim->GetWaterLevel() >= WL_Waist )
  307. {
  308. IncrementCount();
  309. }
  310. }
  311. }
  312. };
  313. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillUnderwater, ACHIEVEMENT_TF_HEAVY_KILL_UNDERWATER, "TF_HEAVY_KILL_UNDERWATER", 5 );
  314. //----------------------------------------------------------------------------------------------------------------
  315. class CAchievementTFHeavy_HealMedikits : public CBaseTFAchievement
  316. {
  317. void Init()
  318. {
  319. SetFlags( ACH_SAVE_GLOBAL );
  320. SetGoal( 1 );
  321. }
  322. virtual void ListenForEvents()
  323. {
  324. ListenForGameEvent( "teamplay_round_active" );
  325. ListenForGameEvent( "localplayer_respawn" );
  326. m_iHealTotal = 0;
  327. }
  328. virtual void UpdateAchievement( int nData )
  329. {
  330. if ( !LocalPlayerCanEarn() )
  331. return;
  332. m_iHealTotal += nData;
  333. if ( m_iHealTotal >= 1000 )
  334. {
  335. IncrementCount();
  336. }
  337. }
  338. void FireGameEvent_Internal( IGameEvent *event )
  339. {
  340. if ( FStrEq( event->GetName(), "teamplay_round_active" ) ||
  341. FStrEq( event->GetName(), "localplayer_respawn" ) )
  342. {
  343. m_iHealTotal = 0;
  344. }
  345. }
  346. private:
  347. int m_iHealTotal;
  348. };
  349. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_HealMedikits, ACHIEVEMENT_TF_HEAVY_HEAL_MEDIKITS, "TF_HEAVY_HEAL_MEDIKITS", 5 );
  350. //----------------------------------------------------------------------------------------------------------------
  351. class CAchievementTFHeavy_ReceiveUberGrind : public CBaseTFAchievement
  352. {
  353. void Init()
  354. {
  355. SetFlags( ACH_SAVE_GLOBAL );
  356. SetGoal( 50 );
  357. SetStoreProgressInSteam( true );
  358. }
  359. // client fires an event for this achievement, no other code within achievement necessary
  360. };
  361. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_ReceiveUberGrind, ACHIEVEMENT_TF_HEAVY_RECEIVE_UBER_GRIND, "TF_HEAVY_RECEIVE_UBER_GRIND", 5 );
  362. //----------------------------------------------------------------------------------------------------------------
  363. class CAchievementTFHeavy_KillWhileSpunup : public CBaseTFAchievement
  364. {
  365. void Init()
  366. {
  367. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  368. SetGoal( 1 );
  369. }
  370. virtual void ListenForEvents()
  371. {
  372. ListenForGameEvent( "localplayer_winddown" );
  373. ListenForGameEvent( "teamplay_round_active" );
  374. ListenForGameEvent( "localplayer_respawn" );
  375. m_nNumKilled = 0;
  376. }
  377. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  378. {
  379. if ( !pVictim || !pVictim->IsPlayer() )
  380. return;
  381. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_MINIGUN )
  382. {
  383. m_nNumKilled++;
  384. if ( m_nNumKilled >= 5 )
  385. {
  386. IncrementCount();
  387. }
  388. }
  389. }
  390. void FireGameEvent_Internal( IGameEvent *event )
  391. {
  392. if ( FStrEq( event->GetName(), "localplayer_winddown" ) ||
  393. FStrEq( event->GetName(), "teamplay_round_active" ) ||
  394. FStrEq( event->GetName(), "localplayer_respawn" ) )
  395. {
  396. m_nNumKilled = 0;
  397. }
  398. }
  399. private:
  400. int m_nNumKilled;
  401. };
  402. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillWhileSpunup, ACHIEVEMENT_TF_HEAVY_KILL_WHILE_SPUNUP, "TF_HEAVY_KILL_WHILE_SPUNUP", 5 );
  403. //----------------------------------------------------------------------------------------------------------------
  404. class CAchievementTFHeavy_PayloadCapGrind : public CBaseTFAchievement
  405. {
  406. void Init()
  407. {
  408. SetFlags( ACH_SAVE_GLOBAL );
  409. SetGoal( 50 );
  410. SetStoreProgressInSteam( true );
  411. }
  412. // server awards this achievement, no other code within achievement necessary
  413. };
  414. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_PayloadCapGrind, ACHIEVEMENT_TF_HEAVY_PAYLOAD_CAP_GRIND, "TF_HEAVY_PAYLOAD_CAP_GRIND", 5 );
  415. //----------------------------------------------------------------------------------------------------------------
  416. class CAchievementTFHeavy_KillMidAirMinigun : public CBaseTFAchievement
  417. {
  418. void Init()
  419. {
  420. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  421. SetGoal( 10 );
  422. SetStoreProgressInSteam( true );
  423. }
  424. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  425. {
  426. if ( !pVictim || !pVictim->IsPlayer() )
  427. return;
  428. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_MINIGUN )
  429. {
  430. if ( !( pVictim->GetFlags() & FL_ONGROUND ) )
  431. {
  432. IncrementCount();
  433. }
  434. }
  435. }
  436. };
  437. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillMidAirMinigun, ACHIEVEMENT_TF_HEAVY_KILL_MIDAIR_MINIGUN, "TF_HEAVY_KILL_MIDAIR_MINIGUN", 5 );
  438. //----------------------------------------------------------------------------------------------------------------
  439. class CAchievementTFHeavy_DefendControlPoint : public CBaseTFAchievement
  440. {
  441. void Init()
  442. {
  443. SetFlags( ACH_SAVE_GLOBAL );
  444. SetGoal( 25 );
  445. SetStoreProgressInSteam( true );
  446. }
  447. // server awards this achievement, no other code within achievement necessary
  448. };
  449. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_DefendControlPoint, ACHIEVEMENT_TF_HEAVY_DEFEND_CONTROL_POINT, "TF_HEAVY_DEFEND_CONTROL_POINT", 5 );
  450. //----------------------------------------------------------------------------------------------------------------
  451. class CAchievementTFHeavy_FireLots : public CBaseTFAchievement
  452. {
  453. void Init()
  454. {
  455. SetFlags( ACH_SAVE_GLOBAL );
  456. SetGoal( 1 );
  457. }
  458. // client weapon fires an event for this achievement, no other code within achievement necessary
  459. };
  460. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_FireLots, ACHIEVEMENT_TF_HEAVY_FIRE_LOTS, "TF_HEAVY_FIRE_LOTS", 5 );
  461. //----------------------------------------------------------------------------------------------------------------
  462. class CAchievementTFHeavy_KillWithShotgun : public CBaseTFAchievement
  463. {
  464. void Init()
  465. {
  466. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  467. SetGoal( 1 );
  468. }
  469. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  470. {
  471. if ( !pVictim || !pVictim->IsPlayer() )
  472. return;
  473. CTFPlayer *pAttackingPlayer = ToTFPlayer( pAttacker );
  474. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && pAttackingPlayer->GetAmmoCount( TF_AMMO_PRIMARY ) <= 0 &&
  475. event->GetInt( "weaponid" ) == TF_WEAPON_SHOTGUN_HWG )
  476. {
  477. IncrementCount();
  478. }
  479. }
  480. };
  481. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillWithShotgun, ACHIEVEMENT_TF_HEAVY_KILL_SHOTGUN, "TF_HEAVY_KILL_SHOTGUN", 5 );
  482. //----------------------------------------------------------------------------------------------------------------
  483. class CAchievementTFHeavy_EarnDominationForMedic : public CBaseTFAchievement
  484. {
  485. void Init()
  486. {
  487. SetFlags( ACH_SAVE_GLOBAL );
  488. SetGoal( 1 );
  489. }
  490. // server awards this achievement, no other code within achievement necessary
  491. };
  492. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_EarnDominationForMedic, ACHIEVEMENT_TF_HEAVY_EARN_MEDIC_DOMINATION, "TF_HEAVY_EARN_MEDIC_DOMINATION", 5 );
  493. //----------------------------------------------------------------------------------------------------------------
  494. class CAchievementTFHeavy_ClearStickybombs : public CBaseTFAchievement
  495. {
  496. void Init()
  497. {
  498. SetFlags( ACH_SAVE_GLOBAL );
  499. SetGoal( 20 );
  500. SetStoreProgressInSteam( true );
  501. }
  502. // server awards this achievement, no other code within achievement necessary
  503. };
  504. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_ClearStickybombs, ACHIEVEMENT_TF_HEAVY_CLEAR_STICKYBOMBS, "TF_HEAVY_CLEAR_STICKYBOMBS", 5 );
  505. //----------------------------------------------------------------------------------------------------------------
  506. class CAchievementTFHeavy_FirstToCap : public CBaseTFAchievement
  507. {
  508. void Init()
  509. {
  510. SetFlags( ACH_SAVE_GLOBAL );
  511. SetGoal( 1 );
  512. }
  513. virtual void ListenForEvents()
  514. {
  515. ListenForGameEvent( "teamplay_round_active" );
  516. ListenForGameEvent( "teamplay_point_startcapture" );
  517. m_bTeamCappedThisRound = false;
  518. }
  519. void FireGameEvent_Internal( IGameEvent *event )
  520. {
  521. if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  522. {
  523. m_bTeamCappedThisRound = false;
  524. }
  525. else if ( FStrEq( event->GetName(), "teamplay_point_startcapture" ) )
  526. {
  527. // only on maps with capture points
  528. if ( TFGameRules() && TFGameRules()->GetGameType() != TF_GAMETYPE_CP && TFGameRules()->GetGameType() != TF_GAMETYPE_ARENA )
  529. return;
  530. // we've already started a capture this round
  531. if ( m_bTeamCappedThisRound )
  532. return;
  533. // is this event about our team?
  534. if ( GetLocalPlayerTeam() == event->GetInt( "capteam" ) )
  535. {
  536. m_bTeamCappedThisRound = true;
  537. // we need to have started the capture by ourselves...not standing on the point with a group of people
  538. const char *cappers = event->GetString( "cappers" );
  539. if ( Q_strlen( cappers ) == 1 )
  540. {
  541. // is the capper the local player?
  542. if ( GetLocalPlayerIndex() == (int)cappers[0] )
  543. {
  544. IncrementCount();
  545. }
  546. }
  547. }
  548. }
  549. }
  550. private:
  551. bool m_bTeamCappedThisRound;
  552. };
  553. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_FirstToCap, ACHIEVEMENT_TF_HEAVY_FIRST_TO_CAP, "TF_HEAVY_FIRST_TO_CAP", 5 );
  554. //----------------------------------------------------------------------------------------------------------------
  555. class CAchievementTFHeavy_KillTaunt : public CBaseTFAchievement
  556. {
  557. void Init()
  558. {
  559. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  560. SetGoal( 1 );
  561. }
  562. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  563. {
  564. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  565. if ( pAttacker == pLocalPlayer )
  566. {
  567. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  568. if ( pTFVictim && event->GetInt( "customkill" ) == TF_DMG_CUSTOM_TAUNTATK_HIGH_NOON )
  569. {
  570. IncrementCount();
  571. }
  572. }
  573. }
  574. };
  575. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillTaunt, ACHIEVEMENT_TF_HEAVY_KILL_TAUNT, "TF_HEAVY_KILL_TAUNT", 5 );
  576. //----------------------------------------------------------------------------------------------------------------
  577. class CAchievementTFHeavy_TeleportFastKill : public CTFAchievementTeleporterTimingKills<CBaseTFAchievement>
  578. {
  579. // stub -- all code in parent class
  580. };
  581. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_TeleportFastKill, ACHIEVEMENT_TF_HEAVY_TELEPORT_FAST_KILL, "TF_HEAVY_TELEPORT_FAST_KILL", 5 );
  582. //----------------------------------------------------------------------------------------------------------------
  583. class CAchievementTFHeavy_FreezecamTaunt : public CBaseTFAchievement
  584. {
  585. void Init()
  586. {
  587. SetFlags( ACH_SAVE_GLOBAL );
  588. SetGoal( 1 );
  589. }
  590. // server awards this achievement, no other code within achievement necessary
  591. };
  592. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_FreezecamTaunt, ACHIEVEMENT_TF_HEAVY_FREEZECAM_TAUNT, "TF_HEAVY_FREEZECAM_TAUNT", 5 );
  593. //----------------------------------------------------------------------------------------------------------------
  594. class CAchievementTFHeavy_RevengeAssist : public CBaseTFAchievement
  595. {
  596. void Init()
  597. {
  598. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  599. SetGoal( 5 );
  600. SetStoreProgressInSteam( true );
  601. }
  602. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  603. {
  604. if ( !pVictim || !pVictim->IsPlayer() )
  605. return;
  606. if ( pAttacker == C_BasePlayer::GetLocalPlayer() )
  607. {
  608. // did the assister get revenge?
  609. if ( event->GetInt( "death_flags" ) & TF_DEATH_ASSISTER_REVENGE )
  610. {
  611. IncrementCount();
  612. }
  613. }
  614. else
  615. {
  616. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  617. if ( iAssisterIndex > 0 )
  618. {
  619. if ( iAssisterIndex == GetLocalPlayerIndex() )
  620. {
  621. // did the attacker get revenge?
  622. if ( event->GetInt( "death_flags" ) & TF_DEATH_REVENGE )
  623. {
  624. IncrementCount();
  625. }
  626. }
  627. }
  628. }
  629. }
  630. };
  631. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_RevengeAssist, ACHIEVEMENT_TF_HEAVY_REVENGE_ASSIST, "TF_HEAVY_REVENGE_ASSIST", 5 );
  632. //----------------------------------------------------------------------------------------------------------------
  633. class CAchievementTFHeavy_DefendMedic : public CBaseTFAchievement
  634. {
  635. void Init()
  636. {
  637. SetFlags( ACH_SAVE_GLOBAL );
  638. SetGoal( 50 );
  639. SetStoreProgressInSteam( true );
  640. }
  641. // server awards this achievement, no other code within achievement necessary
  642. };
  643. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_DefendMedic, ACHIEVEMENT_TF_HEAVY_DEFEND_MEDIC, "TF_HEAVY_DEFEND_MEDIC", 5 );
  644. //----------------------------------------------------------------------------------------------------------------
  645. class CAchievementTFHeavy_KillCappingEnemies : public CBaseTFAchievement
  646. {
  647. void Init()
  648. {
  649. SetFlags( ACH_SAVE_GLOBAL );
  650. SetGoal( 15 );
  651. SetStoreProgressInSteam( true );
  652. }
  653. // server awards this achievement, no other code within achievement necessary
  654. };
  655. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillCappingEnemies, ACHIEVEMENT_TF_HEAVY_KILL_CAPPING_ENEMIES, "TF_HEAVY_KILL_CAPPING_ENEMIES", 5 );
  656. //----------------------------------------------------------------------------------------------------------------
  657. class CAchievementTFHeavy_BlockInvulnHeavy : public CBaseTFAchievement
  658. {
  659. void Init()
  660. {
  661. SetFlags( ACH_SAVE_GLOBAL );
  662. SetGoal( 1 );
  663. }
  664. // server awards this achievement, no other code within achievement necessary
  665. };
  666. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_BlockInvulnHeavy, ACHIEVEMENT_TF_HEAVY_BLOCK_INVULN_HEAVY, "TF_HEAVY_BLOCK_INVULN_HEAVY", 5 );
  667. //----------------------------------------------------------------------------------------------------------------
  668. class CAchievementTFHeavy_KillFlagCarriers : public CBaseTFAchievement
  669. {
  670. void Init()
  671. {
  672. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  673. SetGoal( 10 );
  674. SetStoreProgressInSteam( true );
  675. }
  676. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  677. {
  678. if ( !pVictim || !pVictim->IsPlayer() )
  679. return;
  680. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && pVictim != C_BasePlayer::GetLocalPlayer() )
  681. {
  682. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  683. if ( pTFVictim && pTFVictim->HasTheFlag() )
  684. {
  685. IncrementCount();
  686. }
  687. }
  688. }
  689. };
  690. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillFlagCarriers, ACHIEVEMENT_TF_HEAVY_KILL_FLAG_CARRIERS, "TF_HEAVY_KILL_FLAG_CARRIERS", 5 );
  691. //----------------------------------------------------------------------------------------------------------------
  692. class CAchievementTFHeavy_StandNearDispenser : public CBaseTFAchievement
  693. {
  694. void Init()
  695. {
  696. SetFlags( ACH_SAVE_GLOBAL );
  697. SetGoal( 20 );
  698. SetStoreProgressInSteam( true );
  699. }
  700. // server awards this achievement, no other code within achievement necessary
  701. };
  702. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_StandNearDispenser, ACHIEVEMENT_TF_HEAVY_STAND_NEAR_DISPENSER, "TF_HEAVY_STAND_NEAR_DISPENSER", 5 );
  703. //----------------------------------------------------------------------------------------------------------------
  704. class CAchievementTFHeavy_EatSandwiches : public CBaseTFAchievement
  705. {
  706. void Init()
  707. {
  708. SetFlags( ACH_SAVE_GLOBAL );
  709. SetGoal( 100 );
  710. SetStoreProgressInSteam( true );
  711. }
  712. // server awards this achievement, no other code within achievement necessary
  713. };
  714. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_EatSandwiches, ACHIEVEMENT_TF_HEAVY_EAT_SANDWICHES, "TF_HEAVY_EAT_SANDWICHES", 5 );
  715. //----------------------------------------------------------------------------------------------------------------
  716. class CAchievementTFHeavy_KillScouts : public CBaseTFAchievement
  717. {
  718. void Init()
  719. {
  720. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  721. SetGoal( 50 );
  722. SetStoreProgressInSteam( true );
  723. }
  724. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  725. {
  726. if ( !pVictim || !pVictim->IsPlayer() )
  727. return;
  728. if ( pAttacker == C_BasePlayer::GetLocalPlayer() && event->GetInt( "weaponid" ) == TF_WEAPON_MINIGUN )
  729. {
  730. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  731. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_SCOUT ) )
  732. {
  733. if ( FStrEq( event->GetString( "weapon_logclassname", "" ), "natascha" ) )
  734. {
  735. IncrementCount();
  736. }
  737. }
  738. }
  739. }
  740. };
  741. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillScouts, ACHIEVEMENT_TF_HEAVY_KILL_SCOUTS, "TF_HEAVY_KILL_SCOUTS", 5 );
  742. //----------------------------------------------------------------------------------------------------------------
  743. class CAchievementTFHeavy_BlockCart : public CBaseTFAchievement
  744. {
  745. void Init()
  746. {
  747. SetFlags( ACH_SAVE_GLOBAL );
  748. SetGoal( 25 );
  749. SetStoreProgressInSteam( true );
  750. }
  751. virtual void ListenForEvents()
  752. {
  753. ListenForGameEvent( "teamplay_capture_blocked" );
  754. }
  755. void FireGameEvent_Internal( IGameEvent *event )
  756. {
  757. if ( !TFGameRules() || TFGameRules()->GetGameType() != TF_GAMETYPE_ESCORT )
  758. return;
  759. if ( Q_strcmp( event->GetName(), "teamplay_capture_blocked" ) == 0 )
  760. {
  761. int index = event->GetInt( "blocker", 0 );
  762. if ( index == GetLocalPlayerIndex() )
  763. {
  764. IncrementCount();
  765. }
  766. }
  767. }
  768. };
  769. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_BlockCart, ACHIEVEMENT_TF_HEAVY_BLOCK_CART, "TF_HEAVY_BLOCK_CART", 5 );
  770. //----------------------------------------------------------------------------------------------------------------
  771. #define MAX_PARTNERS 12
  772. class CAchievementTFHeavy_AssistMedicLarge : public CBaseTFAchievement
  773. {
  774. void Init()
  775. {
  776. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  777. SetGoal( 1 );
  778. }
  779. virtual void ListenForEvents()
  780. {
  781. ListenForGameEvent( "teamplay_round_active" );
  782. ListenForGameEvent( "localplayer_respawn" );
  783. }
  784. void FireGameEvent_Internal( IGameEvent *event )
  785. {
  786. if ( FStrEq( event->GetName(), "teamplay_round_active" ) ||
  787. FStrEq( event->GetName(), "localplayer_respawn" ) )
  788. {
  789. m_Partners.Purge();
  790. }
  791. }
  792. int GetPartnerIndex( CBaseEntity *pPlayer )
  793. {
  794. for ( int i = 0; i < m_Partners.Count(); i++ )
  795. {
  796. if ( m_Partners[i].hPartner == pPlayer )
  797. return i;
  798. }
  799. return -1;
  800. }
  801. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  802. {
  803. if ( !pVictim || !pVictim->IsPlayer() )
  804. return;
  805. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  806. if ( pLocalPlayer )
  807. {
  808. if ( pVictim->GetTeamNumber() != pLocalPlayer->GetTeamNumber() )
  809. {
  810. if ( pLocalPlayer == pAttacker )
  811. {
  812. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  813. if ( iAssisterIndex > 0 )
  814. {
  815. C_TFPlayer *pTFAssister = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
  816. if ( pTFAssister && pTFAssister->IsPlayerClass( TF_CLASS_MEDIC ) )
  817. {
  818. int index = GetPartnerIndex( pTFAssister );
  819. if ( index == -1 )
  820. {
  821. if ( m_Partners.Count() >= MAX_PARTNERS )
  822. {
  823. // Remove the one with the least assists
  824. int iLowest = 999;
  825. int iLowestIndex = -1;
  826. for ( int i = 0; i < m_Partners.Count(); i++ )
  827. {
  828. if ( !m_Partners[i].hPartner )
  829. {
  830. // Player is gone. Lets remove that one.
  831. iLowestIndex = i;
  832. break;
  833. }
  834. if ( m_Partners[i].iAssists < iLowest )
  835. {
  836. iLowestIndex = i;
  837. iLowest = m_Partners[i].iAssists;
  838. }
  839. }
  840. if ( iLowestIndex >= 0 )
  841. {
  842. //Msg("FULL Removed %d (%s)\n", iLowestIndex, g_PR->GetPlayerName(m_Partners[iLowestIndex].hPartner->entindex()) );
  843. m_Partners.Remove(iLowestIndex);
  844. }
  845. }
  846. int iNewIndex = m_Partners.AddToTail();
  847. m_Partners[iNewIndex].hPartner = pTFAssister;
  848. m_Partners[iNewIndex].iAssists = 1;
  849. //Msg("Inserted %s into %d\n", g_PR->GetPlayerName(pTFAssister->entindex()), iNewIndex );
  850. }
  851. else
  852. {
  853. m_Partners[index].iAssists++;
  854. //Msg("Incremented %s in %d to %d\n", g_PR->GetPlayerName(m_Partners[index].hPartner->entindex()), index, m_Partners[index].iAssists );
  855. if ( m_Partners[index].iAssists >= 10 )
  856. {
  857. IncrementCount();
  858. }
  859. }
  860. }
  861. else
  862. {
  863. // Ensure this guy isn't in our list. We can have non-medics in our list if we
  864. // earn an assist with them, and then they switch classes in the respawn room.
  865. int index = GetPartnerIndex( pTFAssister );
  866. if ( index != -1 )
  867. {
  868. m_Partners.Remove(index);
  869. }
  870. }
  871. }
  872. }
  873. }
  874. // See if it's one of our partners
  875. int index = GetPartnerIndex( pVictim );
  876. if ( index != -1 )
  877. {
  878. //Msg("DEATH: Removed %d (%s)\n", index, g_PR->GetPlayerName(m_Partners[index].hPartner->entindex()) );
  879. m_Partners.Remove( index );
  880. }
  881. /*
  882. Msg("State:\n");
  883. for ( int i = 0; i < m_Partners.Count(); i++ )
  884. {
  885. if ( m_Partners[i].hPartner )
  886. {
  887. Msg(" %d: %s with %d\n", i, g_PR->GetPlayerName(m_Partners[i].hPartner->entindex()), m_Partners[i].iAssists );
  888. }
  889. else
  890. {
  891. Msg(" %d: EMPTY\n", i );
  892. }
  893. }
  894. */
  895. }
  896. }
  897. private:
  898. struct partners_t
  899. {
  900. EHANDLE hPartner;
  901. int iAssists;
  902. };
  903. CUtlVector<partners_t> m_Partners;
  904. };
  905. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AssistMedicLarge, ACHIEVEMENT_TF_HEAVY_ASSIST_MEDIC_LARGE, "TF_HEAVY_ASSIST_MEDIC_LARGE", 5 );
  906. //----------------------------------------------------------------------------------------------------------------
  907. class CAchievementTFHeavy_KillMedicPair : public CBaseTFAchievement
  908. {
  909. void Init()
  910. {
  911. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_ENEMY_EVENTS );
  912. SetGoal( 1 );
  913. }
  914. virtual void ListenForEvents( void )
  915. {
  916. ListenForGameEvent( "localplayer_respawn" );
  917. ListenForGameEvent( "teamplay_round_active" );
  918. m_hTargets.Purge();
  919. }
  920. void FireGameEvent_Internal( IGameEvent *event )
  921. {
  922. const char *pszEventName = event->GetName();
  923. if ( FStrEq( pszEventName, "localplayer_respawn" ) ||
  924. FStrEq( pszEventName, "teamplay_round_active" ) )
  925. {
  926. m_hTargets.Purge();
  927. }
  928. }
  929. int GetTargetIndex( CBaseEntity *pTarget )
  930. {
  931. for ( int i = 0; i < m_hTargets.Count(); i++ )
  932. {
  933. if ( m_hTargets[i].hTarget == pTarget )
  934. return i;
  935. }
  936. return -1;
  937. }
  938. void AddNewTarget( CBaseEntity *pTarget, CBaseEntity *pPartner )
  939. {
  940. if ( !pTarget || !pPartner )
  941. return;
  942. // see if the target is already in our list or get a new index
  943. int iTargetIndex = GetTargetIndex( pTarget );
  944. if ( iTargetIndex == -1 )
  945. {
  946. iTargetIndex = m_hTargets.AddToTail();
  947. }
  948. m_hTargets[iTargetIndex].hPartner = pPartner;
  949. m_hTargets[iTargetIndex].hTarget = pTarget;
  950. m_hTargets[iTargetIndex].flTimeToBeat = gpGlobals->curtime + 15.0f; // 15 seconds to kill the target
  951. }
  952. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  953. {
  954. if ( !pVictim || !pVictim->IsPlayer() )
  955. return;
  956. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  957. if ( pLocalPlayer )
  958. {
  959. int iAssisterIndex = engine->GetPlayerForUserID( event->GetInt( "assister" ) );
  960. if ( iAssisterIndex > 0 )
  961. {
  962. C_TFPlayer *pTFAssister = ToTFPlayer( UTIL_PlayerByIndex( iAssisterIndex ) );
  963. C_TFPlayer *pTFAttacker = ToTFPlayer( pAttacker );
  964. if ( ( pTFAttacker == pLocalPlayer && ( pTFAssister && pTFAssister->IsPlayerClass( TF_CLASS_MEDIC ) ) ) ||
  965. ( pTFAssister == pLocalPlayer && ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_MEDIC ) ) ) )
  966. {
  967. C_TFPlayer *pPartner = ( pTFAttacker == pLocalPlayer ) ? pTFAssister : pTFAttacker;
  968. // is this victim in our list of targets?
  969. int index = GetTargetIndex( pVictim );
  970. if ( index != -1 )
  971. {
  972. // did we kill them with the correct partner?
  973. if ( m_hTargets[index].hPartner == pPartner )
  974. {
  975. // did we beat the time?
  976. if ( m_hTargets[index].flTimeToBeat > gpGlobals->curtime )
  977. {
  978. IncrementCount();
  979. }
  980. }
  981. }
  982. else
  983. {
  984. C_TFPlayer *pNewTarget = NULL;
  985. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  986. if ( pTFVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  987. {
  988. for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
  989. {
  990. pNewTarget = ToTFPlayer( UTIL_PlayerByIndex( i ) );
  991. if ( pNewTarget && pNewTarget->IsPlayerClass( TF_CLASS_MEDIC ) && pNewTarget->MedicGetHealTarget() == pTFVictim )
  992. {
  993. // add all of his Medics to our list of targets (could be more than one Medic)
  994. AddNewTarget( pNewTarget, pPartner );
  995. }
  996. }
  997. }
  998. else if ( pTFVictim->IsPlayerClass( TF_CLASS_MEDIC ) )
  999. {
  1000. pNewTarget = ToTFPlayer( pTFVictim->MedicGetHealTarget() );
  1001. if ( pNewTarget && pNewTarget->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  1002. {
  1003. AddNewTarget( pNewTarget, pPartner );
  1004. }
  1005. }
  1006. }
  1007. }
  1008. }
  1009. }
  1010. // is this victim in our list of targets?
  1011. int index = GetTargetIndex( pVictim );
  1012. if ( index != -1 )
  1013. {
  1014. m_hTargets.Remove( index );
  1015. }
  1016. }
  1017. private:
  1018. struct targets_t
  1019. {
  1020. EHANDLE hPartner;
  1021. EHANDLE hTarget;
  1022. float flTimeToBeat;
  1023. };
  1024. CUtlVector<targets_t> m_hTargets;
  1025. };
  1026. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_KillMedicPair, ACHIEVEMENT_TF_HEAVY_KILL_MEDIC_PAIR, "TF_HEAVY_KILL_MEDIC_PAIR", 5 );
  1027. //----------------------------------------------------------------------------------------------------------------
  1028. class CAchievementTFHeavy_AchieveProgress1 : public CAchievement_AchievedCount
  1029. {
  1030. public:
  1031. DECLARE_CLASS( CAchievementTFHeavy_AchieveProgress1, CAchievement_AchievedCount );
  1032. void Init()
  1033. {
  1034. BaseClass::Init();
  1035. SetAchievementsRequired( 10, ACHIEVEMENT_TF_HEAVY_START_RANGE, ACHIEVEMENT_TF_HEAVY_END_RANGE );
  1036. }
  1037. };
  1038. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AchieveProgress1, ACHIEVEMENT_TF_HEAVY_ACHIEVE_PROGRESS1, "TF_HEAVY_ACHIEVE_PROGRESS1", 5 );
  1039. //----------------------------------------------------------------------------------------------------------------
  1040. class CAchievementTFHeavy_AchieveProgress2 : public CAchievement_AchievedCount
  1041. {
  1042. public:
  1043. DECLARE_CLASS( CAchievementTFHeavy_AchieveProgress2, CAchievement_AchievedCount );
  1044. void Init()
  1045. {
  1046. BaseClass::Init();
  1047. SetAchievementsRequired( 16, ACHIEVEMENT_TF_HEAVY_START_RANGE, ACHIEVEMENT_TF_HEAVY_END_RANGE );
  1048. }
  1049. };
  1050. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AchieveProgress2, ACHIEVEMENT_TF_HEAVY_ACHIEVE_PROGRESS2, "TF_HEAVY_ACHIEVE_PROGRESS2", 5 );
  1051. //----------------------------------------------------------------------------------------------------------------
  1052. class CAchievementTFHeavy_AchieveProgress3 : public CAchievement_AchievedCount
  1053. {
  1054. public:
  1055. DECLARE_CLASS( CAchievementTFHeavy_AchieveProgress3, CAchievement_AchievedCount );
  1056. void Init()
  1057. {
  1058. BaseClass::Init();
  1059. SetAchievementsRequired( 22, ACHIEVEMENT_TF_HEAVY_START_RANGE, ACHIEVEMENT_TF_HEAVY_END_RANGE );
  1060. }
  1061. };
  1062. DECLARE_ACHIEVEMENT( CAchievementTFHeavy_AchieveProgress3, ACHIEVEMENT_TF_HEAVY_ACHIEVE_PROGRESS3, "TF_HEAVY_ACHIEVE_PROGRESS3", 5 );
  1063. #endif // CLIENT_DLL