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.

727 lines
31 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include <time.h>
  8. #ifdef CLIENT_DLL
  9. #include "achievementmgr.h"
  10. #include "baseachievement.h"
  11. #include "cs_achievement_constants.h"
  12. #include "c_cs_team.h"
  13. #include "c_cs_player.h"
  14. #include "c_cs_playerresource.h"
  15. #include "cs_gamerules.h"
  16. #include "achievements_cs.h"
  17. #include "cs_gamestats_shared.h"
  18. #include "cs_client_gamestats.h"
  19. // [dwenger] Necessary for stats display
  20. #include "cs_achievements_and_stats_interface.h"
  21. // [dwenger] Necessary for sorting achievements by award time
  22. #include <vgui/ISystem.h>
  23. #include "../../src/public/vgui_controls/Controls.h"
  24. ConVar achievements_easymode( "achievement_easymode", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY,
  25. "Enables all stat-based achievements to be earned at 10% of goals" );
  26. // global achievement mgr for CS
  27. CAchievementMgr g_AchievementMgrCS;
  28. // [dwenger] Necessary for achievement / stats panel
  29. CSAchievementsAndStatsInterface g_AchievementsAndStatsInterfaceCS;
  30. CCSBaseAchievement::CCSBaseAchievement()
  31. {
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Determines the timestamp when the achievement is awarded
  35. //-----------------------------------------------------------------------------
  36. void CCSBaseAchievement::OnAchieved()
  37. {
  38. // __time32_t unlockTime;
  39. // _time32(&unlockTime);
  40. // SetUnlockTime(unlockTime);
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Returns the time values when the achievement was awarded.
  44. //-----------------------------------------------------------------------------
  45. bool CCSBaseAchievement::GetAwardTime( int& year, int& month, int& day, int& hour, int& minute, int& second )
  46. {
  47. time_t t = GetUnlockTime();
  48. if ( t != 0 )
  49. {
  50. struct tm structuredTime;
  51. Plat_localtime(&t, &structuredTime);
  52. year = structuredTime.tm_year + 1900;
  53. month = structuredTime.tm_mon + 1; // 0..11
  54. day = structuredTime.tm_mday;
  55. hour = structuredTime.tm_hour;
  56. minute = structuredTime.tm_min;
  57. second = structuredTime.tm_sec;
  58. return true;
  59. }
  60. return false;
  61. }
  62. void CCSBaseAchievement::GetSettings( KeyValues* pNodeOut )
  63. {
  64. BaseClass::GetSettings(pNodeOut);
  65. pNodeOut->SetInt("unlockTime", GetUnlockTime());
  66. }
  67. void CCSBaseAchievement::ApplySettings( /* const */ KeyValues* pNodeIn )
  68. {
  69. BaseClass::ApplySettings(pNodeIn);
  70. SetUnlockTime(pNodeIn->GetInt("unlockTime"));
  71. }
  72. /**
  73. * Meta Achievement base class methods
  74. */
  75. CAchievement_Meta::CAchievement_Meta() :
  76. m_CallbackUserAchievement( this, &CAchievement_Meta::Steam_OnUserAchievementStored )
  77. {
  78. }
  79. void CAchievement_Meta::Init()
  80. {
  81. SetFlags( ACH_SAVE_GLOBAL );
  82. SetGoal( 1 );
  83. }
  84. void CAchievement_Meta::Steam_OnUserAchievementStored( UserAchievementStored_t *pUserAchievementStored )
  85. {
  86. if ( IsAchieved() )
  87. return;
  88. int iAchieved = 0;
  89. FOR_EACH_VEC(m_requirements, i)
  90. {
  91. IAchievement* pAchievement = (IAchievement*)m_pAchievementMgr->GetAchievementByID(m_requirements[i]);
  92. Assert ( pAchievement );
  93. if ( pAchievement->IsAchieved() )
  94. iAchieved++;
  95. else
  96. break;
  97. }
  98. if ( iAchieved == m_requirements.Count() )
  99. {
  100. AwardAchievement();
  101. }
  102. }
  103. void CAchievement_Meta::AddRequirement( int nAchievementId )
  104. {
  105. m_requirements.AddToTail(nAchievementId);
  106. }
  107. #if 0
  108. bool CheckWinNoEnemyCaps( IGameEvent *event, int iRole );
  109. // Grace period that we allow a player to start after level init and still consider them to be participating for the full round. This is fairly generous
  110. // because it can in some cases take a client several minutes to connect with respect to when the server considers the game underway
  111. #define CS_FULL_ROUND_GRACE_PERIOD ( 4 * 60.0f )
  112. bool IsLocalCSPlayerClass( int iClass );
  113. //-----------------------------------------------------------------------------
  114. // Purpose:
  115. //-----------------------------------------------------------------------------
  116. void CCSBaseAchievementFullRound::Init()
  117. {
  118. m_iFlags |= ACH_FILTER_FULL_ROUND_ONLY;
  119. }
  120. //-----------------------------------------------------------------------------
  121. // Purpose:
  122. //-----------------------------------------------------------------------------
  123. void CCSBaseAchievementFullRound::ListenForEvents()
  124. {
  125. ListenForGameEvent( "teamplay_round_win" );
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Purpose:
  129. //-----------------------------------------------------------------------------
  130. void CCSBaseAchievementFullRound::FireGameEvent_Internal( IGameEvent *event )
  131. {
  132. if ( 0 == Q_strcmp( event->GetName(), "teamplay_round_win" ) )
  133. {
  134. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  135. if ( pLocalPlayer )
  136. {
  137. // is the player currently on a game team?
  138. int iTeam = pLocalPlayer->GetTeamNumber();
  139. if ( iTeam >= FIRST_GAME_TEAM )
  140. {
  141. float flRoundTime = event->GetFloat( "round_time", 0 );
  142. if ( flRoundTime > 0 )
  143. {
  144. Event_OnRoundComplete( flRoundTime, event );
  145. }
  146. }
  147. }
  148. }
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose:
  152. //-----------------------------------------------------------------------------
  153. bool CCSBaseAchievementFullRound::PlayerWasInEntireRound( float flRoundTime )
  154. {
  155. float flTeamplayStartTime = m_pAchievementMgr->GetTeamplayStartTime();
  156. if ( flTeamplayStartTime > 0 )
  157. {
  158. // has the player been present and on a game team since the start of this round (minus a grace period)?
  159. if ( flTeamplayStartTime < ( gpGlobals->curtime - flRoundTime ) + CS_FULL_ROUND_GRACE_PERIOD )
  160. return true;
  161. }
  162. return false;
  163. }
  164. #endif
  165. //Base class for all achievements to kill x players with a given weapon
  166. class CAchievement_StatGoal: public CCSBaseAchievement
  167. {
  168. public:
  169. void SetStatId(CSStatType_t stat)
  170. {
  171. m_StatId = stat;
  172. }
  173. private:
  174. virtual void Init()
  175. {
  176. SetFlags( ACH_SAVE_GLOBAL );
  177. }
  178. void OnPlayerStatsUpdate()
  179. {
  180. // when stats are updated by server, use most recent stat value
  181. const StatsCollection_t& roundStats = g_CSClientGameStats.GetLifetimeStats();
  182. int iOldCount = GetCount();
  183. SetCount(roundStats[m_StatId]);
  184. if ( GetCount() != iOldCount )
  185. {
  186. m_pAchievementMgr->SetDirty(true);
  187. }
  188. int iGoal = GetGoal();
  189. if (!IsAchieved() && iGoal > 0 )
  190. {
  191. if (achievements_easymode.GetBool())
  192. {
  193. iGoal /= 10;
  194. if ( iGoal == 0 )
  195. iGoal = 1;
  196. }
  197. if ( GetCount() >= iGoal )
  198. {
  199. AwardAchievement();
  200. }
  201. }
  202. }
  203. CSStatType_t m_StatId;
  204. };
  205. #define DECLARE_ACHIEVEMENT_STATGOAL( achievementID, achievementName, iPointValue, iStatId, iGoal ) \
  206. static CBaseAchievement *Create_##achievementID( void ) \
  207. { \
  208. CAchievement_StatGoal *pAchievement = new CAchievement_StatGoal(); \
  209. pAchievement->SetAchievementID( achievementID ); \
  210. pAchievement->SetName( achievementName ); \
  211. pAchievement->SetPointValue( iPointValue ); \
  212. pAchievement->SetHideUntilAchieved( false ); \
  213. pAchievement->SetStatId(iStatId); \
  214. pAchievement->SetGoal( iGoal ); \
  215. return pAchievement; \
  216. }; \
  217. static CBaseAchievementHelper g_##achievementID##_Helper( Create_##achievementID );
  218. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsLow, "KILL_ENEMY_LOW", 10, CSSTAT_KILLS, 25); //25
  219. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsMed, "KILL_ENEMY_MED", 10, CSSTAT_KILLS, 500); //500
  220. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsHigh, "KILL_ENEMY_HIGH", 10, CSSTAT_KILLS, 10000); //10000
  221. DECLARE_ACHIEVEMENT_STATGOAL(CSWinRoundsLow, "WIN_ROUNDS_LOW", 10, CSSTAT_ROUNDS_WON, 10); //10
  222. DECLARE_ACHIEVEMENT_STATGOAL(CSWinRoundsMed, "WIN_ROUNDS_MED", 10, CSSTAT_ROUNDS_WON, 200); //200
  223. DECLARE_ACHIEVEMENT_STATGOAL(CSWinRoundsHigh, "WIN_ROUNDS_HIGH", 10, CSSTAT_ROUNDS_WON, 5000); //5000
  224. DECLARE_ACHIEVEMENT_STATGOAL(CSWinPistolRoundsLow, "WIN_PISTOLROUNDS_LOW", 10, CSSTAT_PISTOLROUNDS_WON, 5); //5
  225. DECLARE_ACHIEVEMENT_STATGOAL(CSWinPistolRoundsMed, "WIN_PISTOLROUNDS_MED", 10, CSSTAT_PISTOLROUNDS_WON, 25); //25
  226. DECLARE_ACHIEVEMENT_STATGOAL(CSWinPistolRoundsHigh, "WIN_PISTOLROUNDS_HIGH", 10, CSSTAT_PISTOLROUNDS_WON, 250); //250
  227. DECLARE_ACHIEVEMENT_STATGOAL(CSMoneyEarnedLow, "EARN_MONEY_LOW", 10, CSSTAT_MONEY_EARNED, 125000); //125000
  228. DECLARE_ACHIEVEMENT_STATGOAL(CSMoneyEarnedMed, "EARN_MONEY_MED", 10, CSSTAT_MONEY_EARNED, 2500000); //2500000
  229. DECLARE_ACHIEVEMENT_STATGOAL(CSMoneyEarnedHigh, "EARN_MONEY_HIGH", 10, CSSTAT_MONEY_EARNED, 50000000); //50000000
  230. DECLARE_ACHIEVEMENT_STATGOAL(CSGiveDamageLow, "GIVE_DAMAGE_LOW", 10, CSSTAT_DAMAGE, 2500); //2500
  231. DECLARE_ACHIEVEMENT_STATGOAL(CSGiveDamageMed, "GIVE_DAMAGE_MED", 10, CSSTAT_DAMAGE, 50000); //50000
  232. DECLARE_ACHIEVEMENT_STATGOAL(CSGiveDamageHigh, "GIVE_DAMAGE_HIGH", 10, CSSTAT_DAMAGE, 1000000); //1000000
  233. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsDeagle, "KILL_ENEMY_DEAGLE", 5, CSSTAT_KILLS_DEAGLE, 200); //200
  234. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsUSP, "KILL_ENEMY_USP", 5, CSSTAT_KILLS_USP, 200); //200
  235. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsGlock, "KILL_ENEMY_GLOCK", 5, CSSTAT_KILLS_GLOCK, 200); //200
  236. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsP228, "KILL_ENEMY_P228", 5, CSSTAT_KILLS_P228, 200); //200
  237. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsElite, "KILL_ENEMY_ELITE", 5, CSSTAT_KILLS_ELITE, 100); //100
  238. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsFiveSeven, "KILL_ENEMY_FIVESEVEN", 5, CSSTAT_KILLS_FIVESEVEN, 100); //100
  239. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsAWP, "KILL_ENEMY_AWP", 5, CSSTAT_KILLS_AWP, 1000); //1000
  240. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsAK47, "KILL_ENEMY_AK47", 5, CSSTAT_KILLS_AK47, 1000); //1000
  241. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsM4A1, "KILL_ENEMY_M4A1", 5, CSSTAT_KILLS_M4A1, 1000); //1000
  242. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsAUG, "KILL_ENEMY_AUG", 5, CSSTAT_KILLS_AUG, 500); //500
  243. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsSG552, "KILL_ENEMY_SG552", 5, CSSTAT_KILLS_SG552, 500); //500
  244. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsSG550, "KILL_ENEMY_SG550", 5, CSSTAT_KILLS_SG550, 500); //500
  245. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsGALIL, "KILL_ENEMY_GALIL", 5, CSSTAT_KILLS_GALIL, 500); //500
  246. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsFAMAS, "KILL_ENEMY_FAMAS", 5, CSSTAT_KILLS_FAMAS, 500); //500
  247. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsScout, "KILL_ENEMY_SCOUT", 5, CSSTAT_KILLS_SCOUT, 1000); //1000
  248. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsG3SG1, "KILL_ENEMY_G3SG1", 5, CSSTAT_KILLS_G3SG1, 500); //500
  249. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsP90, "KILL_ENEMY_P90", 5, CSSTAT_KILLS_P90, 1000); //1000
  250. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsMP5NAVY, "KILL_ENEMY_MP5NAVY", 5, CSSTAT_KILLS_MP5NAVY, 1000); //1000
  251. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsTMP, "KILL_ENEMY_TMP", 5, CSSTAT_KILLS_TMP, 500); //500
  252. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsMAC10, "KILL_ENEMY_MAC10", 5, CSSTAT_KILLS_MAC10, 500); //500
  253. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsUMP45, "KILL_ENEMY_UMP45", 5, CSSTAT_KILLS_UMP45, 1000); //1000
  254. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsM3, "KILL_ENEMY_M3", 5, CSSTAT_KILLS_M3, 200); //200
  255. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsXM1014, "KILL_ENEMY_XM1014", 5, CSSTAT_KILLS_XM1014, 200); //200
  256. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsM249, "KILL_ENEMY_M249", 5, CSSTAT_KILLS_M249, 500); //500
  257. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsKnife, "KILL_ENEMY_KNIFE", 5, CSSTAT_KILLS_KNIFE, 100); //100
  258. DECLARE_ACHIEVEMENT_STATGOAL(CSEnemyKillsHEGrenade, "KILL_ENEMY_HEGRENADE", 5, CSSTAT_KILLS_HEGRENADE, 500); //500
  259. DECLARE_ACHIEVEMENT_STATGOAL(CSHeadshots, "HEADSHOTS", 5, CSSTAT_KILLS_HEADSHOT, 250); //250
  260. DECLARE_ACHIEVEMENT_STATGOAL(CSKillsEnemyWeapon, "KILLS_ENEMY_WEAPON", 5, CSSTAT_KILLS_ENEMY_WEAPON, 100); //100
  261. DECLARE_ACHIEVEMENT_STATGOAL(CSKillEnemyBlinded, "KILL_ENEMY_BLINDED", 5, CSSTAT_KILLS_ENEMY_BLINDED, 25); //25
  262. DECLARE_ACHIEVEMENT_STATGOAL(CSDefuseBombsLow, "BOMB_DEFUSE_LOW", 5, CSSTAT_NUM_BOMBS_DEFUSED, 100); //100
  263. DECLARE_ACHIEVEMENT_STATGOAL(CSPlantBombsLow, "BOMB_PLANT_LOW", 5, CSSTAT_NUM_BOMBS_PLANTED, 100); //100
  264. DECLARE_ACHIEVEMENT_STATGOAL(CSRescueHostagesLow, "RESCUE_HOSTAGES_LOW", 5, CSSTAT_NUM_HOSTAGES_RESCUED, 100); //100
  265. DECLARE_ACHIEVEMENT_STATGOAL(CSRescueHostagesMid, "RESCUE_HOSTAGES_MED", 5, CSSTAT_NUM_HOSTAGES_RESCUED, 500); //500
  266. DECLARE_ACHIEVEMENT_STATGOAL(CSWinKnifeFightsLow, "WIN_KNIFE_FIGHTS_LOW", 5, CSSTAT_KILLS_KNIFE_FIGHT, 1); //1
  267. DECLARE_ACHIEVEMENT_STATGOAL(CSWinKnifeFightsHigh, "WIN_KNIFE_FIGHTS_HIGH", 5, CSSTAT_KILLS_KNIFE_FIGHT, 100); //100
  268. DECLARE_ACHIEVEMENT_STATGOAL(CSDecalSprays, "DECAL_SPRAYS", 5, CSSTAT_DECAL_SPRAYS, 100); //100
  269. DECLARE_ACHIEVEMENT_STATGOAL(CSNightvisionDamage, "NIGHTVISION_DAMAGE", 5, CSSTAT_NIGHTVISION_DAMAGE, 5000); //5000
  270. DECLARE_ACHIEVEMENT_STATGOAL(CSKillSnipers, "KILL_SNIPERS", 5, CSSTAT_KILLS_AGAINST_ZOOMED_SNIPER, 100); //100
  271. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_ASSAULT, "WIN_MAP_CS_ASSAULT", 5, CSSTAT_MAP_WINS_CS_ASSAULT, 100); //100
  272. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_COMPOUND, "WIN_MAP_CS_COMPOUND", 5, CSSTAT_MAP_WINS_CS_COMPOUND, 100); //100
  273. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_HAVANA, "WIN_MAP_CS_HAVANA", 5, CSSTAT_MAP_WINS_CS_HAVANA, 100); //100
  274. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_ITALY, "WIN_MAP_CS_ITALY", 5, CSSTAT_MAP_WINS_CS_ITALY, 100); //100
  275. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_MILITIA, "WIN_MAP_CS_MILITIA", 5, CSSTAT_MAP_WINS_CS_MILITIA, 100); //100
  276. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapCS_OFFICE, "WIN_MAP_CS_OFFICE", 5, CSSTAT_MAP_WINS_CS_OFFICE, 100); //100
  277. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_AZTEC, "WIN_MAP_DE_AZTEC", 5, CSSTAT_MAP_WINS_DE_AZTEC, 100); //100
  278. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_CBBLE, "WIN_MAP_DE_CBBLE", 5, CSSTAT_MAP_WINS_DE_CBBLE, 100); //100
  279. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_CHATEAU, "WIN_MAP_DE_CHATEAU", 5, CSSTAT_MAP_WINS_DE_CHATEAU, 100); //100
  280. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_DUST2, "WIN_MAP_DE_DUST2", 5, CSSTAT_MAP_WINS_DE_DUST2, 100); //100
  281. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_DUST, "WIN_MAP_DE_DUST", 5, CSSTAT_MAP_WINS_DE_DUST, 100); //100
  282. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_INFERNO, "WIN_MAP_DE_INFERNO", 5, CSSTAT_MAP_WINS_DE_INFERNO, 100); //100
  283. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_NUKE, "WIN_MAP_DE_NUKE", 5, CSSTAT_MAP_WINS_DE_NUKE, 100); //100
  284. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_PIRANESI, "WIN_MAP_DE_PIRANESI", 5, CSSTAT_MAP_WINS_DE_PIRANESI, 100); //100
  285. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_PORT, "WIN_MAP_DE_PORT", 5, CSSTAT_MAP_WINS_DE_PORT, 100); //100
  286. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_PRODIGY, "WIN_MAP_DE_PRODIGY", 5, CSSTAT_MAP_WINS_DE_PRODIGY, 100); //100
  287. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_TIDES, "WIN_MAP_DE_TIDES", 5, CSSTAT_MAP_WINS_DE_TIDES, 100); //100
  288. DECLARE_ACHIEVEMENT_STATGOAL(CSWinMapDE_TRAIN, "WIN_MAP_DE_TRAIN", 5, CSSTAT_MAP_WINS_DE_TRAIN, 100); //100
  289. DECLARE_ACHIEVEMENT_STATGOAL(CSDonateWeapons, "DONATE_WEAPONS", 5, CSSTAT_WEAPONS_DONATED, 100); //100
  290. DECLARE_ACHIEVEMENT_STATGOAL(CSDominationsLow, "DOMINATIONS_LOW", 5, CSSTAT_DOMINATIONS, 1); //1
  291. DECLARE_ACHIEVEMENT_STATGOAL(CSDominationsHigh, "DOMINATIONS_HIGH", 5, CSSTAT_DOMINATIONS, 10); //10
  292. DECLARE_ACHIEVEMENT_STATGOAL(CSDominationOverkillsLow, "DOMINATION_OVERKILLS_LOW", 5, CSSTAT_DOMINATION_OVERKILLS, 1); //1
  293. DECLARE_ACHIEVEMENT_STATGOAL(CSDominationOverkillsHigh, "DOMINATION_OVERKILLS_HIGH",5, CSSTAT_DOMINATION_OVERKILLS, 100); //100
  294. DECLARE_ACHIEVEMENT_STATGOAL(CSRevengesLow, "REVENGES_LOW", 5, CSSTAT_REVENGES, 1); //1
  295. DECLARE_ACHIEVEMENT_STATGOAL(CSRevengesHigh, "REVENGES_HIGH", 5, CSSTAT_REVENGES, 20); //20
  296. //-----------------------------------------------------------------------------
  297. // Purpose: Generic server awarded achievement
  298. //-----------------------------------------------------------------------------
  299. class CAchievementCS_ServerAwarded : public CCSBaseAchievement
  300. {
  301. virtual void Init()
  302. {
  303. SetGoal(1);
  304. SetFlags( ACH_SAVE_GLOBAL );
  305. }
  306. // server fires an event for this achievement, no other code within achievement necessary
  307. };
  308. #define DECLARE_ACHIEVEMENT_SERVERAWARDED(achievementID, achievementName, iPointValue) \
  309. static CBaseAchievement *Create_##achievementID( void ) \
  310. { \
  311. CAchievementCS_ServerAwarded *pAchievement = new CAchievementCS_ServerAwarded( ); \
  312. pAchievement->SetAchievementID( achievementID ); \
  313. pAchievement->SetName( achievementName ); \
  314. pAchievement->SetPointValue( iPointValue ); \
  315. return pAchievement; \
  316. }; \
  317. static CBaseAchievementHelper g_##achievementID##_Helper( Create_##achievementID );
  318. // server triggered achievements
  319. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSBombDefuseCloseCall, "BOMB_DEFUSE_CLOSE_CALL", 5);
  320. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSDefuseAndNeededKit, "BOMB_DEFUSE_NEEDED_KIT", 5);
  321. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKilledDefuser, "KILL_BOMB_DEFUSER", 5);
  322. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinBombPlant, "WIN_BOMB_PLANT", 5);
  323. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinBombDefuse, "WIN_BOMB_DEFUSE", 5);
  324. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSPlantBombWithin25Seconds, "BOMB_PLANT_IN_25_SECONDS", 5);
  325. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSRescueAllHostagesInARound, "RESCUE_ALL_HOSTAGES", 5);
  326. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemyWithFormerGun, "KILL_WITH_OWN_GUN", 5);
  327. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillingSpree, "KILLING_SPREE", 5);
  328. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillTwoWithOneShot, "KILL_TWO_WITH_ONE_SHOT", 5);
  329. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemyReloading, "KILL_ENEMY_RELOADING", 5);
  330. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillsWithMultipleGuns, "KILLS_WITH_MULTIPLE_GUNS", 5);
  331. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSPosthumousGrenadeKill, "DEAD_GRENADE_KILL", 5);
  332. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemyTeam, "KILL_ENEMY_TEAM", 5);
  333. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSLastPlayerAlive, "LAST_PLAYER_ALIVE", 5);
  334. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemyLastBullet, "KILL_ENEMY_LAST_BULLET", 5);
  335. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillingSpreeEnder, "KILLING_SPREE_ENDER", 5);
  336. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemiesWhileBlind, "KILL_ENEMIES_WHILE_BLIND", 5);
  337. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemiesWhileBlindHard, "KILL_ENEMIES_WHILE_BLIND_HARD", 5);
  338. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSDamageNoKill, "DAMAGE_NO_KILL", 5);
  339. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillLowDamage, "KILL_LOW_DAMAGE", 5);
  340. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKilledRescuer, "KILL_HOSTAGE_RESCUER", 5);
  341. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSurviveGrenade, "SURVIVE_GRENADE", 5);
  342. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKilledDefuserWithGrenade, "KILLED_DEFUSER_WITH_GRENADE", 5);
  343. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSurvivedHeadshotDueToHelmet, "SURVIVED_HEADSHOT_DUE_TO_HELMET", 5);
  344. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillSniperWithSniper, "KILL_SNIPER_WITH_SNIPER", 5);
  345. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillSniperWithKnife, "KILL_SNIPER_WITH_KNIFE", 5);
  346. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSHipShot, "HIP_SHOT", 5);
  347. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillWhenAtLowHealth, "KILL_WHEN_AT_LOW_HEALTH", 5);
  348. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSGrenadeMultikill, "GRENADE_MULTIKILL", 5);
  349. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSBombMultikill, "BOMB_MULTIKILL", 5);
  350. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSPistolRoundKnifeKill, "PISTOL_ROUND_KNIFE_KILL", 5);
  351. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSFastRoundWin, "FAST_ROUND_WIN", 5);
  352. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSurviveManyAttacks, "SURVIVE_MANY_ATTACKS", 5);
  353. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSGooseChase, "GOOSE_CHASE", 5);
  354. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinBombPlantAfterRecovery, "WIN_BOMB_PLANT_AFTER_RECOVERY", 5);
  355. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSLosslessExtermination, "LOSSLESS_EXTERMINATION", 5);
  356. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSFlawlessVictory, "FLAWLESS_VICTORY", 5);
  357. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinDualDuel, "WIN_DUAL_DUEL", 5);
  358. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSFastHostageRescue, "FAST_HOSTAGE_RESCUE", 5);
  359. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSBreakWindows, "BREAK_WINDOWS", 5);
  360. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSBreakProps, "BREAK_PROPS", 5);
  361. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSUnstoppableForce, "UNSTOPPABLE_FORCE", 5);
  362. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSImmovableObject, "IMMOVABLE_OBJECT", 5);
  363. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSHeadshotsInRound, "HEADSHOTS_IN_ROUND", 5);
  364. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillWhileInAir, "KILL_WHILE_IN_AIR", 5);
  365. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillEnemyInAir, "KILL_ENEMY_IN_AIR", 5);
  366. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillerAndEnemyInAir, "KILLER_AND_ENEMY_IN_AIR", 5);
  367. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSilentWin, "SILENT_WIN", 5);
  368. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSBloodlessVictory, "BLOODLESS_VICTORY", 5);
  369. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinRoundsWithoutBuying, "WIN_ROUNDS_WITHOUT_BUYING", 5)
  370. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSDefuseDefense, "DEFUSE_DEFENSE", 5)
  371. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSKillBombPickup, "KILL_BOMB_PICKUP", 5)
  372. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSameUniform, "SAME_UNIFORM", 5)
  373. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSConcurrentDominations, "CONCURRENT_DOMINATIONS", 5)
  374. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSDominationOverkillsMatch, "DOMINATION_OVERKILLS_MATCH", 5)
  375. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSExtendedDomination, "EXTENDED_DOMINATION", 5)
  376. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSCauseFriendlyFireWithFlashbang, "CAUSE_FRIENDLY_FIRE_WITH_FLASHBANG", 5)
  377. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSWinClanMatch, "WIN_CLAN_MATCH", 5)
  378. DECLARE_ACHIEVEMENT_SERVERAWARDED(CSSnipeTwoFromSameSpot, "SNIPE_TWO_FROM_SAME_SPOT", 5 )
  379. //-----------------------------------------------------------------------------
  380. // Meta Achievements
  381. //-----------------------------------------------------------------------------
  382. //-----------------------------------------------------------------------------
  383. // Purpose: Get all the pistol achievements
  384. //-----------------------------------------------------------------------------
  385. class CAchievementCS_PistolMaster : public CAchievement_Meta
  386. {
  387. DECLARE_CLASS( CAchievementCS_PistolMaster, CAchievement_Meta );
  388. virtual void Init()
  389. {
  390. BaseClass::Init();
  391. AddRequirement(CSEnemyKillsDeagle);
  392. AddRequirement(CSEnemyKillsUSP);
  393. AddRequirement(CSEnemyKillsGlock);
  394. AddRequirement(CSEnemyKillsP228);
  395. AddRequirement(CSEnemyKillsElite);
  396. AddRequirement(CSEnemyKillsFiveSeven);
  397. }
  398. };
  399. DECLARE_ACHIEVEMENT(CAchievementCS_PistolMaster, CSMetaPistol, "META_PISTOL", 10);
  400. //-----------------------------------------------------------------------------
  401. // Purpose: Get all the rifle achievements
  402. //-----------------------------------------------------------------------------
  403. class CAchievementCS_RifleMaster : public CAchievement_Meta
  404. {
  405. DECLARE_CLASS( CAchievementCS_RifleMaster, CAchievement_Meta );
  406. virtual void Init()
  407. {
  408. BaseClass::Init();
  409. AddRequirement(CSEnemyKillsAWP);
  410. AddRequirement(CSEnemyKillsAK47);
  411. AddRequirement(CSEnemyKillsM4A1);
  412. AddRequirement(CSEnemyKillsAUG);
  413. AddRequirement(CSEnemyKillsSG552);
  414. AddRequirement(CSEnemyKillsSG550);
  415. AddRequirement(CSEnemyKillsGALIL);
  416. AddRequirement(CSEnemyKillsFAMAS);
  417. AddRequirement(CSEnemyKillsScout);
  418. AddRequirement(CSEnemyKillsG3SG1);
  419. }
  420. };
  421. DECLARE_ACHIEVEMENT(CAchievementCS_RifleMaster, CSMetaRifle, "META_RIFLE", 10);
  422. //-----------------------------------------------------------------------------
  423. // Purpose: Get all the SMG achievements
  424. //-----------------------------------------------------------------------------
  425. class CAchievementCS_SubMachineGunMaster : public CAchievement_Meta
  426. {
  427. DECLARE_CLASS( CAchievementCS_SubMachineGunMaster, CAchievement_Meta );
  428. virtual void Init()
  429. {
  430. BaseClass::Init();
  431. AddRequirement(CSEnemyKillsP90);
  432. AddRequirement(CSEnemyKillsMP5NAVY);
  433. AddRequirement(CSEnemyKillsTMP);
  434. AddRequirement(CSEnemyKillsMAC10);
  435. AddRequirement(CSEnemyKillsUMP45);
  436. }
  437. };
  438. DECLARE_ACHIEVEMENT(CAchievementCS_SubMachineGunMaster, CSMetaSMG, "META_SMG", 10);
  439. //-----------------------------------------------------------------------------
  440. // Purpose: Get all the Shotgun achievements
  441. //-----------------------------------------------------------------------------
  442. class CAchievementCS_ShotgunMaster : public CAchievement_Meta
  443. {
  444. DECLARE_CLASS( CAchievementCS_ShotgunMaster, CAchievement_Meta );
  445. virtual void Init()
  446. {
  447. BaseClass::Init();
  448. AddRequirement(CSEnemyKillsM3);
  449. AddRequirement(CSEnemyKillsXM1014);
  450. }
  451. };
  452. DECLARE_ACHIEVEMENT(CAchievementCS_ShotgunMaster, CSMetaShotgun, "META_SHOTGUN", 10);
  453. //-----------------------------------------------------------------------------
  454. // Purpose: Get every weapon achievement
  455. //-----------------------------------------------------------------------------
  456. class CAchievementCS_WeaponMaster : public CAchievement_Meta
  457. {
  458. DECLARE_CLASS( CAchievementCS_WeaponMaster, CAchievement_Meta );
  459. virtual void Init()
  460. {
  461. BaseClass::Init();
  462. AddRequirement(CSMetaPistol);
  463. AddRequirement(CSMetaRifle);
  464. AddRequirement(CSMetaSMG);
  465. AddRequirement(CSMetaShotgun);
  466. AddRequirement(CSEnemyKillsM249);
  467. AddRequirement(CSEnemyKillsKnife);
  468. AddRequirement(CSEnemyKillsHEGrenade);
  469. }
  470. };
  471. DECLARE_ACHIEVEMENT(CAchievementCS_WeaponMaster, CSMetaWeaponMaster, "META_WEAPONMASTER", 50);
  472. class CAchievementCS_KillWithAllWeapons : public CCSBaseAchievement
  473. {
  474. void Init()
  475. {
  476. SetFlags( ACH_SAVE_GLOBAL );
  477. SetGoal( 1 );
  478. }
  479. void OnPlayerStatsUpdate()
  480. {
  481. const StatsCollection_t& roundStats = g_CSClientGameStats.GetLifetimeStats();
  482. //Loop through all weapons we care about and make sure we got a kill with each.
  483. for (int i = 0; WeaponName_StatId_Table[i].killStatId != CSSTAT_UNDEFINED; ++i)
  484. {
  485. CSStatType_t statId = WeaponName_StatId_Table[i].killStatId;
  486. if ( roundStats[statId] == 0)
  487. {
  488. return;
  489. }
  490. }
  491. //If we haven't bailed yet, award the achievement.
  492. IncrementCount();
  493. }
  494. };
  495. DECLARE_ACHIEVEMENT( CAchievementCS_KillWithAllWeapons, CSKillWithEveryWeapon, "KILL_WITH_EVERY_WEAPON", 5 );
  496. class CAchievementCS_FriendsSameUniform : public CCSBaseAchievement
  497. {
  498. void Init()
  499. {
  500. SetFlags(ACH_SAVE_GLOBAL);
  501. SetGoal(1);
  502. }
  503. void ListenForEvents()
  504. {
  505. ListenForGameEvent( "round_start" );
  506. }
  507. void FireGameEvent_Internal( IGameEvent *event )
  508. {
  509. if ( Q_strcmp( event->GetName(), "round_start" ) == 0 )
  510. {
  511. int localPlayerIndex = GetLocalPlayerIndex();
  512. C_CSPlayer* pLocalPlayer = ToCSPlayer(UTIL_PlayerByIndex(localPlayerIndex));
  513. // Initialize all to 1, since the local player doesn't get counted as we loop.
  514. int numPlayersOnTeam = 1;
  515. int numFriendsOnTeam = 1;
  516. int numMatchingFriendsOnTeam = 1;
  517. if (pLocalPlayer)
  518. {
  519. int localPlayerClass = pLocalPlayer->PlayerClass();
  520. int localPlayerTeam = pLocalPlayer->GetTeamNumber();
  521. for ( int i = 1; i <= gpGlobals->maxClients; i++ )
  522. {
  523. if ( i != localPlayerIndex)
  524. {
  525. CCSPlayer *pPlayer = (CCSPlayer*) UTIL_PlayerByIndex( i );
  526. if (pPlayer)
  527. {
  528. if (pPlayer->GetTeamNumber() == localPlayerTeam)
  529. {
  530. ++numPlayersOnTeam;
  531. if (pLocalPlayer->HasPlayerAsFriend(pPlayer) )
  532. {
  533. ++numFriendsOnTeam;
  534. if ( pPlayer->PlayerClass() == localPlayerClass )
  535. ++numMatchingFriendsOnTeam;
  536. }
  537. }
  538. }
  539. }
  540. }
  541. if (numMatchingFriendsOnTeam >= AchievementConsts::FriendsSameUniform_MinPlayers )
  542. {
  543. AwardAchievement();
  544. }
  545. }
  546. }
  547. }
  548. };
  549. DECLARE_ACHIEVEMENT( CAchievementCS_FriendsSameUniform, CSFriendsSameUniform, "FRIENDS_SAME_UNIFORM", 5 );
  550. class CAchievementCS_AvengeFriend : public CCSBaseAchievement
  551. {
  552. void Init()
  553. {
  554. SetFlags(ACH_SAVE_GLOBAL);
  555. SetGoal(1);
  556. }
  557. void ListenForEvents()
  558. {
  559. ListenForGameEvent( "player_avenged_teammate" );
  560. }
  561. void FireGameEvent_Internal( IGameEvent *event )
  562. {
  563. if ( Q_strcmp( event->GetName(), "player_avenged_teammate" ) == 0 )
  564. {
  565. int localPlayerIndex = GetLocalPlayerIndex();
  566. C_CSPlayer* pLocalPlayer = ToCSPlayer(UTIL_PlayerByIndex(localPlayerIndex));
  567. //for debugging
  568. //int eventId = event->GetInt( "avenger_id" );
  569. //int localUserId = pLocalPlayer->GetUserID();
  570. if (pLocalPlayer && pLocalPlayer->GetUserID() == event->GetInt( "avenger_id" ))
  571. {
  572. int avengedPlayerIndex = engine->GetPlayerForUserID( event->GetInt( "avenged_player_id" ) );
  573. if ( avengedPlayerIndex > 0 )
  574. {
  575. C_CSPlayer* pAvengedPlayer = ToCSPlayer(UTIL_PlayerByIndex(avengedPlayerIndex));
  576. if (pAvengedPlayer && pLocalPlayer->HasPlayerAsFriend(pAvengedPlayer))
  577. {
  578. AwardAchievement();
  579. }
  580. }
  581. }
  582. }
  583. }
  584. };
  585. DECLARE_ACHIEVEMENT( CAchievementCS_AvengeFriend, CSAvengeFriend, "AVENGE_FRIEND", 5 );
  586. class CAchievementCS_CollectHolidayGifts : public CCSBaseAchievement
  587. {
  588. void Init()
  589. {
  590. SetFlags( ACH_SAVE_GLOBAL );
  591. SetGoal( 3 );
  592. SetStoreProgressInSteam( true );
  593. }
  594. virtual void ListenForEvents()
  595. {
  596. ListenForGameEvent( "christmas_gift_grab" );
  597. }
  598. void FireGameEvent_Internal( IGameEvent *event )
  599. {
  600. if ( !UTIL_IsHolidayActive( 3 /*kHoliday_Christmas*/ ) )
  601. return;
  602. if ( Q_strcmp( event->GetName(), "christmas_gift_grab" ) == 0 )
  603. {
  604. int iPlayer = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
  605. CBaseEntity *pPlayer = UTIL_PlayerByIndex( iPlayer );
  606. if ( pPlayer && pPlayer == C_CSPlayer::GetLocalCSPlayer() )
  607. {
  608. IncrementCount();
  609. }
  610. }
  611. }
  612. };
  613. DECLARE_ACHIEVEMENT( CAchievementCS_CollectHolidayGifts, CSCollectHolidayGifts, "COLLECT_GIFTS", 5 );
  614. #endif // CLIENT_DLL