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.

1798 lines
47 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 "c_tf_objective_resource.h"
  15. #include "tf_gamerules.h"
  16. #include "achievements_tf.h"
  17. #include "tf_item_powerup_bottle.h"
  18. //----------------------------------------------------------------------------------------------------------------
  19. class CAchievementTF_MvM_CompletePopFile : public CBaseTFAchievementSimple
  20. {
  21. void Init()
  22. {
  23. SetFlags( ACH_SAVE_GLOBAL );
  24. SetGoal( 1 );
  25. m_bPlayedEntireMission = false;
  26. }
  27. virtual void ListenForEvents()
  28. {
  29. ListenForGameEvent( "mvm_begin_wave" );
  30. ListenForGameEvent( "mvm_mission_complete" );
  31. }
  32. void FireGameEvent_Internal( IGameEvent *event )
  33. {
  34. const char *pszEventName = event->GetName();
  35. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  36. {
  37. if ( event->GetInt( "wave_index" ) == 0 )
  38. {
  39. m_bPlayedEntireMission = true;
  40. }
  41. }
  42. else if ( FStrEq( pszEventName, "mvm_mission_complete" ) )
  43. {
  44. if ( m_bPlayedEntireMission )
  45. {
  46. AwardAchievement();
  47. }
  48. }
  49. }
  50. private:
  51. bool m_bPlayedEntireMission;
  52. };
  53. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_CompletePopFile, ACHIEVEMENT_TF_MVM_COMPLETE_POP_FILE, "TF_MVM_COMPLETE_POP_FILE", 5 );
  54. //----------------------------------------------------------------------------------------------------------------
  55. class CAchievementTF_MvM_EarnMoneyBonus : public CBaseTFAchievementSimple
  56. {
  57. public:
  58. void Init()
  59. {
  60. SetFlags( ACH_SAVE_GLOBAL );
  61. SetGoal( 1 );
  62. m_bPlayedEntireWave = false;
  63. }
  64. virtual void ListenForEvents()
  65. {
  66. ListenForGameEvent( "teamplay_round_active" );
  67. ListenForGameEvent( "mvm_creditbonus_wave" );
  68. }
  69. void FireGameEvent_Internal( IGameEvent *event )
  70. {
  71. const char *pszEventName = event->GetName();
  72. if ( FStrEq( pszEventName, "teamplay_round_active" ) )
  73. {
  74. m_bPlayedEntireWave = true;
  75. }
  76. else if ( FStrEq( pszEventName, "mvm_creditbonus_wave" ) )
  77. {
  78. if ( m_bPlayedEntireWave )
  79. {
  80. AwardAchievement();
  81. }
  82. }
  83. }
  84. private:
  85. bool m_bPlayedEntireWave;
  86. };
  87. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_EarnMoneyBonus, ACHIEVEMENT_TF_MVM_EARN_MONEY_BONUS, "TF_MVM_EARN_MONEY_BONUS", 5 );
  88. //----------------------------------------------------------------------------------------------------------------
  89. class CAchievementTF_MvM_AdvancedEarnAllBonuses : public CBaseTFAchievementSimple
  90. {
  91. public:
  92. void Init()
  93. {
  94. SetFlags( ACH_SAVE_GLOBAL );
  95. SetGoal( 1 );
  96. m_bPlayedEntireMission = false;
  97. }
  98. virtual void ListenForEvents()
  99. {
  100. ListenForGameEvent( "mvm_begin_wave" );
  101. ListenForGameEvent( "mvm_creditbonus_all_advanced" );
  102. }
  103. void FireGameEvent_Internal( IGameEvent *event )
  104. {
  105. const char *pszEventName = event->GetName();
  106. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  107. {
  108. if ( event->GetInt( "wave_index" ) == 0 )
  109. {
  110. m_bPlayedEntireMission = true;
  111. }
  112. }
  113. else if ( FStrEq( pszEventName, "mvm_creditbonus_all_advanced" ) )
  114. {
  115. if ( m_bPlayedEntireMission )
  116. {
  117. AwardAchievement();
  118. }
  119. }
  120. }
  121. private:
  122. bool m_bPlayedEntireMission;
  123. };
  124. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_AdvancedEarnAllBonuses, ACHIEVEMENT_TF_MVM_ADVANCED_EARN_ALL_BONUSES, "TF_MVM_ADVANCED_EARN_ALL_BONUSES", 5 );
  125. //----------------------------------------------------------------------------------------------------------------
  126. class CAchievementTF_MvM_PickupMoneyAboutToExpire : public CBaseTFAchievementSimple
  127. {
  128. public:
  129. void Init()
  130. {
  131. SetFlags( ACH_SAVE_GLOBAL );
  132. SetGoal( 1 );
  133. }
  134. // server awards this achievement, no other code within achievement necessary
  135. };
  136. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_PickupMoneyAboutToExpire, ACHIEVEMENT_TF_MVM_PICKUP_MONEY_ABOUT_TO_EXPIRE, "TF_MVM_PICKUP_MONEY_ABOUT_TO_EXPIRE", 5 );
  137. //----------------------------------------------------------------------------------------------------------------
  138. class CAchievementTF_MvM_CollectMoneyGrind : public CBaseTFAchievementSimple
  139. {
  140. public:
  141. void Init()
  142. {
  143. SetFlags( ACH_SAVE_GLOBAL );
  144. SetGoal( 1000000 );
  145. SetStoreProgressInSteam( true );
  146. }
  147. virtual void ListenForEvents()
  148. {
  149. ListenForGameEvent( "mvm_pickup_currency" );
  150. }
  151. void FireGameEvent_Internal( IGameEvent *event )
  152. {
  153. if ( FStrEq( event->GetName(), "mvm_pickup_currency" ) )
  154. {
  155. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  156. {
  157. IncrementCount( event->GetInt( "currency" ) );
  158. }
  159. }
  160. }
  161. };
  162. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_CollectMoneyGrind, ACHIEVEMENT_TF_MVM_COLLECT_MONEY_GRIND, "TF_MVM_COLLECT_MONEY_GRIND", 5 );
  163. //----------------------------------------------------------------------------------------------------------------
  164. class CAchievementTF_MvM_PlayGameFriends : public CBaseTFAchievementSimple
  165. {
  166. public:
  167. void Init()
  168. {
  169. SetFlags( ACH_SAVE_GLOBAL );
  170. SetGoal( 1 );
  171. }
  172. virtual void ListenForEvents()
  173. {
  174. ListenForGameEvent( "mvm_mission_complete" );
  175. }
  176. void FireGameEvent_Internal( IGameEvent *event )
  177. {
  178. if ( FStrEq( event->GetName(), "mvm_mission_complete" ) )
  179. {
  180. if ( CalcPlayersOnFriendsList( 5 ) )
  181. {
  182. AwardAchievement();
  183. }
  184. }
  185. }
  186. };
  187. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_PlayGameFriends, ACHIEVEMENT_TF_MVM_PLAY_GAME_FRIENDS, "TF_MVM_PLAY_GAME_FRIENDS", 5 );
  188. //----------------------------------------------------------------------------------------------------------------
  189. class CAchievementTF_MvM_PlayEachClass : public CBaseTFAchievementSimple
  190. {
  191. public:
  192. void Init()
  193. {
  194. SetFlags( ACH_SAVE_GLOBAL | ACH_HAS_COMPONENTS );
  195. SetGoal( ( TF_LAST_NORMAL_CLASS - 1 ) - TF_FIRST_NORMAL_CLASS + 1 ); //( TF_LAST_NORMAL_CLASS - 1 ) to exclude the new civilian class
  196. m_bChangedClass = true;
  197. }
  198. virtual void ListenForEvents()
  199. {
  200. ListenForGameEvent( "mvm_begin_wave" );
  201. ListenForGameEvent( "localplayer_changeclass" );
  202. ListenForGameEvent( "localplayer_changeteam" );
  203. ListenForGameEvent( "mvm_mission_complete" );
  204. }
  205. void FireGameEvent_Internal( IGameEvent *event )
  206. {
  207. const char *pszEventName = event->GetName();
  208. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  209. {
  210. if ( event->GetInt( "wave_index" ) == 0 )
  211. {
  212. // beginning the first wave...lock down class changes
  213. m_bChangedClass = false;
  214. }
  215. }
  216. else if ( FStrEq( pszEventName, "localplayer_changeclass" ) || // can't change class or team after the first round starts
  217. FStrEq( pszEventName, "localplayer_changeteam" ) )
  218. {
  219. m_bChangedClass = true;
  220. }
  221. else if ( FStrEq( pszEventName, "mvm_mission_complete" ) )
  222. {
  223. if ( !m_bChangedClass )
  224. {
  225. C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  226. if ( pTFPlayer )
  227. {
  228. int iClass = pTFPlayer->GetPlayerClass()->GetClassIndex();
  229. if ( iClass >= TF_FIRST_NORMAL_CLASS && iClass <= ( TF_LAST_NORMAL_CLASS - 1 ) ) //( TF_LAST_NORMAL_CLASS - 1 ) to exclude the new civilian class
  230. {
  231. // yes, the achievement is satisfied for this class, set the corresponding bit
  232. int iBitNumber =( iClass - TF_FIRST_NORMAL_CLASS );
  233. EnsureComponentBitSetAndEvaluate( iBitNumber );
  234. }
  235. }
  236. }
  237. }
  238. }
  239. private:
  240. bool m_bChangedClass;
  241. };
  242. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_PlayEachClass, ACHIEVEMENT_TF_MVM_PLAY_EACH_CLASS, "TF_MVM_PLAY_EACH_CLASS", 5 );
  243. //----------------------------------------------------------------------------------------------------------------
  244. class CAchievementTF_MvM_DestroyTwoTanks : public CBaseTFAchievementSimple
  245. {
  246. public:
  247. void Init()
  248. {
  249. SetFlags( ACH_SAVE_GLOBAL );
  250. SetGoal( 1 );
  251. m_flLastTankDestroyedTime = 0.0f;
  252. }
  253. virtual void ListenForEvents()
  254. {
  255. ListenForGameEvent( "mvm_tank_destroyed_by_players" );
  256. ListenForGameEvent( "mvm_begin_wave" );
  257. }
  258. void FireGameEvent_Internal( IGameEvent *event )
  259. {
  260. if ( FStrEq( event->GetName(), "mvm_tank_destroyed_by_players" ) )
  261. {
  262. if ( m_flLastTankDestroyedTime > 0.0f )
  263. {
  264. if ( fabs( gpGlobals->curtime - m_flLastTankDestroyedTime ) <= 5.0f )
  265. {
  266. AwardAchievement();
  267. }
  268. }
  269. m_flLastTankDestroyedTime = gpGlobals->curtime;
  270. }
  271. if ( FStrEq( event->GetName(), "mvm_begin_wave" ) )
  272. {
  273. m_flLastTankDestroyedTime = 0.f;
  274. }
  275. }
  276. private:
  277. float m_flLastTankDestroyedTime;
  278. };
  279. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_DestroyTwoTanks, ACHIEVEMENT_TF_MVM_DESTROY_TWO_TANKS, "TF_MVM_DESTROY_TWO_TANKS", 5 );
  280. //----------------------------------------------------------------------------------------------------------------
  281. class CAchievementTF_MvM_DestroyTankWhileDeploying : public CBaseTFAchievementSimple
  282. {
  283. public:
  284. void Init()
  285. {
  286. SetFlags( ACH_SAVE_GLOBAL );
  287. SetGoal( 1 );
  288. }
  289. // server awards this achievement, no other code within achievement necessary
  290. };
  291. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_DestroyTankWhileDeploying, ACHIEVEMENT_TF_MVM_DESTROY_TANK_WHILE_DEPLOYING, "TF_MVM_DESTROY_TANK_WHILE_DEPLOYING", 5 );
  292. //----------------------------------------------------------------------------------------------------------------
  293. class CAchievementTF_MvM_DestroyTankQuickly : public CBaseTFAchievementSimple
  294. {
  295. public:
  296. void Init()
  297. {
  298. SetFlags( ACH_SAVE_GLOBAL );
  299. SetGoal( 1 );
  300. }
  301. // server awards this achievement, no other code within achievement necessary
  302. };
  303. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_DestroyTankQuickly, ACHIEVEMENT_TF_MVM_DESTROY_TANK_QUICKLY, "TF_MVM_DESTROY_TANK_QUICKLY", 5 );
  304. //----------------------------------------------------------------------------------------------------------------
  305. class CAchievementTF_MvM_DefendCap : public CBaseTFAchievementSimple
  306. {
  307. public:
  308. void Init()
  309. {
  310. SetFlags( ACH_SAVE_GLOBAL );
  311. SetGoal( 1 );
  312. iCount = 0;
  313. }
  314. virtual void ListenForEvents()
  315. {
  316. ListenForGameEvent( "teamplay_round_active" );
  317. ListenForGameEvent( "mvm_kill_robot_delivering_bomb" );
  318. }
  319. void FireGameEvent_Internal( IGameEvent *event )
  320. {
  321. const char *pszEventName = event->GetName();
  322. if ( FStrEq( pszEventName, "teamplay_round_active" ) )
  323. {
  324. iCount = 0;
  325. }
  326. else if ( FStrEq( pszEventName, "mvm_kill_robot_delivering_bomb" ) )
  327. {
  328. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  329. {
  330. iCount++;
  331. if ( iCount >= 10 )
  332. {
  333. AwardAchievement();
  334. }
  335. }
  336. }
  337. }
  338. private:
  339. int iCount;
  340. };
  341. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_DefendCap, ACHIEVEMENT_TF_MVM_DEFEND_CAP, "TF_MVM_DEFEND_CAP", 5 );
  342. //----------------------------------------------------------------------------------------------------------------
  343. class CAchievementTF_MvM_KillBombCarriers : public CBaseTFAchievementSimple
  344. {
  345. public:
  346. void Init()
  347. {
  348. SetFlags( ACH_SAVE_GLOBAL );
  349. SetGoal( 1 );
  350. m_nConsecutiveKillCount = 0;
  351. ACHIEVEMENT_COUNT = 15;
  352. }
  353. virtual void ListenForEvents()
  354. {
  355. ListenForGameEvent( "mvm_bomb_carrier_killed" );
  356. ListenForGameEvent( "teamplay_round_active" );
  357. }
  358. void FireGameEvent_Internal( IGameEvent *event )
  359. {
  360. if ( Q_strcmp( event->GetName(), "mvm_bomb_carrier_killed" ) == 0 )
  361. {
  362. if ( GetLocalPlayerTeam() != TF_TEAM_PVE_DEFENDERS )
  363. return;
  364. int nLevel = event->GetInt( "level" );
  365. if ( !nLevel )
  366. {
  367. m_nConsecutiveKillCount++;
  368. }
  369. else
  370. {
  371. m_nConsecutiveKillCount = 0;
  372. }
  373. }
  374. else if ( Q_strcmp( event->GetName(), "teamplay_round_active" ) == 0 )
  375. {
  376. m_nConsecutiveKillCount = 0;
  377. }
  378. if ( m_nConsecutiveKillCount >= ACHIEVEMENT_COUNT )
  379. {
  380. AwardAchievement();
  381. }
  382. }
  383. private:
  384. int m_nConsecutiveKillCount;
  385. int ACHIEVEMENT_COUNT;
  386. };
  387. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_KillBombCarriers, ACHIEVEMENT_TF_MVM_KILL_BOMB_CARRIERS, "TF_MVM_KILL_BOMB_CARRIERS", 5 );
  388. //----------------------------------------------------------------------------------------------------------------
  389. class CAchievementTF_MvM_CompleteWaveWithoutDying : public CBaseTFAchievementSimple
  390. {
  391. public:
  392. void Init()
  393. {
  394. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  395. SetGoal( 1 );
  396. bSurvivedEntireWave = false;
  397. }
  398. virtual void ListenForEvents()
  399. {
  400. ListenForGameEvent( "teamplay_round_active" );
  401. ListenForGameEvent( "mvm_wave_complete" );
  402. }
  403. void FireGameEvent_Internal( IGameEvent *event )
  404. {
  405. const char *pszEventName = event->GetName();
  406. if ( FStrEq( pszEventName, "teamplay_round_active" ) )
  407. {
  408. bSurvivedEntireWave = true;
  409. }
  410. else if ( FStrEq( pszEventName, "mvm_wave_complete" ) )
  411. {
  412. if ( event->GetBool( "advanced" ) )
  413. {
  414. if ( bSurvivedEntireWave )
  415. {
  416. AwardAchievement();
  417. }
  418. }
  419. }
  420. }
  421. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  422. {
  423. if ( pVictim && ( pVictim == C_BasePlayer::GetLocalPlayer() ) )
  424. {
  425. bSurvivedEntireWave = false;
  426. }
  427. }
  428. private:
  429. bool bSurvivedEntireWave;
  430. };
  431. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_CompleteWaveWithoutDying, ACHIEVEMENT_TF_MVM_COMPLETE_WAVE_WITHOUT_DYING, "TF_MVM_COMPLETE_WAVE_WITHOUT_DYING", 5 );
  432. //----------------------------------------------------------------------------------------------------------------
  433. class CAchievementTF_MvM_CompleteTour : public CBaseTFAchievementSimple
  434. {
  435. public:
  436. void Init()
  437. {
  438. SetFlags( ACH_SAVE_GLOBAL | ACH_HAS_COMPONENTS );
  439. static const char *szComponents[] =
  440. {
  441. "scripts/population/mvm_decoy.pop", "scripts/population/mvm_coaltown.pop", "scripts/population/mvm_mannworks.pop"
  442. };
  443. m_pszComponentNames = szComponents;
  444. m_iNumComponents = ARRAYSIZE( szComponents );
  445. SetGoal( m_iNumComponents );
  446. m_bPlayedEntireMission = false;
  447. }
  448. virtual void ListenForEvents()
  449. {
  450. ListenForGameEvent( "mvm_begin_wave" );
  451. ListenForGameEvent( "mvm_mission_complete" );
  452. }
  453. void FireGameEvent_Internal( IGameEvent *event )
  454. {
  455. const char *pszEventName = event->GetName();
  456. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  457. {
  458. if ( event->GetInt( "wave_index" ) == 0 )
  459. {
  460. m_bPlayedEntireMission = true;
  461. }
  462. }
  463. else if ( FStrEq( pszEventName, "mvm_mission_complete" ) )
  464. {
  465. if ( m_bPlayedEntireMission )
  466. {
  467. OnComponentEvent( event->GetString( "mission" ) );
  468. }
  469. }
  470. }
  471. private:
  472. bool m_bPlayedEntireMission;
  473. };
  474. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_CompleteTour, ACHIEVEMENT_TF_MVM_COMPLETE_TOUR, "TF_MVM_COMPLETE_TOUR", 5 );
  475. //----------------------------------------------------------------------------------------------------------------
  476. class CAchievementTF_MvM_UseTeleportBottle : public CBaseTFAchievementSimple
  477. {
  478. public:
  479. void Init()
  480. {
  481. SetFlags( ACH_SAVE_GLOBAL );
  482. SetGoal( 1 );
  483. m_flAchievementEndTime = 0.0f;
  484. }
  485. virtual void ListenForEvents()
  486. {
  487. ListenForGameEvent( "player_used_powerup_bottle" );
  488. ListenForGameEvent( "teamplay_flag_event" );
  489. }
  490. void FireGameEvent_Internal( IGameEvent *event )
  491. {
  492. const char *pszEventName = event->GetName();
  493. if ( FStrEq( pszEventName, "player_used_powerup_bottle" ) )
  494. {
  495. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  496. {
  497. if ( event->GetInt( "type" ) == POWERUP_BOTTLE_RECALL )
  498. {
  499. // defend the bomb within 5 seconds
  500. m_flAchievementEndTime = gpGlobals->curtime + 5.0f;
  501. }
  502. }
  503. }
  504. else if ( FStrEq( pszEventName, "teamplay_flag_event" ) )
  505. {
  506. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  507. {
  508. if ( event->GetInt( "eventtype" ) == TF_FLAGEVENT_DEFEND )
  509. {
  510. if ( gpGlobals->curtime < m_flAchievementEndTime )
  511. {
  512. AwardAchievement();
  513. }
  514. }
  515. }
  516. }
  517. }
  518. private:
  519. float m_flAchievementEndTime;
  520. };
  521. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_UseTeleportBottle, ACHIEVEMENT_TF_MVM_USE_TELEPORT_BOTTLE, "TF_MVM_USE_TELEPORT_BOTTLE", 5 );
  522. //----------------------------------------------------------------------------------------------------------------
  523. class CAchievementTF_MvM_UseCritBottle : public CBaseTFAchievementSimple
  524. {
  525. public:
  526. void Init()
  527. {
  528. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  529. SetGoal( 1 );
  530. m_flAchievementEndTime = 0.0f;
  531. }
  532. virtual void ListenForEvents()
  533. {
  534. ListenForGameEvent( "player_used_powerup_bottle" );
  535. }
  536. void FireGameEvent_Internal( IGameEvent *event )
  537. {
  538. const char *pszEventName = event->GetName();
  539. if ( FStrEq( pszEventName, "player_used_powerup_bottle" ) )
  540. {
  541. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  542. {
  543. if ( event->GetInt( "type" ) == POWERUP_BOTTLE_CRITBOOST )
  544. {
  545. C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  546. if ( pLocalTFPlayer )
  547. {
  548. m_flAchievementEndTime = gpGlobals->curtime + event->GetFloat( "time" );
  549. }
  550. }
  551. }
  552. }
  553. }
  554. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  555. {
  556. if ( gpGlobals->curtime < m_flAchievementEndTime )
  557. {
  558. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  559. if ( pTFVictim && pTFVictim->IsMiniBoss() )
  560. {
  561. AwardAchievement();
  562. }
  563. }
  564. }
  565. private:
  566. float m_flAchievementEndTime;
  567. };
  568. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_UseCritBottle, ACHIEVEMENT_TF_MVM_USE_CRIT_BOTTLE, "TF_MVM_USE_CRIT_BOTTLE", 5 );
  569. //----------------------------------------------------------------------------------------------------------------
  570. class CAchievementTF_MvM_UseUberBottle : public CBaseTFAchievementSimple
  571. {
  572. public:
  573. void Init()
  574. {
  575. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  576. SetGoal( 1 );
  577. m_iKillCount = 0;
  578. m_flAchievementEndTime = 0.0f;
  579. }
  580. virtual void ListenForEvents()
  581. {
  582. ListenForGameEvent( "player_used_powerup_bottle" );
  583. }
  584. void FireGameEvent_Internal( IGameEvent *event )
  585. {
  586. const char *pszEventName = event->GetName();
  587. if ( FStrEq( pszEventName, "player_used_powerup_bottle" ) )
  588. {
  589. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  590. {
  591. if ( event->GetInt( "type" ) == POWERUP_BOTTLE_UBERCHARGE )
  592. {
  593. m_flAchievementEndTime = gpGlobals->curtime + event->GetFloat( "time" );
  594. m_iKillCount = 0;
  595. }
  596. }
  597. }
  598. }
  599. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  600. {
  601. if ( gpGlobals->curtime < m_flAchievementEndTime )
  602. {
  603. m_iKillCount++;
  604. if ( m_iKillCount >= 15 )
  605. {
  606. AwardAchievement();
  607. }
  608. }
  609. }
  610. private:
  611. float m_flAchievementEndTime;
  612. int m_iKillCount;
  613. };
  614. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_UseUberBottle, ACHIEVEMENT_TF_MVM_USE_UBER_BOTTLE, "TF_MVM_USE_UBER_BOTTLE", 5 );
  615. //----------------------------------------------------------------------------------------------------------------
  616. class CAchievementTF_MvM_UseBuildBottle : public CBaseTFAchievementSimple
  617. {
  618. public:
  619. void Init()
  620. {
  621. SetFlags( ACH_SAVE_GLOBAL );
  622. SetGoal( 1 );
  623. m_flAchievementEndTime = 0.0f;
  624. }
  625. virtual void ListenForEvents()
  626. {
  627. ListenForGameEvent( "object_destroyed" );
  628. ListenForGameEvent( "mvm_quick_sentry_upgrade" );
  629. }
  630. void FireGameEvent_Internal( IGameEvent *event )
  631. {
  632. const char *pszEventName = event->GetName();
  633. if ( FStrEq( pszEventName, "object_destroyed" ) )
  634. {
  635. if ( TFGameRules() && ( TFGameRules()->State_Get() == GR_STATE_RND_RUNNING ) )
  636. {
  637. int iObject = event->GetInt( "objecttype" );
  638. if ( iObject == OBJ_SENTRYGUN )
  639. {
  640. int iEngineerIdx = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
  641. if ( iEngineerIdx == GetLocalPlayerIndex() )
  642. {
  643. m_flAchievementEndTime = gpGlobals->curtime + 3.0f;
  644. }
  645. }
  646. }
  647. }
  648. else if ( FStrEq( pszEventName, "mvm_quick_sentry_upgrade" ) )
  649. {
  650. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  651. {
  652. if ( gpGlobals->curtime < m_flAchievementEndTime )
  653. {
  654. AwardAchievement();
  655. }
  656. }
  657. }
  658. }
  659. private:
  660. float m_flAchievementEndTime;
  661. };
  662. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_UseBuildBottle, ACHIEVEMENT_TF_MVM_USE_BUILD_BOTTLE, "TF_MVM_USE_BUILD_BOTTLE", 5 );
  663. //----------------------------------------------------------------------------------------------------------------
  664. class CAchievementTF_MvM_UseAmmoBottle : public CBaseTFAchievementSimple
  665. {
  666. public:
  667. void Init()
  668. {
  669. SetFlags( ACH_SAVE_GLOBAL );
  670. SetGoal( 1 );
  671. }
  672. // server awards this achievement, no other code within achievement necessary
  673. };
  674. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_UseAmmoBottle, ACHIEVEMENT_TF_MVM_USE_AMMO_BOTTLE, "TF_MVM_USE_AMMO_BOTTLE", 5 );
  675. //----------------------------------------------------------------------------------------------------------------
  676. class CAchievementTF_MvM_MaxPrimaryUpgrades : public CBaseTFAchievementSimple
  677. {
  678. public:
  679. void Init()
  680. {
  681. SetFlags( ACH_SAVE_GLOBAL );
  682. SetGoal( 1 );
  683. }
  684. // server awards this achievement, no other code within achievement necessary
  685. };
  686. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_MaxPrimaryUpgrades, ACHIEVEMENT_TF_MVM_MAX_PRIMARY_UPGRADES, "TF_MVM_MAX_PRIMARY_UPGRADES", 5 );
  687. //----------------------------------------------------------------------------------------------------------------
  688. class CAchievementTF_MvM_MaxPlayerResistances : public CBaseTFAchievementSimple
  689. {
  690. public:
  691. void Init()
  692. {
  693. SetFlags( ACH_SAVE_GLOBAL );
  694. SetGoal( 1 );
  695. }
  696. // server awards this achievement, no other code within achievement necessary
  697. };
  698. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_MaxPlayerResistances, ACHIEVEMENT_TF_MVM_MAX_PLAYER_RESISTANCES, "TF_MVM_MAX_PLAYER_RESISTANCES", 5 );
  699. //----------------------------------------------------------------------------------------------------------------
  700. class CAchievementTF_MvM_NoAlarmsInFinalWave : public CBaseTFAchievementSimple
  701. {
  702. public:
  703. void Init()
  704. {
  705. SetFlags( ACH_SAVE_GLOBAL );
  706. SetGoal( 1 );
  707. m_bAlarmTriggered = true;
  708. }
  709. virtual void ListenForEvents()
  710. {
  711. ListenForGameEvent( "mvm_begin_wave" );
  712. ListenForGameEvent( "mvm_bomb_alarm_triggered" );
  713. ListenForGameEvent( "mvm_mission_complete" );
  714. }
  715. void FireGameEvent_Internal( IGameEvent *event )
  716. {
  717. const char *pszEventName = event->GetName();
  718. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  719. {
  720. if ( event->GetInt( "advanced" ) > 0 )
  721. {
  722. if ( event->GetInt( "wave_index" ) == ( event->GetInt( "max_waves" ) - 1 ) )
  723. {
  724. m_bAlarmTriggered = false;
  725. }
  726. else
  727. {
  728. m_bAlarmTriggered = true;
  729. }
  730. }
  731. }
  732. else if ( FStrEq( pszEventName, "mvm_bomb_alarm_triggered" ) )
  733. {
  734. m_bAlarmTriggered = true;
  735. }
  736. else if ( FStrEq( pszEventName, "mvm_mission_complete" ) )
  737. {
  738. if ( !m_bAlarmTriggered )
  739. {
  740. AwardAchievement();
  741. }
  742. }
  743. }
  744. private:
  745. bool m_bAlarmTriggered;
  746. };
  747. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_NoAlarmsInFinalWave, ACHIEVEMENT_TF_MVM_NO_ALARMS_IN_FINAL_WAVE, "TF_MVM_NO_ALARMS_IN_FINAL_WAVE", 5 );
  748. //----------------------------------------------------------------------------------------------------------------
  749. class CAchievementTF_MvM_KillMedicsCharged : public CBaseTFAchievementSimple
  750. {
  751. public:
  752. void Init()
  753. {
  754. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  755. SetGoal( 1 );
  756. iCount = 0;
  757. }
  758. virtual void ListenForEvents()
  759. {
  760. ListenForGameEvent( "teamplay_round_active" );
  761. }
  762. void FireGameEvent_Internal( IGameEvent *event )
  763. {
  764. if ( FStrEq( event->GetName(), "teamplay_round_active" ) )
  765. {
  766. iCount = 0;
  767. }
  768. }
  769. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  770. {
  771. C_TFPlayer *pTFVictim = ToTFPlayer( pVictim );
  772. if ( pTFVictim && pTFVictim->IsPlayerClass( TF_CLASS_MEDIC ) && ( pTFVictim->MedicGetChargeLevel() >= 1.0 ) )
  773. {
  774. iCount++;
  775. if ( iCount >= 5 )
  776. {
  777. AwardAchievement();
  778. }
  779. }
  780. }
  781. private:
  782. int iCount;
  783. };
  784. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_KillMedicsCharged, ACHIEVEMENT_TF_MVM_KILL_MEDICS_CHARGED, "TF_MVM_KILL_MEDICS_CHARGED", 5 );
  785. //----------------------------------------------------------------------------------------------------------------
  786. class CAchievementTF_MvM_KillRobotGrind : public CBaseTFAchievementSimple
  787. {
  788. public:
  789. void Init()
  790. {
  791. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  792. SetGoal( 100000 );
  793. SetStoreProgressInSteam( true );
  794. }
  795. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  796. {
  797. IncrementCount();
  798. }
  799. };
  800. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_KillRobotGrind, ACHIEVEMENT_TF_MVM_KILL_ROBOT_GRIND, "TF_MVM_KILL_ROBOT_GRIND", 5 );
  801. //----------------------------------------------------------------------------------------------------------------
  802. class CAchievementTF_MvM_KillRobotMegaGrind : public CBaseTFAchievementSimple
  803. {
  804. public:
  805. void Init()
  806. {
  807. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS );
  808. SetGoal( 1000000 );
  809. SetStoreProgressInSteam( true );
  810. }
  811. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  812. {
  813. IncrementCount();
  814. }
  815. };
  816. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_KillRobotMegaGrind, ACHIEVEMENT_TF_MVM_KILL_ROBOT_MEGA_GRIND, "TF_MVM_KILL_ROBOT_MEGA_GRIND", 5 );
  817. //----------------------------------------------------------------------------------------------------------------
  818. class CAchievementTF_MvM_KillSentryBuster : public CBaseTFAchievementSimple
  819. {
  820. public:
  821. void Init()
  822. {
  823. SetFlags( ACH_SAVE_GLOBAL );
  824. SetGoal( 1 );
  825. }
  826. // server awards this achievement, no other code within achievement necessary
  827. };
  828. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_KillSentryBuster, ACHIEVEMENT_TF_MVM_KILL_SENTRY_BUSTER, "TF_MVM_KILL_SENTRY_BUSTER", 5 );
  829. //----------------------------------------------------------------------------------------------------------------
  830. class CAchievementTF_MvM_SpySapRobots : public CBaseTFAchievementSimple
  831. {
  832. public:
  833. void Init()
  834. {
  835. SetFlags( ACH_SAVE_GLOBAL );
  836. SetGoal( 1 );
  837. }
  838. // server awards this achievement, no other code within achievement necessary
  839. };
  840. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_SpySapRobots, ACHIEVEMENT_TF_MVM_SPY_SAP_ROBOTS, "TF_MVM_SPY_SAP_ROBOTS", 5 );
  841. //----------------------------------------------------------------------------------------------------------------
  842. class CAchievementTF_MvM_SoldierBuffTeam : public CBaseTFAchievementSimple
  843. {
  844. public:
  845. void Init()
  846. {
  847. SetFlags( ACH_SAVE_GLOBAL );
  848. SetGoal( 1 );
  849. }
  850. // server awards this achievement, no other code within achievement necessary
  851. };
  852. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_SoldierBuffTeam, ACHIEVEMENT_TF_MVM_SOLDIER_BUFF_TEAM, "TF_MVM_SOLDIER_BUFF_TEAM", 5 );
  853. //----------------------------------------------------------------------------------------------------------------
  854. class CAchievementTF_MvM_HeavyRagePushDeployingRobot : public CBaseTFAchievementSimple
  855. {
  856. public:
  857. void Init()
  858. {
  859. SetFlags( ACH_SAVE_GLOBAL );
  860. SetGoal( 1 );
  861. }
  862. virtual void ListenForEvents()
  863. {
  864. ListenForGameEvent( "mvm_bomb_deploy_reset_by_player" );
  865. }
  866. void FireGameEvent_Internal( IGameEvent *event )
  867. {
  868. if ( FStrEq( event->GetName(), "mvm_bomb_deploy_reset_by_player" ) )
  869. {
  870. if ( GetLocalPlayerTeam() != TF_TEAM_PVE_DEFENDERS )
  871. return;
  872. C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  873. if ( !pLocalTFPlayer )
  874. return;
  875. if ( !pLocalTFPlayer->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
  876. return;
  877. if ( !pLocalTFPlayer->m_Shared.IsRageDraining() )
  878. return;
  879. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  880. {
  881. AwardAchievement();
  882. }
  883. }
  884. }
  885. };
  886. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_HeavyRagePushDeployingRobot, ACHIEVEMENT_TF_MVM_HEAVY_RAGE_PUSH_DEPLOYING_ROBOT, "TF_MVM_HEAVY_RAGE_PUSH_DEPLOYING_ROBOT", 5 );
  887. //----------------------------------------------------------------------------------------------------------------
  888. class CAchievementTF_MvM_MedicShareBottles : public CBaseTFAchievementSimple
  889. {
  890. public:
  891. void Init()
  892. {
  893. SetFlags( ACH_SAVE_GLOBAL );
  894. SetGoal( 1 );
  895. iCount = 0;
  896. }
  897. virtual void ListenForEvents()
  898. {
  899. ListenForGameEvent( "teamplay_round_active" );
  900. ListenForGameEvent( "mvm_medic_powerup_shared" );
  901. }
  902. void FireGameEvent_Internal( IGameEvent *event )
  903. {
  904. const char *pszEventName = event->GetName();
  905. if ( FStrEq( pszEventName, "teamplay_round_active" ) )
  906. {
  907. iCount = 0;
  908. }
  909. else if ( FStrEq( pszEventName, "mvm_medic_powerup_shared" ) )
  910. {
  911. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  912. {
  913. iCount++;
  914. if ( iCount >= 5 )
  915. {
  916. AwardAchievement();
  917. }
  918. }
  919. }
  920. }
  921. private:
  922. int iCount;
  923. };
  924. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_MedicShareBottles, ACHIEVEMENT_TF_MVM_MEDIC_SHARE_BOTTLES, "TF_MVM_MEDIC_SHARE_BOTTLES", 5 );
  925. //----------------------------------------------------------------------------------------------------------------
  926. class CAchievementTF_MvM_DemoGroupKill : public CBaseTFAchievementSimple
  927. {
  928. public:
  929. void Init()
  930. {
  931. SetFlags( ACH_SAVE_GLOBAL );
  932. SetGoal( 1 );
  933. }
  934. };
  935. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_DemoGroupKill, ACHIEVEMENT_TF_MVM_DEMO_GROUP_KILL, "TF_MVM_DEMO_GROUP_KILL", 5 );
  936. //----------------------------------------------------------------------------------------------------------------
  937. class CAchievementTF_MvM_ScoutMarkForDeath : public CBaseTFAchievementSimple
  938. {
  939. public:
  940. void Init()
  941. {
  942. SetFlags( ACH_SAVE_GLOBAL );
  943. SetGoal( 1 );
  944. iCount = 0;
  945. }
  946. virtual void ListenForEvents()
  947. {
  948. ListenForGameEvent( "teamplay_round_active" );
  949. ListenForGameEvent( "mvm_scout_marked_for_death" );
  950. }
  951. void FireGameEvent_Internal( IGameEvent *event )
  952. {
  953. const char *pszEventName = event->GetName();
  954. if ( FStrEq( pszEventName, "teamplay_round_active" ) )
  955. {
  956. iCount = 0;
  957. }
  958. else if ( FStrEq( pszEventName, "mvm_scout_marked_for_death" ) )
  959. {
  960. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  961. {
  962. iCount++;
  963. if ( iCount >= 15 )
  964. {
  965. AwardAchievement();
  966. }
  967. }
  968. }
  969. }
  970. private:
  971. int iCount;
  972. };
  973. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_ScoutMarkForDeath, ACHIEVEMENT_TF_MVM_SCOUT_MARK_FOR_DEATH, "TF_MVM_SCOUT_MARK_FOR_DEATH", 5 );
  974. //----------------------------------------------------------------------------------------------------------------
  975. class CAchievementTF_MvM_SniperKillGroup : public CBaseTFAchievementSimple
  976. {
  977. public:
  978. void Init()
  979. {
  980. SetFlags( ACH_SAVE_GLOBAL );
  981. SetGoal( 1 );
  982. }
  983. // server awards this achievement, no other code within achievement necessary
  984. };
  985. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_SniperKillGroup, ACHIEVEMENT_TF_MVM_SNIPER_KILL_GROUP, "TF_MVM_SNIPER_KILL_GROUP", 5 );
  986. //----------------------------------------------------------------------------------------------------------------
  987. class CAchievementTF_MvM_PyroBombReset : public CBaseTFAchievementSimple
  988. {
  989. public:
  990. void Init()
  991. {
  992. SetFlags( ACH_SAVE_GLOBAL );
  993. SetGoal( 1 );
  994. RESET_COUNT = 3;
  995. m_iResetCountInWave = 0;
  996. }
  997. virtual void ListenForEvents()
  998. {
  999. ListenForGameEvent( "mvm_bomb_reset_by_player" );
  1000. ListenForGameEvent( "mvm_wave_complete" );
  1001. ListenForGameEvent( "teamplay_round_active" );
  1002. }
  1003. void FireGameEvent_Internal( IGameEvent *event )
  1004. {
  1005. const char *pszEventName = event->GetName();
  1006. if ( FStrEq( pszEventName, "mvm_bomb_reset_by_player" ) )
  1007. {
  1008. if ( GetLocalPlayerTeam() != TF_TEAM_PVE_DEFENDERS )
  1009. return;
  1010. C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer();
  1011. if ( !pLocalTFPlayer )
  1012. return;
  1013. if ( !pLocalTFPlayer->IsPlayerClass( TF_CLASS_PYRO ) )
  1014. return;
  1015. if ( event->GetInt( "player" ) == GetLocalPlayerIndex() )
  1016. {
  1017. m_iResetCountInWave++;
  1018. }
  1019. if ( m_iResetCountInWave >= RESET_COUNT )
  1020. {
  1021. AwardAchievement();
  1022. }
  1023. }
  1024. else if ( FStrEq( pszEventName, "mvm_wave_complete" ) ||
  1025. FStrEq( pszEventName, "teamplay_round_active" ) )
  1026. {
  1027. m_iResetCountInWave = 0;
  1028. }
  1029. }
  1030. private:
  1031. int RESET_COUNT;
  1032. int m_iResetCountInWave;
  1033. };
  1034. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_PyroBombReset, ACHIEVEMENT_TF_MVM_PYRO_BOMB_RESET, "TF_MVM_PYRO_BOMB_RESET", 5 );
  1035. //----------------------------------------------------------------------------------------------------------------
  1036. class CAchievementTF_MvM_EngineerEscapeSentryBuster : public CBaseTFAchievementSimple
  1037. {
  1038. public:
  1039. void Init()
  1040. {
  1041. SetFlags( ACH_SAVE_GLOBAL );
  1042. SetGoal( 1 );
  1043. ListenForGameEvent( "mvm_sentrybuster_detonate" );
  1044. }
  1045. void FireGameEvent_Internal( IGameEvent *event )
  1046. {
  1047. // We should only be here if the sentry buster thinks it was successful
  1048. // which is to say started to detonate because they were within range
  1049. if ( FStrEq( event->GetName(), "mvm_sentrybuster_detonate" ) )
  1050. {
  1051. if ( GetLocalPlayerTeam() != TF_TEAM_PVE_DEFENDERS )
  1052. return;
  1053. int iTargetIdx = event->GetInt( "player" );
  1054. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  1055. if ( !pLocalPlayer )
  1056. return;
  1057. if ( !pLocalPlayer->IsAlive() )
  1058. return;
  1059. if ( !pLocalPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) )
  1060. return;
  1061. // Where it exploded
  1062. float x, y, z = 0;
  1063. x = event->GetFloat( "det_x" );
  1064. y = event->GetFloat( "det_y" );
  1065. z = event->GetFloat( "det_z" );
  1066. // If we're not the target, but within a reasonable range of the sentry buster,
  1067. // also give credit, otherwise we give the target credit for still being alive.
  1068. if ( GetLocalPlayerIndex() != iTargetIdx )
  1069. {
  1070. Vector vDist = pLocalPlayer->GetAbsOrigin() - Vector( x, y, z );
  1071. if ( vDist.LengthSqr() > 400 * 400 )
  1072. return;
  1073. }
  1074. AwardAchievement();
  1075. }
  1076. }
  1077. };
  1078. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_EngineerEscapeSentryBuster, ACHIEVEMENT_TF_MVM_ENGINEER_ESCAPE_SENTRY_BUSTER, "TF_MVM_ENGINEER_ESCAPE_SENTRY_BUSTER", 5 );
  1079. //----------------------------------------------------------------------------------------------------------------
  1080. class CAchievementTF_MvM_Maps_Rottenburg_Tank : public CBaseTFAchievementSimple
  1081. {
  1082. void Init()
  1083. {
  1084. SetFlags( ACH_SAVE_GLOBAL );
  1085. SetGoal( 1 );
  1086. }
  1087. // server awards this achievement, no other code within achievement necessary
  1088. };
  1089. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Rottenburg_Tank, ACHIEVEMENT_TF_MVM_MAPS_ROTTENBURG_TANK, "TF_MVM_MAPS_ROTTENBURG_TANK", 5 );
  1090. //----------------------------------------------------------------------------------------------------------------
  1091. class CAchievementTF_MvM_Maps_Rottenburg_Bomb : public CBaseTFAchievementSimple
  1092. {
  1093. void Init()
  1094. {
  1095. SetFlags( ACH_SAVE_GLOBAL );
  1096. SetGoal( 1 );
  1097. SetMapNameFilter( "mvm_rottenburg" );
  1098. m_bValidWave = false;
  1099. }
  1100. virtual void ListenForEvents()
  1101. {
  1102. ListenForGameEvent( "mvm_begin_wave" );
  1103. ListenForGameEvent( "mvm_wave_complete" );
  1104. ListenForGameEvent( "flag_carried_in_detection_zone" );
  1105. }
  1106. void FireGameEvent_Internal( IGameEvent *event )
  1107. {
  1108. const char *pszEventName = event->GetName();
  1109. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  1110. {
  1111. m_bValidWave = true;
  1112. }
  1113. else if ( FStrEq( pszEventName, "flag_carried_in_detection_zone" ) )
  1114. {
  1115. m_bValidWave = false;
  1116. }
  1117. else if ( FStrEq( pszEventName, "mvm_wave_complete" ) )
  1118. {
  1119. if ( event->GetBool( "advanced" ) )
  1120. {
  1121. if ( m_bValidWave )
  1122. {
  1123. AwardAchievement();
  1124. }
  1125. }
  1126. }
  1127. }
  1128. private:
  1129. bool m_bValidWave;
  1130. };
  1131. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Rottenburg_Bomb, ACHIEVEMENT_TF_MVM_MAPS_ROTTENBURG_BOMB, "TF_MVM_MAPS_ROTTENBURG_BOMB", 5 );
  1132. //----------------------------------------------------------------------------------------------------------------
  1133. class CAchievementTF_MvM_Maps_Rottenburg_PitGrind : public CBaseTFAchievementSimple
  1134. {
  1135. void Init()
  1136. {
  1137. SetFlags( ACH_SAVE_GLOBAL );
  1138. SetGoal( 100 );
  1139. SetStoreProgressInSteam( true );
  1140. }
  1141. // server awards this achievement, no other code within achievement necessary
  1142. };
  1143. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Rottenburg_PitGrind, ACHIEVEMENT_TF_MVM_MAPS_ROTTENBURG_PIT_GRIND, "TF_MVM_MAPS_ROTTENBURG_PIT_GRIND", 5 );
  1144. //----------------------------------------------------------------------------------------------------------------
  1145. class CAchievementTF_MvM_Maps_Manhattan_Pit : public CBaseTFAchievementSimple
  1146. {
  1147. void Init()
  1148. {
  1149. SetFlags( ACH_SAVE_GLOBAL );
  1150. SetGoal( 1 );
  1151. SetMapNameFilter( "mvm_mannhattan" );
  1152. m_iCount = 0;
  1153. }
  1154. virtual void ListenForEvents()
  1155. {
  1156. ListenForGameEvent( "mvm_begin_wave" );
  1157. ListenForGameEvent( "mvm_mannhattan_pit" );
  1158. }
  1159. void FireGameEvent_Internal( IGameEvent *event )
  1160. {
  1161. const char *pszEventName = event->GetName();
  1162. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  1163. {
  1164. m_iCount = 0;
  1165. }
  1166. else if ( FStrEq( pszEventName, "mvm_mannhattan_pit" ) )
  1167. {
  1168. m_iCount++;
  1169. if ( m_iCount >= 10 )
  1170. {
  1171. AwardAchievement();
  1172. }
  1173. }
  1174. }
  1175. private:
  1176. int m_iCount;
  1177. };
  1178. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Manhattan_Pit, ACHIEVEMENT_TF_MVM_MAPS_MANNHATTAN_PIT, "TF_MVM_MAPS_MANNHATTAN_PIT", 5 );
  1179. //----------------------------------------------------------------------------------------------------------------
  1180. class CAchievementTF_MvM_Maps_Manhattan_Mystery : public CBaseTFAchievementSimple
  1181. {
  1182. void Init()
  1183. {
  1184. SetFlags( ACH_SAVE_GLOBAL );
  1185. SetGoal( 1 );
  1186. }
  1187. // server awards this achievement, no other code within achievement necessary
  1188. };
  1189. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Manhattan_Mystery, ACHIEVEMENT_TF_MVM_MAPS_MANNHATTAN_MYSTERY, "TF_MVM_MAPS_MANNHATTAN_MYSTERY", 5 );
  1190. //----------------------------------------------------------------------------------------------------------------
  1191. class CAchievementTF_MvM_Maps_Manhattan_NoGates : public CBaseTFAchievementSimple
  1192. {
  1193. void Init()
  1194. {
  1195. SetFlags( ACH_SAVE_GLOBAL );
  1196. SetGoal( 1 );
  1197. SetMapNameFilter( "mvm_mannhattan" );
  1198. m_iWaveBits = 0;
  1199. }
  1200. virtual void ListenForEvents()
  1201. {
  1202. ListenForGameEvent( "mvm_begin_wave" );
  1203. ListenForGameEvent( "mvm_adv_wave_complete_no_gates" );
  1204. }
  1205. void FireGameEvent_Internal( IGameEvent *event )
  1206. {
  1207. const char *pszEventName = event->GetName();
  1208. if ( FStrEq( pszEventName, "mvm_begin_wave" ) )
  1209. {
  1210. if ( event->GetInt( "wave_index" ) == 0 )
  1211. {
  1212. m_iWaveBits = 0;
  1213. }
  1214. }
  1215. else if ( FStrEq( pszEventName, "mvm_adv_wave_complete_no_gates" ) )
  1216. {
  1217. m_iWaveBits |= ( 1 << event->GetInt( "index" ) );
  1218. int iComponentBits = m_iWaveBits;
  1219. int iNumBitsSet = 0;
  1220. while ( iComponentBits > 0 )
  1221. {
  1222. if ( iComponentBits & 1 )
  1223. {
  1224. iNumBitsSet++;
  1225. }
  1226. iComponentBits >>= 1;
  1227. }
  1228. if ( TFObjectiveResource() )
  1229. {
  1230. if ( iNumBitsSet >= TFObjectiveResource()->GetMannVsMachineMaxWaveCount() )
  1231. {
  1232. AwardAchievement();
  1233. }
  1234. }
  1235. }
  1236. }
  1237. private:
  1238. int m_iWaveBits;
  1239. };
  1240. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Manhattan_NoGates, ACHIEVEMENT_TF_MVM_MAPS_MANNHATTAN_NO_GATES, "TF_MVM_MAPS_MANNHATTAN_NO_GATES", 5 );
  1241. //----------------------------------------------------------------------------------------------------------------
  1242. class CAchievementTF_MvM_Maps_Manhattan_KillStunRadiowave : public CBaseTFAchievementSimple
  1243. {
  1244. void Init()
  1245. {
  1246. SetFlags( ACH_SAVE_GLOBAL );
  1247. SetGoal( 1 );
  1248. SetMapNameFilter( "mvm_mannhattan" );
  1249. m_nRobotsKilled = 0;
  1250. }
  1251. virtual void ListenForEvents()
  1252. {
  1253. ListenForGameEvent( "mvm_adv_wave_killed_stun_radio" );
  1254. }
  1255. void FireGameEvent_Internal( IGameEvent *event )
  1256. {
  1257. if ( FStrEq( event->GetName(), "mvm_adv_wave_killed_stun_radio" ) )
  1258. {
  1259. m_nRobotsKilled++;
  1260. if ( m_nRobotsKilled >= 50 )
  1261. {
  1262. AwardAchievement();
  1263. }
  1264. }
  1265. }
  1266. private:
  1267. int m_nRobotsKilled;
  1268. };
  1269. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Manhattan_KillStunRadiowave, ACHIEVEMENT_TF_MVM_MAPS_MANNHATTAN_STUN_RADIOWAVE, "TF_MVM_MAPS_MANNHATTAN_STUN_RADIOWAVE", 5 );
  1270. //----------------------------------------------------------------------------------------------------------------
  1271. class CAchievementTF_MvM_Maps_Manhattan_BombBotGrind : public CBaseTFAchievementSimple
  1272. {
  1273. void Init()
  1274. {
  1275. SetFlags( ACH_SAVE_GLOBAL );
  1276. SetGoal( 500 );
  1277. SetStoreProgressInSteam( true );
  1278. }
  1279. // server awards this achievement, no other code within achievement necessary
  1280. };
  1281. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Maps_Manhattan_BombBotGrind, ACHIEVEMENT_TF_MVM_MAPS_MANNHATTAN_BOMB_BOT_GRIND, "TF_MVM_MAPS_MANNHATTAN_BOMB_BOT_GRIND", 5 );
  1282. //----------------------------------------------------------------------------------------------------------------
  1283. class CAchievementTF_MvM_SentryBusterFriendlyFire : public CBaseTFAchievementSimple
  1284. {
  1285. void Init()
  1286. {
  1287. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  1288. SetGoal( 1 );
  1289. m_flDetonateTime = 0.f;
  1290. m_pSentryBuster = NULL;
  1291. m_Victims.EnsureCapacity( MAX_PLAYERS );
  1292. }
  1293. virtual void ListenForEvents()
  1294. {
  1295. ListenForGameEvent( "mvm_sentrybuster_killed" );
  1296. }
  1297. void FireGameEvent_Internal( IGameEvent *event )
  1298. {
  1299. if ( FStrEq( event->GetName(), "mvm_sentrybuster_killed" ) )
  1300. {
  1301. m_pSentryBuster = UTIL_PlayerByIndex( event->GetInt( "sentry_buster" ) );
  1302. if ( m_pSentryBuster )
  1303. {
  1304. m_flDetonateTime = gpGlobals->curtime;
  1305. SetNextThink( 0.1 );
  1306. }
  1307. }
  1308. }
  1309. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1310. {
  1311. if ( pAttacker && pVictim )
  1312. {
  1313. CBasePlayer *pAttackerPlayer = UTIL_PlayerByIndex( pAttacker->entindex() );
  1314. if ( m_pSentryBuster && m_pSentryBuster == pAttackerPlayer && gpGlobals->curtime <= m_flDetonateTime + 0.25f )
  1315. {
  1316. if ( pVictim->GetTeamNumber() == TF_TEAM_PVE_INVADERS )
  1317. {
  1318. if ( m_Victims.Find( pVictim->entindex() ) == m_Victims.InvalidIndex() )
  1319. {
  1320. m_Victims.AddToTail( pVictim->entindex() );
  1321. }
  1322. }
  1323. }
  1324. }
  1325. }
  1326. virtual void Think( void )
  1327. {
  1328. if ( gpGlobals->curtime <= m_flDetonateTime + 0.25f )
  1329. {
  1330. int nVictims = m_Victims.Count();
  1331. if ( nVictims >= 5 )
  1332. {
  1333. AwardAchievement();
  1334. }
  1335. SetNextThink( 0.1 );
  1336. return;
  1337. }
  1338. m_pSentryBuster = NULL;
  1339. m_Victims.RemoveAll();
  1340. }
  1341. private:
  1342. CUtlVector< int > m_Victims;
  1343. CBasePlayer *m_pSentryBuster;
  1344. float m_flDetonateTime;
  1345. };
  1346. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_SentryBusterFriendlyFire, ACHIEVEMENT_TF_MVM_SENTRY_BUSTER_FRIENDLY_FIRE, "TF_MVM_SENTRY_BUSTER_FRIENDLY_FIRE", 5 );
  1347. //----------------------------------------------------------------------------------------------------------------
  1348. class CAchievementTF_MvM_Sniper_CollectHeadshotMoney : public CBaseTFAchievementSimple
  1349. {
  1350. void Init()
  1351. {
  1352. SetFlags( ACH_SAVE_GLOBAL );
  1353. SetGoal( 1 );
  1354. SetMapNameFilter( "mvm_mannhattan" );
  1355. m_nCurrencyCollected = 0;
  1356. }
  1357. virtual void ListenForEvents()
  1358. {
  1359. ListenForGameEvent( "mvm_sniper_headshot_currency" );
  1360. }
  1361. void FireGameEvent_Internal( IGameEvent *event )
  1362. {
  1363. if ( FStrEq( event->GetName(), "mvm_sniper_headshot_currency" ) )
  1364. {
  1365. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  1366. if ( pLocalPlayer )
  1367. {
  1368. if ( event->GetInt( "userid" ) == pLocalPlayer->GetUserID() )
  1369. {
  1370. m_nCurrencyCollected += event->GetFloat( "currency" );
  1371. if ( m_nCurrencyCollected >= 500 )
  1372. {
  1373. AwardAchievement();
  1374. }
  1375. }
  1376. }
  1377. }
  1378. }
  1379. private:
  1380. int m_nCurrencyCollected;
  1381. };
  1382. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Sniper_CollectHeadshotMoney, ACHIEVEMENT_TF_MVM_SNIPER_COLLECT_HEADSHOT_MONEY, "TF_MVM_SNIPER_COLLECT_HEADSHOT_MONEY", 5 );
  1383. //----------------------------------------------------------------------------------------------------------------
  1384. class CAchievementTF_MvM_Medic_ShieldBlockDamage : public CBaseTFAchievementSimple
  1385. {
  1386. void Init()
  1387. {
  1388. SetFlags( ACH_SAVE_GLOBAL );
  1389. SetGoal( 1 );
  1390. SetMapNameFilter( "mvm_mannhattan" );
  1391. m_flDamage = 0.0f;
  1392. }
  1393. virtual void ListenForEvents()
  1394. {
  1395. ListenForGameEvent( "teamplay_round_active" );
  1396. ListenForGameEvent( "localplayer_respawn" );
  1397. ListenForGameEvent( "medigun_shield_blocked_damage" );
  1398. }
  1399. void FireGameEvent_Internal( IGameEvent *event )
  1400. {
  1401. const char *pszEvent = event->GetName();
  1402. if ( FStrEq( pszEvent, "teamplay_round_active" ) ||
  1403. FStrEq( pszEvent, "localplayer_respawn" ) )
  1404. {
  1405. m_flDamage = 0.0f;
  1406. }
  1407. else if ( FStrEq( pszEvent, "medigun_shield_blocked_damage" ) )
  1408. {
  1409. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  1410. if ( pLocalPlayer )
  1411. {
  1412. if ( event->GetInt( "userid" ) == pLocalPlayer->GetUserID() )
  1413. {
  1414. m_flDamage += event->GetFloat( "damage" );
  1415. if ( m_flDamage >= 5000.0f )
  1416. {
  1417. AwardAchievement();
  1418. }
  1419. }
  1420. }
  1421. }
  1422. }
  1423. private:
  1424. float m_flDamage;
  1425. };
  1426. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Medic_ShieldBlockDamage, ACHIEVEMENT_TF_MVM_MEDIC_SHIELD_BLOCK_DAMAGE, "TF_MVM_MEDIC_SHIELD_BLOCK_DAMAGE", 5 );
  1427. //----------------------------------------------------------------------------------------------------------------
  1428. class CAchievementTF_MvM_Medic_ReviveTeammates : public CBaseTFAchievementSimple
  1429. {
  1430. void Init()
  1431. {
  1432. SetFlags( ACH_SAVE_GLOBAL );
  1433. SetGoal( 1 );
  1434. }
  1435. virtual void ListenForEvents()
  1436. {
  1437. ListenForGameEvent( "revive_player_complete" );
  1438. }
  1439. void FireGameEvent_Internal( IGameEvent *event )
  1440. {
  1441. if ( FStrEq( event->GetName(), "revive_player_complete" ) )
  1442. {
  1443. if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
  1444. {
  1445. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  1446. if ( pLocalPlayer && pLocalPlayer->MedicIsReleasingCharge() )
  1447. {
  1448. if ( event->GetInt( "entindex" ) == GetLocalPlayerIndex() )
  1449. {
  1450. int iNewIndex = m_Times.AddToTail();
  1451. m_Times[iNewIndex] = gpGlobals->curtime;
  1452. // we only care about the last two times we revived someone
  1453. if ( m_Times.Count() > 2 )
  1454. {
  1455. m_Times.Remove( 0 );
  1456. }
  1457. if ( m_Times.Count() == 2 )
  1458. {
  1459. if ( m_Times.Tail() - m_Times.Head() <= 5.0 )
  1460. {
  1461. AwardAchievement();
  1462. }
  1463. }
  1464. }
  1465. }
  1466. }
  1467. }
  1468. }
  1469. private:
  1470. CUtlVector< float > m_Times;
  1471. };
  1472. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_Medic_ReviveTeammates, ACHIEVEMENT_TF_MVM_MEDIC_REVIVE_TEAMMATES, "TF_MVM_MEDIC_REVIVE_TEAMMATES", 5 );
  1473. //----------------------------------------------------------------------------------------------------------------
  1474. class CAchievementTF_MvM_RocketSpecialistKillGrind : public CBaseTFAchievementSimple
  1475. {
  1476. void Init()
  1477. {
  1478. SetFlags( ACH_SAVE_GLOBAL | ACH_LISTEN_KILL_EVENTS );
  1479. SetGoal( 1 );
  1480. m_flLastDirectTime = 0.f;
  1481. m_Victims.EnsureCapacity( MAX_PLAYERS );
  1482. }
  1483. virtual void ListenForEvents()
  1484. {
  1485. ListenForGameEvent( "player_directhit_stun" );
  1486. }
  1487. void FireGameEvent_Internal( IGameEvent *event )
  1488. {
  1489. const char *pszEvent = event->GetName();
  1490. // If we hit a bot directly, track player deaths over the next 0.25 seconds and see if we're the attacker
  1491. if ( FStrEq( pszEvent, "player_directhit_stun" ) )
  1492. {
  1493. int iLocalPlayerIndex = C_BasePlayer::GetLocalPlayer()->entindex();
  1494. int iAttackerIndex = event->GetInt( "attacker" );
  1495. CBasePlayer *pVictim = UTIL_PlayerByIndex( event->GetInt( "victim" ) );
  1496. if ( pVictim && pVictim->IsPlayer() && iLocalPlayerIndex == iAttackerIndex )
  1497. {
  1498. m_flLastDirectTime = gpGlobals->curtime;
  1499. SetNextThink( 0.1 );
  1500. }
  1501. }
  1502. }
  1503. virtual void Event_EntityKilled( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event )
  1504. {
  1505. if ( gpGlobals->curtime <= m_flLastDirectTime + 0.25f )
  1506. {
  1507. if ( pAttacker && pVictim && pAttacker != pVictim && pAttacker == C_BasePlayer::GetLocalPlayer() )
  1508. {
  1509. CBasePlayer *pPlayerVictim = UTIL_PlayerByIndex( pVictim->entindex() );
  1510. if ( m_Victims.Find( pPlayerVictim ) == m_Victims.InvalidIndex() )
  1511. {
  1512. m_Victims.AddToTail( pPlayerVictim );
  1513. }
  1514. }
  1515. }
  1516. }
  1517. virtual void Think( void )
  1518. {
  1519. int nVictims = m_Victims.Count();
  1520. if ( nVictims )
  1521. {
  1522. if ( gpGlobals->curtime <= m_flLastDirectTime + 0.25f )
  1523. {
  1524. if ( nVictims >= 5 )
  1525. {
  1526. AwardAchievement();
  1527. }
  1528. }
  1529. else
  1530. {
  1531. m_Victims.RemoveAll();
  1532. return;
  1533. }
  1534. SetNextThink( 0.1 );
  1535. }
  1536. }
  1537. private:
  1538. CUtlVector< CBasePlayer* > m_Victims;
  1539. float m_flLastDirectTime;
  1540. };
  1541. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_RocketSpecialistKillGrind, ACHIEVEMENT_TF_MVM_ROCKET_SPECIALIST_KILL_GRIND, "TF_MVM_ROCKET_SPECIALIST_KILL_GRIND", 5 );
  1542. //----------------------------------------------------------------------------------------------------------------
  1543. class CAchievementTF_MvM_RocketSpecialistStunGrind : public CBaseTFAchievementSimple
  1544. {
  1545. void Init()
  1546. {
  1547. SetFlags( ACH_SAVE_GLOBAL );
  1548. SetGoal( 50 );
  1549. SetStoreProgressInSteam( true );
  1550. }
  1551. // server awards this achievement, no other code within achievement necessary
  1552. };
  1553. DECLARE_ACHIEVEMENT( CAchievementTF_MvM_RocketSpecialistStunGrind, ACHIEVEMENT_TF_MVM_ROCKET_SPECIALIST_STUN_GRIND, "TF_MVM_ROCKET_SPECIALIST_STUN_GRIND", 5 );
  1554. #endif // CLIENT_DLL