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.

356 lines
12 KiB

  1. //========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "cs_shareddefs.h"
  8. #include "gametypes/igametypes.h"
  9. // NOTE: This has to be the last file included!
  10. #include "tier0/memdbgon.h"
  11. const float CS_PLAYER_SPEED_RUN = 260.0f;
  12. const float CS_PLAYER_SPEED_VIP = 227.0f;
  13. const float CS_PLAYER_SPEED_SHIELD = 160.0f;
  14. const float CS_PLAYER_SPEED_HAS_HOSTAGE = 200.0f;
  15. const float CS_PLAYER_SPEED_STOPPED = 1.0f;
  16. const float CS_PLAYER_SPEED_OBSERVER = 900.0f;
  17. const float CS_PLAYER_SPEED_DUCK_MODIFIER = 0.34f;
  18. const float CS_PLAYER_SPEED_WALK_MODIFIER = 0.52f;
  19. const float CS_PLAYER_SPEED_CLIMB_MODIFIER = 0.34f;
  20. const float CS_PLAYER_HEAVYARMOR_FLINCH_MODIFIER = 0.5f;
  21. const float CS_PLAYER_DUCK_SPEED_IDEAL = 8.0f;
  22. const char *pszWinPanelCategoryHeaders[] =
  23. {
  24. "",
  25. "#winpanel_topdamage",
  26. "#winpanel_topheadshots",
  27. "#winpanel_kills"
  28. };
  29. const char *PlayerModelInfo::g_customizationModelCT = "models/player/custom_player/scaffold_ct.mdl";
  30. const char *PlayerModelInfo::g_customizationModelT = "models/player/custom_player/scaffold_t.mdl";
  31. const char *PlayerModelInfo::g_defaultTModel = "tm_phoenix";
  32. const char *PlayerModelInfo::g_defaultCTModel = "ctm_st6";
  33. #define CFG( mdl_substr, skintone, def_glove, sleeve, override_sleeve ) { #mdl_substr, #skintone, #def_glove, #sleeve, #override_sleeve },
  34. static PlayerViewmodelArmConfig s_playerViewmodelArmConfigs[] =
  35. {
  36. #include "viewmodel_arm_config.inc"
  37. /*
  38. // Old values, leaving for reference
  39. // character model substr //skintone index // default glove model // associated sleeve // econ override sleeve ( if present, overrides associated sleeve if glove is econ )
  40. { "tm_leet", "0", "models/weapons/v_models/arms/glove_fingerless/v_glove_fingerless.mdl", "", "" },
  41. { "tm_phoenix", "0", "models/weapons/v_models/arms/glove_fullfinger/v_glove_fullfinger.mdl", "", "" },
  42. { "tm_separatist", "0", "models/weapons/v_models/arms/glove_fullfinger/v_glove_fullfinger.mdl", "models/weapons/v_models/arms/separatist/v_sleeve_separatist.mdl", "" },
  43. { "tm_balkan", "0", "models/weapons/v_models/arms/glove_fullfinger/v_glove_fullfinger.mdl", "models/weapons/v_models/arms/balkan/v_sleeve_balkan.mdl", "" },
  44. { "tm_professional_var4", "1", "models/weapons/v_models/arms/glove_fullfinger/v_glove_fullfinger.mdl", "models/weapons/v_models/arms/professional/v_sleeve_professional.mdl", "" },
  45. { "tm_professional", "0", "models/weapons/v_models/arms/glove_fullfinger/v_glove_fullfinger.mdl", "models/weapons/v_models/arms/professional/v_sleeve_professional.mdl", "" },
  46. { "tm_anarchist", "0", "models/weapons/v_models/arms/anarchist/v_glove_anarchist.mdl", "", "models/weapons/v_models/arms/anarchist/v_sleeve_anarchist.mdl" },
  47. { "tm_pirate", "1", "models/weapons/v_models/arms/bare/v_bare_hands.mdl", "models/weapons/v_models/arms/pirate/v_pirate_watch.mdl", "" },
  48. { "tm_heavy", "0", "models/weapons/v_models/arms/glove_fingerless/v_glove_fingerless.mdl", "models/weapons/v_models/arms/balkan/v_sleeve_balkan.mdl", "" },
  49. { "ctm_st6", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle.mdl", "models/weapons/v_models/arms/st6/v_sleeve_st6.mdl", "" },
  50. { "ctm_idf", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle.mdl", "models/weapons/v_models/arms/idf/v_sleeve_idf.mdl", "" },
  51. { "ctm_gign", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_blue.mdl", "models/weapons/v_models/arms/gign/v_sleeve_gign.mdl", "" },
  52. { "ctm_swat_variantb", "1", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_black.mdl", "models/weapons/v_models/arms/swat/v_sleeve_swat.mdl", "" },
  53. { "ctm_swat", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_black.mdl", "models/weapons/v_models/arms/swat/v_sleeve_swat.mdl", "" },
  54. { "ctm_gsg9", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_blue.mdl", "models/weapons/v_models/arms/gsg9/v_sleeve_gsg9.mdl", "" },
  55. { "ctm_sas", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_black.mdl", "models/weapons/v_models/arms/sas/v_sleeve_sas.mdl", "" },
  56. { "ctm_fbi", "0", "models/weapons/v_models/arms/glove_hardknuckle/v_glove_hardknuckle_black.mdl", "models/weapons/v_models/arms/fbi/v_sleeve_fbi.mdl", "" },
  57. */
  58. };
  59. #undef CFG
  60. PlayerModelInfo PlayerModelInfo::s_PlayerModelInfo;
  61. PlayerModelInfo::PlayerModelInfo()
  62. {
  63. #if !defined( CLIENT_DLL )
  64. m_NumTModels = 0;
  65. m_NumCTModels = 0;
  66. m_NumModels = 0;
  67. m_nNextClassT = -1;
  68. m_nNextClassCT = -1;
  69. m_mapName[0] = 0;
  70. for ( int i=0; i<CS_MAX_PLAYER_MODELS; ++i )
  71. {
  72. m_ClassModelPaths[i][0] = 0;
  73. m_ClassNames[i][0] = 0;
  74. }
  75. #endif // !CLIENT_DLL
  76. }
  77. const PlayerViewmodelArmConfig *GetPlayerViewmodelArmConfigForPlayerModel( const char* szPlayerModel )
  78. {
  79. if ( szPlayerModel != NULL )
  80. {
  81. for ( int i=0; i<ARRAYSIZE(s_playerViewmodelArmConfigs); i++ )
  82. {
  83. if ( V_stristr( szPlayerModel, s_playerViewmodelArmConfigs[i].szPlayerModelSearchSubStr ) )
  84. return &s_playerViewmodelArmConfigs[i];
  85. }
  86. }
  87. AssertMsg1( false, "Could not determine viewmodel config for character model: %s", szPlayerModel );
  88. return &s_playerViewmodelArmConfigs[0];
  89. }
  90. #if !defined( CLIENT_DLL )
  91. bool PlayerModelInfo::IsTClass( int i )
  92. {
  93. // The 0 model is class NONE
  94. return (i >= GetFirstTClass() && i <= GetLastTClass() );
  95. }
  96. bool PlayerModelInfo::IsCTClass( int i )
  97. {
  98. // The 0 model is class NONE
  99. return (i >= GetFirstCTClass() && i <= GetLastCTClass() );
  100. }
  101. const char *PlayerModelInfo::GetClassName( int classID )
  102. {
  103. AssertMsg( classID >= GetFirstClass() && classID <= GetLastClass(), "Invalid class ID for models loaded.\n ");
  104. return m_ClassNames[classID-1];
  105. }
  106. const char *PlayerModelInfo::GetClassModelPath( int classID )
  107. {
  108. AssertMsg( classID >= GetFirstClass() && classID <= GetLastClass(), "Invalid class ID for models loaded.\n ");
  109. return m_ClassModelPaths[classID-1];
  110. }
  111. int PlayerModelInfo::GetNextClassForTeam( int team )
  112. {
  113. if ( team == TEAM_TERRORIST )
  114. {
  115. if ( m_nNextClassT == -1 )
  116. {
  117. m_nNextClassT = RandomInt( GetFirstTClass(), GetLastTClass() );
  118. }
  119. ++m_nNextClassT;
  120. if ( m_nNextClassT > GetLastTClass() )
  121. {
  122. m_nNextClassT = GetFirstTClass();
  123. }
  124. return m_nNextClassT;
  125. }
  126. else if ( team == TEAM_CT )
  127. {
  128. if ( m_nNextClassCT == -1 )
  129. {
  130. m_nNextClassCT = RandomInt( GetFirstCTClass(), GetLastCTClass() );
  131. }
  132. ++m_nNextClassCT;
  133. if ( m_nNextClassCT > GetLastCTClass() )
  134. {
  135. m_nNextClassCT = GetFirstCTClass();
  136. }
  137. return m_nNextClassCT;
  138. }
  139. else
  140. {
  141. return GetFirstClass();
  142. }
  143. }
  144. void PlayerModelInfo::InitializeForCurrentMap( void )
  145. {
  146. const char *mapName = ( gpGlobals ? STRING( gpGlobals->mapname ) : NULL );
  147. if ( mapName &&
  148. V_stricmp( m_mapName, mapName ) == 0 )
  149. {
  150. // We have already cached the model information for this map.
  151. return;
  152. }
  153. if ( mapName )
  154. {
  155. V_strcpy( m_mapName, mapName );
  156. }
  157. else
  158. {
  159. m_mapName[0] = '\0';
  160. }
  161. m_NumTModels = 0;
  162. m_NumCTModels = 0;
  163. m_NumModels = 0;
  164. m_nNextClassCT = -1;
  165. m_nNextClassT = -1;
  166. bool bUseCosmetics = false;
  167. // If the custom character system is enabled, we should load invisible skeleton players that will be eventually clothed.
  168. if ( bUseCosmetics )
  169. {
  170. //FIXME: custom characters have no audio persona; that is they don't speak yet (who would they sound like?)
  171. AddModel( g_customizationModelT );
  172. m_NumTModels = 1;
  173. AddModel( g_customizationModelCT );
  174. m_NumCTModels = 1;
  175. DevMsg( "Using script-defined character customization definitions\n" );
  176. }
  177. else
  178. {
  179. // Add the terrorist models.
  180. // NOTE: Terrorists must be loaded first since it is assumed they are first in the list of models.
  181. const CUtlStringList *pTModelNames = g_pGameTypes->GetTModelsForMap( m_mapName );
  182. if ( pTModelNames )
  183. {
  184. FOR_EACH_VEC( *pTModelNames, iModel )
  185. {
  186. const char *modelName = (*pTModelNames)[iModel];
  187. if ( modelName )
  188. {
  189. AddModel( modelName );
  190. }
  191. }
  192. m_NumTModels = m_NumModels;
  193. }
  194. // Add the default terrorist model, if no models were loaded.
  195. if ( m_NumTModels == 0 )
  196. {
  197. Warning( "PlayerModelInfo: missing terrorist models for map %s. Adding the default model %s.\n", m_mapName, g_defaultTModel );
  198. AddModel( g_defaultTModel );
  199. m_NumTModels = 1;
  200. }
  201. // Add the counter-terrorist models.
  202. const CUtlStringList *pCTModelNames = g_pGameTypes->GetCTModelsForMap( m_mapName );
  203. if ( pCTModelNames )
  204. {
  205. FOR_EACH_VEC( *pCTModelNames, iModel )
  206. {
  207. const char *modelName = (*pCTModelNames)[iModel];
  208. if ( modelName )
  209. {
  210. AddModel( modelName );
  211. }
  212. }
  213. m_NumCTModels = m_NumModels - m_NumTModels;
  214. }
  215. // Add the default counter-terrorist model, if no models were loaded.
  216. if ( m_NumCTModels == 0 )
  217. {
  218. Warning( "PlayerModelInfo: missing counter-terrorist models for map %s. Adding the default model %s.\n", m_mapName, g_defaultCTModel );
  219. AddModel( g_defaultCTModel );
  220. m_NumCTModels = 1;
  221. }
  222. }
  223. }
  224. void PlayerModelInfo::AddModel( const char *modelName )
  225. {
  226. Assert( modelName );
  227. if ( !modelName ||
  228. modelName[0] == '\0' )
  229. {
  230. return;
  231. }
  232. Assert( m_NumModels >= 0 && m_NumModels < CS_MAX_PLAYER_MODELS );
  233. if ( m_NumModels >= 0 && m_NumModels < CS_MAX_PLAYER_MODELS )
  234. {
  235. V_strcpy_safe( m_ClassNames[m_NumModels], modelName );
  236. if ( V_stristr( modelName, "scaffold" ) )
  237. {
  238. V_strcpy_safe( m_ClassModelPaths[m_NumModels], modelName );
  239. }
  240. else
  241. {
  242. char szCleanedPath[MAX_MODEL_STRING_SIZE];
  243. V_StrSubst( m_ClassNames[m_NumModels], "models/player", "", szCleanedPath, sizeof(szCleanedPath) );
  244. char szRedirectedPath[MAX_MODEL_STRING_SIZE];
  245. V_sprintf_safe( szRedirectedPath, "models/player/custom_player/legacy/%s", szCleanedPath );
  246. if ( !V_stristr( szRedirectedPath, ".mdl" ) )
  247. V_strcat_safe( szRedirectedPath, ".mdl" );
  248. if ( !filesystem->FileExists( szRedirectedPath, "MOD" ) )
  249. {
  250. AssertMsg1( false, "Verify map .kv: Player model doesn't exist: %s.", szRedirectedPath );
  251. // Get a full path to the mdl file.
  252. if ( !V_stristr( modelName, "models/player" ) && !V_stristr( modelName, ".mdl" ) )
  253. {
  254. V_snprintf( m_ClassModelPaths[m_NumModels], sizeof( m_ClassModelPaths[m_NumModels] ), "models/player/%s.mdl", modelName );
  255. }
  256. else
  257. {
  258. V_snprintf( m_ClassModelPaths[m_NumModels], sizeof( m_ClassModelPaths[m_NumModels] ), "%s", modelName );
  259. }
  260. }
  261. else
  262. {
  263. V_strcpy_safe( m_ClassModelPaths[m_NumModels], szRedirectedPath );
  264. }
  265. }
  266. ++m_NumModels;
  267. }
  268. else
  269. {
  270. Warning( "PlayerModelInfo: model count has exceeded the maximum (%d) for map \"%s\". Ignoring model %s.\n",
  271. CS_MAX_PLAYER_MODELS, m_mapName, modelName );
  272. }
  273. }
  274. #endif // !CLIENT_DLL
  275. const char* QuestProgress::ReasonString(Reason reason)
  276. {
  277. switch(reason)
  278. {
  279. case QUEST_OK:
  280. return "ok";
  281. case QUEST_NOT_ENOUGH_PLAYERS:
  282. return "not_enough_players";
  283. case QUEST_WARMUP:
  284. return "warmup";
  285. case QUEST_NOT_CONNECTED_TO_STEAM:
  286. return "not_connected_to_steam";
  287. case QUEST_NONOFFICIAL_SERVER:
  288. return "nonofficial_server";
  289. case QUEST_NO_ENTITLEMENT:
  290. return "no_entitlement";
  291. case QUEST_NO_QUEST:
  292. return "no_quest";
  293. case QUEST_PLAYER_IS_BOT:
  294. return "player_is_bot";
  295. case QUEST_WRONG_MAP:
  296. return "wrong_map";
  297. case QUEST_WRONG_MODE:
  298. return "wrong_mode";
  299. case QUEST_NOT_SYNCED_WITH_SERVER:
  300. return "not_synced_with_server";
  301. case QUEST_NONINITIALIZED: // treat as 'unknown reason'.
  302. default:
  303. return "unknown";
  304. }
  305. }