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.

547 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "achievementmgr.h"
  8. #include "baseachievement.h"
  9. #ifdef GAME_DLL
  10. #include "prop_portal.h"
  11. #include "util.h"
  12. CAchievementMgr g_AchievementMgrPortal; // global achievement mgr for Portal
  13. class CAchievementPortalInfiniteFall : public CBaseAchievement
  14. {
  15. DECLARE_CLASS( CAchievementPortalInfiniteFall, CBaseAchievement );
  16. public:
  17. void Init()
  18. {
  19. SetFlags( ACH_SAVE_WITH_GAME );
  20. SetGameDirFilter( "portal" );
  21. SetGoal( 1 );
  22. m_fAccumulatedDistance = 0.0f;
  23. m_bIsFlinging = false;
  24. }
  25. virtual void ListenForEvents()
  26. {
  27. ListenForGameEvent( "portal_player_portaled" );
  28. ListenForGameEvent( "portal_player_touchedground" );
  29. }
  30. virtual void PreRestoreSavedGame()
  31. {
  32. m_fAccumulatedDistance = 0.0f;
  33. m_bIsFlinging = false;
  34. BaseClass::PreRestoreSavedGame();
  35. }
  36. protected:
  37. virtual void FireGameEvent( IGameEvent *event )
  38. {
  39. const char *name = event->GetName();
  40. if ( 0 == Q_strcmp( name, "portal_player_portaled" ) )
  41. {
  42. bool bIsPortal2 = event->GetBool( "portal2", false );
  43. // Get the portals that they teleported through
  44. CProp_Portal *pInPortal = CProp_Portal::FindPortal( 0, bIsPortal2, false );
  45. CProp_Portal *pOutPortal = CProp_Portal::FindPortal( 0, !bIsPortal2, false );
  46. if ( pInPortal && pOutPortal )
  47. {
  48. if ( m_bIsFlinging )
  49. {
  50. // Add up how far we traveled since the last teleport
  51. m_fAccumulatedDistance += m_fZPortalPosition - pInPortal->GetAbsOrigin().z;
  52. if ( m_fAccumulatedDistance > 30000.0f * 12 )
  53. IncrementCount();
  54. }
  55. // Remember the Z position to get the distance when the teleport again or land
  56. m_fZPortalPosition = pOutPortal->GetAbsOrigin().z;
  57. m_bIsFlinging = true;
  58. }
  59. }
  60. else if ( 0 == Q_strcmp( name, "portal_player_touchedground" ) )
  61. {
  62. if ( m_bIsFlinging )
  63. {
  64. CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
  65. if ( pLocalPlayer )
  66. {
  67. m_fAccumulatedDistance += m_fZPortalPosition - pLocalPlayer->GetAbsOrigin().z;
  68. if ( m_fAccumulatedDistance > 30000.0f * 12 )
  69. IncrementCount();
  70. m_fAccumulatedDistance = 0.0f;
  71. m_bIsFlinging = false;
  72. }
  73. }
  74. }
  75. }
  76. private:
  77. bool m_bIsFlinging;
  78. float m_fAccumulatedDistance;
  79. float m_fZPortalPosition;
  80. };
  81. DECLARE_ACHIEVEMENT( CAchievementPortalInfiniteFall, ACHIEVEMENT_PORTAL_INFINITEFALL, "PORTAL_INFINITEFALL", 5 );
  82. class CAchievementPortalLongJump : public CBaseAchievement
  83. {
  84. DECLARE_CLASS( CAchievementPortalLongJump, CBaseAchievement );
  85. public:
  86. void Init()
  87. {
  88. SetFlags( ACH_SAVE_WITH_GAME );
  89. SetGameDirFilter( "portal" );
  90. SetGoal( 1 );
  91. m_fAccumulatedDistance = 0.0f;
  92. m_bIsFlinging = false;
  93. }
  94. virtual void ListenForEvents()
  95. {
  96. ListenForGameEvent( "portal_player_portaled" );
  97. ListenForGameEvent( "portal_player_touchedground" );
  98. }
  99. virtual void PreRestoreSavedGame()
  100. {
  101. m_fAccumulatedDistance = 0.0f;
  102. m_bIsFlinging = false;
  103. BaseClass::PreRestoreSavedGame();
  104. }
  105. protected:
  106. virtual void FireGameEvent( IGameEvent *event )
  107. {
  108. const char *name = event->GetName();
  109. if ( 0 == Q_strcmp( name, "portal_player_portaled" ) )
  110. {
  111. bool bIsPortal2 = event->GetBool( "portal2", false );
  112. // Get the portals that they teleported through
  113. CProp_Portal *pInPortal = CProp_Portal::FindPortal( 0, bIsPortal2, false );
  114. CProp_Portal *pOutPortal = CProp_Portal::FindPortal( 0, !bIsPortal2, false );
  115. if ( pInPortal && pOutPortal )
  116. {
  117. if ( m_bIsFlinging )
  118. {
  119. // Add up how far we traveled since the last teleport
  120. float flDist = pInPortal->GetAbsOrigin().AsVector2D().DistTo( m_vec2DPortalPosition );
  121. // Ignore small distances that can be caused by microadjustments in infinite falls
  122. if ( flDist > 63.0f )
  123. {
  124. m_fAccumulatedDistance += flDist;
  125. }
  126. if ( m_fAccumulatedDistance > 300.0f * 12 )
  127. IncrementCount();
  128. }
  129. // Remember the 2D position to get the distance when the teleport again or land
  130. m_vec2DPortalPosition = pOutPortal->GetAbsOrigin().AsVector2D();
  131. m_bIsFlinging = true;
  132. }
  133. }
  134. else if ( 0 == Q_strcmp( name, "portal_player_touchedground" ) )
  135. {
  136. if ( m_bIsFlinging )
  137. {
  138. CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
  139. if ( pLocalPlayer )
  140. {
  141. float flDist = pLocalPlayer->GetAbsOrigin().AsVector2D().DistTo( m_vec2DPortalPosition );
  142. // Ignore small distances that can be caused by microadjustments in infinite falls
  143. if ( flDist > 63.0f )
  144. {
  145. m_fAccumulatedDistance += flDist;
  146. }
  147. if ( m_fAccumulatedDistance > 300.0f * 12 )
  148. IncrementCount();
  149. m_fAccumulatedDistance = 0.0f;
  150. m_bIsFlinging = false;
  151. }
  152. }
  153. }
  154. }
  155. private:
  156. bool m_bIsFlinging;
  157. float m_fAccumulatedDistance;
  158. Vector2D m_vec2DPortalPosition;
  159. };
  160. DECLARE_ACHIEVEMENT( CAchievementPortalLongJump, ACHIEVEMENT_PORTAL_LONGJUMP, "PORTAL_LONGJUMP", 5 );
  161. class CAchievementPortalBeat2AdvancedMaps: public CBaseAchievement
  162. {
  163. public:
  164. virtual void Init()
  165. {
  166. SetFlags( ACH_SAVE_GLOBAL );
  167. SetGoal( 2 );
  168. m_iProgressMsgMinimum = 0;
  169. }
  170. virtual void ListenForEvents()
  171. {
  172. ListenForGameEvent( "advanced_map_complete" );
  173. }
  174. protected:
  175. virtual void FireGameEvent( IGameEvent* event )
  176. {
  177. if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
  178. {
  179. if ( !IsAchieved() )
  180. {
  181. int iNumAdvanced = event->GetInt( "numadvanced" );
  182. SetCount ( iNumAdvanced );
  183. if ( iNumAdvanced >= GetGoal() )
  184. {
  185. AwardAchievement();
  186. }
  187. else
  188. {
  189. HandleProgressUpdate();
  190. }
  191. }
  192. }
  193. }
  194. virtual void CalcProgressMsgIncrement()
  195. {
  196. // show progress every tick
  197. m_iProgressMsgIncrement = 1;
  198. }
  199. };
  200. DECLARE_ACHIEVEMENT( CAchievementPortalBeat2AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_2ADVANCEDMAPS, "PORTAL_BEAT_2ADVANCEDMAPS", 10 );
  201. class CAchievementPortalBeat4AdvancedMaps : public CBaseAchievement
  202. {
  203. public:
  204. virtual void Init()
  205. {
  206. SetFlags( ACH_SAVE_GLOBAL );
  207. SetGoal( 4 );
  208. m_iProgressMsgMinimum = 3;
  209. }
  210. virtual void ListenForEvents()
  211. {
  212. ListenForGameEvent( "advanced_map_complete" );
  213. }
  214. protected:
  215. virtual void FireGameEvent( IGameEvent* event )
  216. {
  217. if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
  218. {
  219. if ( !IsAchieved() )
  220. {
  221. int iNumAdvanced = event->GetInt( "numadvanced" );
  222. SetCount ( iNumAdvanced );
  223. if ( iNumAdvanced >= GetGoal() )
  224. {
  225. AwardAchievement();
  226. }
  227. else
  228. {
  229. HandleProgressUpdate();
  230. }
  231. }
  232. }
  233. }
  234. virtual void CalcProgressMsgIncrement()
  235. {
  236. // show progress every tick
  237. m_iProgressMsgIncrement = 1;
  238. }
  239. };
  240. DECLARE_ACHIEVEMENT( CAchievementPortalBeat4AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_4ADVANCEDMAPS, "PORTAL_BEAT_4ADVANCEDMAPS", 20 );
  241. class CAchievementPortalBeat6AdvancedMaps : public CBaseAchievement
  242. {
  243. public:
  244. virtual void Init()
  245. {
  246. SetFlags( ACH_SAVE_GLOBAL );
  247. SetGoal( 6 );
  248. m_iProgressMsgMinimum = 5;
  249. }
  250. virtual void ListenForEvents()
  251. {
  252. ListenForGameEvent( "advanced_map_complete" );
  253. }
  254. protected:
  255. virtual void FireGameEvent( IGameEvent* event )
  256. {
  257. if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
  258. {
  259. if ( !IsAchieved() )
  260. {
  261. int iNumAdvanced = event->GetInt( "numadvanced" );
  262. SetCount ( iNumAdvanced );
  263. if ( iNumAdvanced >= GetGoal() )
  264. {
  265. AwardAchievement();
  266. }
  267. else
  268. {
  269. HandleProgressUpdate();
  270. }
  271. }
  272. }
  273. }
  274. virtual void CalcProgressMsgIncrement()
  275. {
  276. // show progress every tick
  277. m_iProgressMsgIncrement = 1;
  278. }
  279. };
  280. DECLARE_ACHIEVEMENT( CAchievementPortalBeat6AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_6ADVANCEDMAPS, "PORTAL_BEAT_6ADVANCEDMAPS", 30 );
  281. class CAchievementPortalGetAllBronze : public CBaseAchievement
  282. {
  283. public:
  284. virtual void Init()
  285. {
  286. SetFlags( ACH_SAVE_GLOBAL );
  287. SetGoal( 18 );
  288. }
  289. virtual void ListenForEvents()
  290. {
  291. ListenForGameEvent( "challenge_map_complete" );
  292. }
  293. protected:
  294. virtual void FireGameEvent( IGameEvent* event )
  295. {
  296. if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
  297. {
  298. if ( !IsAchieved() )
  299. {
  300. int iBronzeCount = event->GetInt( "numbronze" );
  301. SetCount ( iBronzeCount );
  302. if ( iBronzeCount >= GetGoal() )
  303. {
  304. AwardAchievement();
  305. }
  306. else
  307. {
  308. HandleProgressUpdate();
  309. }
  310. }
  311. }
  312. }
  313. virtual void CalcProgressMsgIncrement()
  314. {
  315. // show progress every tick
  316. m_iProgressMsgIncrement = 1;
  317. }
  318. };
  319. DECLARE_ACHIEVEMENT( CAchievementPortalGetAllBronze, ACHIEVEMENT_PORTAL_GET_ALLBRONZE, "PORTAL_GET_ALLBRONZE", 10 );
  320. class CAchievementPortalGetAllSilver : public CBaseAchievement
  321. {
  322. public:
  323. virtual void Init()
  324. {
  325. SetFlags( ACH_SAVE_GLOBAL );
  326. SetGoal( 18 );
  327. }
  328. virtual void ListenForEvents()
  329. {
  330. ListenForGameEvent( "challenge_map_complete" );
  331. }
  332. protected:
  333. virtual void FireGameEvent( IGameEvent* event )
  334. {
  335. if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
  336. {
  337. if ( !IsAchieved() )
  338. {
  339. int iSilverCount = event->GetInt( "numsilver" );
  340. SetCount ( iSilverCount );
  341. if ( iSilverCount >= GetGoal() )
  342. {
  343. AwardAchievement();
  344. }
  345. else
  346. {
  347. HandleProgressUpdate();
  348. }
  349. }
  350. }
  351. }
  352. virtual void CalcProgressMsgIncrement()
  353. {
  354. // show progress every tick
  355. m_iProgressMsgIncrement = 1;
  356. }
  357. };
  358. DECLARE_ACHIEVEMENT( CAchievementPortalGetAllSilver, ACHIEVEMENT_PORTAL_GET_ALLSILVER, "PORTAL_GET_ALLSILVER", 20 );
  359. class CAchievementPortalGetAllGold : public CBaseAchievement
  360. {
  361. public:
  362. virtual void Init()
  363. {
  364. SetFlags( ACH_SAVE_GLOBAL );
  365. SetGoal( 18 );
  366. }
  367. virtual void ListenForEvents()
  368. {
  369. ListenForGameEvent( "challenge_map_complete" );
  370. }
  371. protected:
  372. virtual void FireGameEvent( IGameEvent* event )
  373. {
  374. if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
  375. {
  376. if ( !IsAchieved() )
  377. {
  378. int iGoldCount = event->GetInt( "numgold" );
  379. SetCount ( iGoldCount );
  380. if ( iGoldCount >= GetGoal() )
  381. {
  382. AwardAchievement();
  383. }
  384. else
  385. {
  386. HandleProgressUpdate();
  387. }
  388. }
  389. }
  390. }
  391. virtual void CalcProgressMsgIncrement()
  392. {
  393. // show progress every tick
  394. m_iProgressMsgIncrement = 1;
  395. }
  396. };
  397. DECLARE_ACHIEVEMENT( CAchievementPortalGetAllGold, ACHIEVEMENT_PORTAL_GET_ALLGOLD, "PORTAL_GET_ALLGOLD", 40 );
  398. class CAchievementPortalDetachAllCameras : public CBaseAchievement
  399. {
  400. protected:
  401. virtual void ListenForEvents()
  402. {
  403. ListenForGameEvent( "security_camera_detached" );
  404. }
  405. void FireGameEvent_Internal( IGameEvent *event )
  406. {
  407. if ( 0 == Q_strcmp( event->GetName(), "security_camera_detached" ) )
  408. {
  409. IncrementCount();
  410. }
  411. }
  412. public:
  413. virtual void Init()
  414. {
  415. SetFlags( ACH_SAVE_WITH_GAME );
  416. SetGoal( 33 );
  417. ListenForGameEvent( "security_camera_detached" );
  418. }
  419. };
  420. DECLARE_ACHIEVEMENT( CAchievementPortalDetachAllCameras, ACHIEVEMENT_PORTAL_DETACH_ALL_CAMERAS, "PORTAL_DETACH_ALL_CAMERAS", 5 );
  421. class CAchievementPortalHitTurretWithTurret : public CBaseAchievement
  422. {
  423. protected:
  424. virtual void ListenForEvents()
  425. {
  426. ListenForGameEvent( "turret_hit_turret" );
  427. }
  428. void FireGameEvent_Internal( IGameEvent *event )
  429. {
  430. if ( 0 == Q_strcmp( event->GetName(), "turret_hit_turret" ) )
  431. {
  432. IncrementCount();
  433. }
  434. }
  435. public:
  436. virtual void Init()
  437. {
  438. SetFlags( ACH_SAVE_GLOBAL );
  439. SetGoal( 1 );
  440. ListenForGameEvent( "turret_hit_turret" );
  441. }
  442. };
  443. DECLARE_ACHIEVEMENT( CAchievementPortalHitTurretWithTurret, ACHIEVEMENT_PORTAL_HIT_TURRET_WITH_TURRET, "PORTAL_HIT_TURRET_WITH_TURRET", 5 );
  444. #ifndef _XBOX
  445. class CAchievementPortalFindAllDinosaurs : public CBaseAchievement
  446. {
  447. DECLARE_CLASS( CAchievementPortalFindAllDinosaurs, CBaseAchievement );
  448. void Init()
  449. {
  450. SetFlags( ACH_HAS_COMPONENTS | ACH_SAVE_GLOBAL );
  451. m_iNumComponents = 26;
  452. SetStoreProgressInSteam( true );
  453. SetGoal( m_iNumComponents );
  454. BaseClass::Init();
  455. m_iProgressMsgMinimum = 1;
  456. }
  457. virtual void ListenForEvents()
  458. {
  459. ListenForGameEvent( "dinosaur_signal_found" );
  460. }
  461. virtual void FireGameEvent_Internal( IGameEvent *event )
  462. {
  463. if ( 0 == Q_strcmp( event->GetName(), "dinosaur_signal_found" ) )
  464. {
  465. int id = event->GetInt( "id", -1 );
  466. Assert( id >= 0 && id < m_iNumComponents );
  467. if ( id >= 0 && id < m_iNumComponents )
  468. {
  469. EnsureComponentBitSetAndEvaluate( id );
  470. // Update our Steam stat
  471. steamapicontext->SteamUserStats()->SetStat( "PORTAL_TRANSMISSION_RECEIVED_STAT", m_iCount );
  472. }
  473. else
  474. {
  475. Warning( "Failed to set achievement progress. Dinosaur ID(%d) out of range (0 to %d)\n", id, m_iNumComponents );
  476. }
  477. }
  478. }
  479. virtual void CalcProgressMsgIncrement()
  480. {
  481. // Show progress every tick
  482. m_iProgressMsgIncrement = 1;
  483. }
  484. };
  485. DECLARE_ACHIEVEMENT( CAchievementPortalFindAllDinosaurs, ACHIEVEMENT_PORTAL_TRANSMISSION_RECEIVED, "PORTAL_TRANSMISSION_RECEIVED", 0 );
  486. #endif // _XBOX
  487. // achievements which are won by a map event firing once
  488. DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_GET_PORTALGUNS, "PORTAL_GET_PORTALGUNS", 5 );
  489. DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_KILL_COMPANIONCUBE, "PORTAL_KILL_COMPANIONCUBE", 5 );
  490. DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_ESCAPE_TESTCHAMBERS, "PORTAL_ESCAPE_TESTCHAMBERS", 5 );
  491. DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_BEAT_GAME, "PORTAL_BEAT_GAME", 10 );
  492. #endif // GAME_DLL