Counter Strike : Global Offensive Source Code
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.

290 lines
12 KiB

  1. //===== Copyright � 1996-2009, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "mm_title.h"
  7. #include "portal2.spa.h"
  8. #include "matchmaking/portal2/imatchext_portal2.h"
  9. #include "steam/isteamuserstats.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. static TitleDataFieldsDescription_t const * PrepareTitleDataStorageDescription()
  13. {
  14. #define TD_ENTRY( szName, nTD, eDataType, numBytesOffset ) \
  15. { \
  16. TitleDataFieldsDescription_t aTDFD = { szName, TitleDataFieldsDescription_t::nTD, TitleDataFieldsDescription_t::eDataType, numBytesOffset }; \
  17. s_tdfd.AddToTail( aTDFD ); \
  18. }
  19. static CUtlVector< TitleDataFieldsDescription_t > s_tdfd;
  20. // Single player progress
  21. TD_ENTRY( "SP.progress", DB_TD1, DT_uint32, offsetof( TitleData1, uiSinglePlayerProgressChapter ) );
  22. // COOP MAPS
  23. #define CFG( fieldname, ctx, idx, num ) \
  24. TD_ENTRY( "MP.complete." #fieldname,DB_TD1, DT_BITFIELD, 8*offsetof( TitleData1, coop.mapbits ) + TitleData1::CoopData_t::fieldname )
  25. #define CFG_DISABLED( fieldname, ctx, idx, num )
  26. #include "xlast_portal2/inc_coop_maps.inc"
  27. #undef CFG_DISABLED
  28. #undef CFG
  29. // COOP TAUNTS
  30. TD_ENTRY( "MP.taunt.own", DB_TD1, DT_0, 8*offsetof( TitleData1, coop.tauntbitsOwned ) + 0 )
  31. #define CFG( fieldname ) \
  32. TD_ENTRY( "MP.taunt.own." #fieldname,DB_TD1, DT_BITFIELD, 8*offsetof( TitleData1, coop.tauntbitsOwned ) + TitleData1::CoopData_t::taunt_##fieldname ) \
  33. TD_ENTRY( "MP.taunt.use." #fieldname,DB_TD1, DT_BITFIELD, 8*offsetof( TitleData1, coop.tauntbitsUsed ) + TitleData1::CoopData_t::taunt_##fieldname )
  34. #define CFG_DISABLED( fieldname )
  35. #include "xlast_portal2/inc_coop_taunts.inc"
  36. #undef CFG_DISABLED
  37. #undef CFG
  38. // #define CFG( fieldname ) \
  39. // TD_ENTRY( "MP.taunt.equipslot." #fieldname,DB_TD1, DT_uint8, offsetof( TitleData1, coop.tauntsEquipSlots[ TitleData1::CoopData_t::taunt_equipslot_##fieldname ] ) )
  40. // #include "xlast_portal2/inc_coop_taunts_equipslots.inc"
  41. // #undef CFG
  42. // GAME INSTRUCTOR LESSONS
  43. #define CFG( fieldname ) \
  44. TD_ENTRY( "GI.lesson." #fieldname, DB_TD1, DT_uint8, offsetof( TitleData1, gameinstructor.lessoninfo[ TitleData1::GameInstructorData_t::lesson_##fieldname ] ) )
  45. #define CFG_DISABLED( fieldname )
  46. #include "xlast_portal2/inc_gameinstructor_lessons.inc"
  47. #undef CFG_DISABLED
  48. #undef CFG
  49. // Storage for achievements components
  50. uint32 uiAchievementComponentBitsUsed = 0;
  51. #define CFG( name, compcount, ... ) \
  52. { \
  53. COMPILE_TIME_ASSERT( (compcount == 0) || (compcount > 1) ); \
  54. int numAchNameChars = Q_strlen( "ACH." #name ); \
  55. for ( int iComponent = 0; iComponent < compcount; ++ iComponent ) \
  56. { \
  57. char *pszComponentName = new char[ numAchNameChars + 10 ]; \
  58. Q_snprintf( pszComponentName, numAchNameChars + 10, "%s[%d]", "ACH." #name, iComponent+1 ); \
  59. TD_ENTRY( pszComponentName, DB_TD2, DT_BITFIELD, 8*offsetof( TitleData2, bitsAchievementsComponents ) + uiAchievementComponentBitsUsed + iComponent ) \
  60. } \
  61. uiAchievementComponentBitsUsed += 32 * STORAGE_COUNT_FOR_BITS( uint32, compcount ); \
  62. }
  63. #include "inc_achievements.inc"
  64. #undef CFG
  65. #ifdef _X360
  66. // Awards bitfields
  67. #define CFG( award, ... ) \
  68. TD_ENTRY( "AV_TD_" #award, DB_TD2, DT_BITFIELD, 8*offsetof( TitleData2, awardbits ) + TitleData2::bitAward##award )
  69. #include "xlast_portal2/inc_asset_awards.inc"
  70. #undef CFG
  71. #endif
  72. // Custom achievements data
  73. {
  74. char const *szAch = "ACH.SPREAD_THE_LOVE";
  75. int numAchNameChars = Q_strlen( szAch );
  76. for ( int iComponent = 0; iComponent < TitleData2::kAchievement_SpreadTheLove_FriendsHuggedCount; ++ iComponent )
  77. {
  78. char *pszComponentName = new char[ numAchNameChars + 10 ];
  79. Q_snprintf( pszComponentName, numAchNameChars + 10, "%s[%d]", szAch, iComponent+1 );
  80. TD_ENTRY( pszComponentName, DB_TD2, DT_uint64, offsetof( TitleData2, ach_SpreadTheLove_FriendsHugged[iComponent] ) );
  81. }
  82. }
  83. {
  84. char const *szAch = "ACH.SPEED_RUN_COOP";
  85. int numAchNameChars = Q_strlen( szAch );
  86. for ( int iComponent = 0; iComponent < TitleData2::kAchievement_SpeedRunCoop_QualifiedRunsCount; ++ iComponent )
  87. {
  88. char *pszComponentName = new char[ numAchNameChars + 10 ];
  89. Q_snprintf( pszComponentName, numAchNameChars + 10, "%s[%d]", szAch, iComponent+1 );
  90. TD_ENTRY( pszComponentName, DB_TD2, DT_uint16, offsetof( TitleData2, ach_SpeedRunCoop_MapsQualified[iComponent] ) );
  91. }
  92. }
  93. #ifdef _PS3
  94. // DLC ownership bits
  95. #define CFG( fieldname ) \
  96. TD_ENTRY( "DLC." #fieldname,DB_TD2, DT_BITFIELD, 8*offsetof( TitleData2, dlcbits ) + fieldname )
  97. CFG( 0x12 )
  98. CFG( 0x13 )
  99. CFG( 0x14 )
  100. #undef CFG
  101. #endif
  102. #ifdef _GAMECONSOLE
  103. // system convars
  104. #define CFG( name, scfgType, cppType, ... ) \
  105. TD_ENTRY( "CFG.sys." #name, DB_TD3, DT_##cppType, offsetof( TitleData3, cvSystem.name ) )
  106. #include "xlast_portal2/inc_gameconsole_settings_sys.inc"
  107. #undef CFG
  108. #define CFG( name ) \
  109. TD_ENTRY( "CFG.sys." #name, DB_TD3, DT_BITFIELD, 8*offsetof( TitleData3, cvSystem.bitfields ) + TitleData3::ConVarsSystem_t::name )
  110. #include "xlast_portal2/inc_gameconsole_settings_sys_bits.inc"
  111. #undef CFG
  112. // profile-specific convars
  113. #define CFG( name, scfgType, cppType ) \
  114. TD_ENTRY( "CFG.usr." #name, DB_TD3, DT_##cppType, offsetof( TitleData3, cvUser.name ) ) \
  115. TD_ENTRY( "CFG.usrSS." #name, DB_TD3, DT_##cppType, offsetof( TitleData3, cvUserSS.name ) )
  116. #include "xlast_portal2/inc_gameconsole_settings_usr.inc"
  117. #undef CFG
  118. #define CFG( name ) \
  119. TD_ENTRY( "CFG.usr." #name, DB_TD3, DT_BITFIELD, 8*offsetof( TitleData3, cvUser.bitfields ) + TitleData3::ConVarsUser_t::name ) \
  120. TD_ENTRY( "CFG.usrSS." #name, DB_TD3, DT_BITFIELD, 8*offsetof( TitleData3, cvUserSS.bitfields ) + TitleData3::ConVarsUser_t::name )
  121. #include "xlast_portal2/inc_gameconsole_settings_usr_bits.inc"
  122. #undef CFG
  123. #endif
  124. // game stats
  125. #define CFG( name, scfgType, cppType ) \
  126. TD_ENTRY( "GAME." #name, DB_TD3, DT_##cppType, offsetof( TitleData3, gamestats.name ) )
  127. #include "xlast_portal2/inc_gamestats.inc"
  128. #undef CFG
  129. // END MARKER
  130. TD_ENTRY( NULL, DB_TD1, DT_0, 0 )
  131. #undef TD_ENTRY
  132. COMPILE_TIME_ASSERT( TitleData1::CoopData_t::mapbits_total >= TitleData1::CoopData_t::mapbits_last_bit_used );
  133. COMPILE_TIME_ASSERT( TitleData1::CoopData_t::tauntbits_total >= TitleData1::CoopData_t::tauntbits_last_bit_used );
  134. COMPILE_TIME_ASSERT( TitleData1::GameInstructorData_t::lessonbits_total >= TitleData1::GameInstructorData_t::lessonbits_last_bit_used );
  135. return s_tdfd.Base();
  136. }
  137. TitleDataFieldsDescription_t const * CMatchTitle::DescribeTitleDataStorage()
  138. {
  139. static TitleDataFieldsDescription_t const *s_pTDFD = PrepareTitleDataStorageDescription();
  140. return s_pTDFD;
  141. }
  142. TitleAchievementsDescription_t const * CMatchTitle::DescribeTitleAchievements()
  143. {
  144. static TitleAchievementsDescription_t tad[] =
  145. {
  146. #define CFG( name, compcount, ... ) \
  147. { "ACH." #name, ACHIEVEMENT_##name, compcount },
  148. #include "inc_achievements.inc"
  149. #undef CFG
  150. // END MARKER
  151. { NULL, 0 }
  152. };
  153. return tad;
  154. }
  155. TitleAvatarAwardsDescription_t const * CMatchTitle::DescribeTitleAvatarAwards()
  156. {
  157. static TitleAvatarAwardsDescription_t taad[] =
  158. {
  159. #define CFG( award, ... ) { "AV_" #award, AVATARASSETAWARD_##award, "AV_TD_" #award },
  160. #include "inc_asset_awards.inc"
  161. #undef CFG
  162. // END MARKER
  163. { NULL, 0 }
  164. };
  165. return taad;
  166. }
  167. TitleDlcDescription_t const * CMatchTitle::DescribeTitleDlcs()
  168. {
  169. static TitleDlcDescription_t tdlcs[] =
  170. {
  171. { PORTAL2_DLCID_RETAIL_DLC1, 0x80000001, 0x80000001, "DLC.0x01" },
  172. { PORTAL2_DLCID_COOP_BOT_SKINS, PORTAL2_DLC_APPID_COOP_BOT_SKINS, PORTAL2_DLC_PKGID_COOP_BOT_SKINS, "DLC.0x12" },
  173. { PORTAL2_DLCID_COOP_BOT_HELMETS, PORTAL2_DLC_APPID_COOP_BOT_HELMETS, PORTAL2_DLC_PKGID_COOP_BOT_HELMETS, "DLC.0x13" },
  174. { PORTAL2_DLCID_COOP_BOT_ANTENNA, PORTAL2_DLC_APPID_COOP_BOT_ANTENNA, PORTAL2_DLC_PKGID_COOP_BOT_ANTENNA, "DLC.0x14" },
  175. // END MARKER
  176. { 0, 0, 0 }
  177. };
  178. return tdlcs;
  179. }
  180. // Title leaderboards
  181. KeyValues * CMatchTitle::DescribeTitleLeaderboard( char const *szLeaderboardView )
  182. {
  183. // Check if this is a challenge leaderboard
  184. if ( char const *szChallenge = StringAfterPrefix( szLeaderboardView, "challenge_besttime_" ) )
  185. {
  186. // if ( IsX360() )
  187. // {
  188. // // Find the corresponding record in the mission script
  189. // KeyValues *pSettings = new KeyValues( "settings" );
  190. // KeyValues::AutoDelete autodelete_pSettings( pSettings );
  191. // pSettings->SetString( "game/mode", "survival" );
  192. //
  193. // KeyValues *pMissionInfo = NULL;
  194. // KeyValues *pMapInfo = g_pMatchExtSwarm->GetMapInfoByBspName( pSettings, szSurvivalMap, &pMissionInfo );
  195. // if ( !pMapInfo || !pMissionInfo )
  196. // return NULL;
  197. //
  198. // // Find the leaderboard description in the map info
  199. // KeyValues *pLbDesc = pMapInfo->FindKey( "x360leaderboard" );
  200. // if ( !pLbDesc )
  201. // return NULL;
  202. //
  203. // // Insert the required keys
  204. // pLbDesc = pLbDesc->MakeCopy();
  205. //
  206. // static KeyValues *s_pRatingKey = KeyValues::FromString( ":rating", // X360 leaderboards are rated
  207. // " name besttime " // game name of the rating field is "besttime"
  208. // " type uint64 " // type is uint64
  209. // " rule max" // rated field must be greater than cached value so that it can be written
  210. // );
  211. // pLbDesc->AddSubKey( s_pRatingKey->MakeCopy() );
  212. // pLbDesc->SetString( "besttime/type", "uint64" );
  213. //
  214. // return pLbDesc;
  215. // }
  216. //
  217. if ( !IsX360() )
  218. {
  219. KeyValues *pSettings = KeyValues::FromString( "SteamLeaderboard",
  220. " :score besttime " // :score is the leaderboard value mapped to game name "besttime"
  221. );
  222. pSettings->SetInt( ":sort", k_ELeaderboardSortMethodAscending ); // Sort order when fetching and displaying leaderboard data
  223. pSettings->SetInt( ":format", k_ELeaderboardDisplayTypeTimeMilliSeconds ); // Note: this is actually 1/100th seconds type, Steam change pending
  224. pSettings->SetInt( ":upload", k_ELeaderboardUploadScoreMethodKeepBest ); // Upload method when writing to leaderboard
  225. return pSettings;
  226. }
  227. }
  228. if ( char const *szChallenge = StringAfterPrefix( szLeaderboardView, "challenge_distance_" ) )
  229. {
  230. if ( !IsX360() )
  231. {
  232. KeyValues *pSettings = KeyValues::FromString( "SteamLeaderboard",
  233. " :score distance " // :score is the leaderboard value mapped to game name "distance"
  234. );
  235. pSettings->SetInt( ":sort", k_ELeaderboardSortMethodAscending ); // Sort order when fetching and displaying leaderboard data
  236. pSettings->SetInt( ":format", k_ELeaderboardDisplayTypeNumeric ); // Note: this is actually 1/100th seconds type, Steam change pending
  237. pSettings->SetInt( ":upload", k_ELeaderboardUploadScoreMethodKeepBest ); // Upload method when writing to leaderboard
  238. return pSettings;
  239. }
  240. }
  241. if ( char const *szChallenge = StringAfterPrefix( szLeaderboardView, "challenge_portals_" ) )
  242. {
  243. if ( !IsX360() )
  244. {
  245. KeyValues *pSettings = KeyValues::FromString( "SteamLeaderboard",
  246. " :score portals " // :score is the leaderboard value mapped to game name "portals"
  247. );
  248. pSettings->SetInt( ":sort", k_ELeaderboardSortMethodAscending ); // Sort order when fetching and displaying leaderboard data
  249. pSettings->SetInt( ":format", k_ELeaderboardDisplayTypeNumeric ); // Note: this is actually 1/100th seconds type, Steam change pending
  250. pSettings->SetInt( ":upload", k_ELeaderboardUploadScoreMethodKeepBest ); // Upload method when writing to leaderboard
  251. return pSettings;
  252. }
  253. }
  254. return NULL;
  255. }