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.

457 lines
18 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The Half-Life 2 game rules, such as the relationship tables and ammo
  4. // damage cvars.
  5. //
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "portal_gamerules.h"
  10. #include "ammodef.h"
  11. #include "hl2_shareddefs.h"
  12. #include "portal_shareddefs.h"
  13. #include "weapon_portalgun_shared.h"
  14. #ifndef CLIENT_DLL
  15. #include "player_voice_listener.h"
  16. #endif // CLIENT_DLL
  17. #ifdef CLIENT_DLL
  18. #ifndef NO_STEAM
  19. #include "steam/steam_api.h"
  20. #endif //NO_STEAM
  21. #include "c_user_message_register.h"
  22. #else
  23. #include "player.h"
  24. #include "game.h"
  25. #include "gamerules.h"
  26. #include "teamplay_gamerules.h"
  27. #include "portal_player.h"
  28. #include "globalstate.h"
  29. #include "ai_basenpc.h"
  30. #include "portal/weapon_physcannon.h"
  31. #include "props.h" // For props flags used in making the portal weight box
  32. #include "datacache/imdlcache.h" // For precaching box model
  33. #include "vscript_server.h"
  34. #endif
  35. // memdbgon must be the last include file in a .cpp file!!!
  36. #include "tier0/memdbgon.h"
  37. #ifdef CLIENT_DLL
  38. extern ConVar locator_lerp_rest;
  39. extern ConVar locator_start_at_crosshair;
  40. extern ConVar locator_topdown_style;
  41. extern ConVar locator_background_style;
  42. extern ConVar locator_background_color;
  43. extern ConVar locator_background_thickness_x;
  44. extern ConVar locator_background_thickness_y;
  45. extern ConVar locator_target_offset_x;
  46. extern ConVar locator_target_offset_y;
  47. extern ConVar locator_background_shift_x;
  48. extern ConVar locator_background_shift_y;
  49. extern ConVar locator_background_border_color;
  50. extern ConVar locator_icon_min_size_non_ss;
  51. extern ConVar locator_icon_max_size_non_ss;
  52. #endif // CLIENT_DLL
  53. REGISTER_GAMERULES_CLASS( CPortalGameRules );
  54. BEGIN_NETWORK_TABLE_NOBASE( CPortalGameRules, DT_PortalGameRules )
  55. END_NETWORK_TABLE()
  56. IMPLEMENT_NETWORKCLASS_ALIASED( PortalGameRulesProxy, DT_PortalGameRulesProxy )
  57. LINK_ENTITY_TO_CLASS_ALIASED( portal_gamerules, PortalGameRulesProxy );
  58. #ifdef CLIENT_DLL
  59. void RecvProxy_PortalGameRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
  60. {
  61. CPortalGameRules *pRules = PortalGameRules();
  62. Assert( pRules );
  63. *pOut = pRules;
  64. }
  65. BEGIN_RECV_TABLE( CPortalGameRulesProxy, DT_PortalGameRulesProxy )
  66. RecvPropDataTable( "portal_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_PortalGameRules ), RecvProxy_PortalGameRules )
  67. END_RECV_TABLE()
  68. #else
  69. void* SendProxy_PortalGameRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
  70. {
  71. CPortalGameRules *pRules = PortalGameRules();
  72. Assert( pRules );
  73. pRecipients->SetAllRecipients();
  74. return pRules;
  75. }
  76. BEGIN_SEND_TABLE( CPortalGameRulesProxy, DT_PortalGameRulesProxy )
  77. SendPropDataTable( "portal_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_PortalGameRules ), SendProxy_PortalGameRules )
  78. END_SEND_TABLE()
  79. #endif
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. // Input :
  83. // Output :
  84. //-----------------------------------------------------------------------------
  85. CPortalGameRules::CPortalGameRules()
  86. {
  87. #ifndef CLIENT_DLL
  88. g_pCVar->FindVar( "sv_maxreplay" )->SetValue( "1.5" );
  89. if ( !GlobalEntity_IsInTable( "player_regenerates_health" ) )
  90. GlobalEntity_Add( MAKE_STRING("player_regenerates_health"), gpGlobals->mapname, GLOBAL_ON );
  91. else
  92. GlobalEntity_SetState( MAKE_STRING("player_regenerates_health"), GLOBAL_ON );
  93. if ( gpGlobals->mapname.ToCStr() && StringHasPrefix( gpGlobals->mapname.ToCStr(), "mp_coop" ) )
  94. {
  95. static ConVarRef flashlightbrightness( "r_flashlightbrightness" );
  96. if ( flashlightbrightness.IsValid() )
  97. {
  98. // All MP maps use this brightness but don't set it explicitly... we need this here for MP maps in commentary mode
  99. flashlightbrightness.SetValue( 0.25f );
  100. }
  101. }
  102. #else
  103. locator_lerp_rest.SetValue( 0.0f );
  104. locator_start_at_crosshair.SetValue( 0 );
  105. locator_topdown_style.SetValue( 0 );
  106. locator_background_style.SetValue( 0 );
  107. locator_background_color.SetValue( "0 0 0 128");
  108. locator_target_offset_x.SetValue( 0 );
  109. locator_target_offset_y.SetValue( 0 );
  110. locator_background_thickness_x.SetValue( 12 );
  111. locator_background_thickness_y.SetValue( 12 );
  112. locator_background_shift_x.SetValue( 0 );
  113. locator_background_shift_y.SetValue( 0 );
  114. locator_background_border_color.SetValue( "32 32 32 64" );
  115. locator_icon_min_size_non_ss.SetValue( 1.5f );
  116. locator_icon_max_size_non_ss.SetValue( 1.75f );
  117. #endif
  118. }
  119. #ifndef CLIENT_DLL
  120. // ------------------------------------------------------------------------------------
  121. // Parse commands coming down from the client
  122. // ------------------------------------------------------------------------------------
  123. bool CPortalGameRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
  124. {
  125. const char *pcmd = args[0];
  126. if ( FStrEq( pcmd, "lobby_select_day" ) )
  127. {
  128. if ( args.ArgC() < 2 )
  129. return true;
  130. //int nDay = atoi( args[1] );
  131. // Msg("Selecting day %d\n", nDay );
  132. return true;
  133. }
  134. return BaseClass::ClientCommand( pEdict, args );
  135. }
  136. // ------------------------------------------------------------------------------------
  137. //
  138. // ------------------------------------------------------------------------------------
  139. const char *CPortalGameRules::GetGameDescription( void )
  140. {
  141. #ifdef PORTAL2
  142. return "Portal 2";
  143. #else
  144. return "Portal";
  145. #endif
  146. }
  147. // ------------------------------------------------------------------------------------
  148. //
  149. // ------------------------------------------------------------------------------------
  150. bool CPortalGameRules::AllowDamage( CBaseEntity *pVictim, const CTakeDamageInfo &info )
  151. {
  152. return BaseClass::AllowDamage( pVictim, info );
  153. }
  154. bool CPortalGameRules::IsSavingAllowed( void )
  155. {
  156. if ( UTIL_GetLocalPlayerOrListenServerHost()->GetBonusChallenge() > 0 )
  157. {
  158. return false;
  159. }
  160. return true;
  161. }
  162. #else
  163. // ------------------------------------------------------------------------------------
  164. //
  165. // ------------------------------------------------------------------------------------
  166. bool CPortalGameRules::IsBonusChallengeTimeBased( void )
  167. {
  168. CBasePlayer* pPlayer = UTIL_PlayerByIndex( 1 );
  169. if ( !pPlayer )
  170. return true;
  171. int iBonusChallenge = pPlayer->GetBonusChallenge();
  172. if ( iBonusChallenge == PORTAL_CHALLENGE_TIME || iBonusChallenge == PORTAL_CHALLENGE_NONE )
  173. return true;
  174. return false;
  175. }
  176. bool CPortalGameRules::IsChallengeMode()
  177. {
  178. CBasePlayer* pPlayer = UTIL_PlayerByIndex( 1 );
  179. if ( pPlayer )
  180. return pPlayer->GetBonusChallenge() != 0;
  181. return false;
  182. }
  183. #endif// !( CLIENT_DLL )
  184. bool CPortalGameRules::ShouldCollide( int collisionGroup0, int collisionGroup1 )
  185. {
  186. if ( collisionGroup0 > collisionGroup1 )
  187. {
  188. // swap so that lowest is always first
  189. V_swap(collisionGroup0,collisionGroup1);
  190. }
  191. // Cubes shouldn't collide with debris but should otherwise act like COLLISION_GROUP_NONE
  192. if( collisionGroup1 == COLLISION_GROUP_WEIGHTED_CUBE && collisionGroup0 == COLLISION_GROUP_DEBRIS )
  193. return false;
  194. if( collisionGroup0 == COLLISION_GROUP_WEIGHTED_CUBE )
  195. collisionGroup0 = COLLISION_GROUP_NONE;
  196. if( collisionGroup1 == COLLISION_GROUP_WEIGHTED_CUBE )
  197. collisionGroup1 = COLLISION_GROUP_NONE;
  198. return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );
  199. }
  200. // ------------------------------------------------------------------------------------ //
  201. // Global functions.
  202. // ------------------------------------------------------------------------------------ //
  203. // shared ammo definition
  204. // JAY: Trying to make a more physical bullet response
  205. #define BULLET_MASS_GRAINS_TO_LB(grains) (0.002285*(grains)/16.0f)
  206. #define BULLET_MASS_GRAINS_TO_KG(grains) lbs2kg(BULLET_MASS_GRAINS_TO_LB(grains))
  207. // exaggerate all of the forces, but use real numbers to keep them consistent
  208. #define BULLET_IMPULSE_EXAGGERATION 3.5
  209. // convert a velocity in ft/sec and a mass in grains to an impulse in kg in/s
  210. #define BULLET_IMPULSE(grains, ftpersec) ((ftpersec)*12*BULLET_MASS_GRAINS_TO_KG(grains)*BULLET_IMPULSE_EXAGGERATION)
  211. CAmmoDef *GetAmmoDef()
  212. {
  213. static CAmmoDef def;
  214. static bool bInitted = false;
  215. if ( !bInitted )
  216. {
  217. bInitted = true;
  218. def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar2", "sk_npc_dmg_ar2", "sk_max_ar2", BULLET_IMPULSE(200, 1225), 0 );
  219. def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 );
  220. def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 );
  221. def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_smg1", "sk_npc_dmg_smg1", "sk_max_smg1", BULLET_IMPULSE(200, 1225), 0 );
  222. def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_357", "sk_npc_dmg_357", "sk_max_357", BULLET_IMPULSE(800, 5000), 0 );
  223. def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_crossbow", "sk_npc_dmg_crossbow", "sk_max_crossbow", BULLET_IMPULSE(800, 8000), 0 );
  224. def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", "sk_npc_dmg_buckshot", "sk_max_buckshot", BULLET_IMPULSE(400, 1200), 0 );
  225. def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 );
  226. def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 );
  227. def.AddAmmoType("SniperRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_plr_dmg_sniper_round", "sk_npc_dmg_sniper_round", "sk_max_sniper_round", BULLET_IMPULSE(650, 6000), 0 );
  228. def.AddAmmoType("SniperPenetratedRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_dmg_sniper_penetrate_plr", "sk_dmg_sniper_penetrate_npc", "sk_max_sniper_round", BULLET_IMPULSE(150, 6000), 0 );
  229. def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0);
  230. def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 );
  231. def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 );
  232. def.AddAmmoType("Battery", DMG_CLUB, TRACER_NONE, NULL, NULL, NULL, 0, 0 );
  233. #ifndef PORTAL2
  234. def.AddAmmoType("GaussEnergy", DMG_SHOCK, TRACER_NONE, "sk_jeep_gauss_damage", "sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s
  235. #endif
  236. def.AddAmmoType("CombineCannon", DMG_BULLET, TRACER_LINE, "sk_npc_dmg_gunship_to_plr", "sk_npc_dmg_gunship", NULL, 1.5 * 750 * 12, 0 ); // hit like a 1.5kg weight at 750 ft/s
  237. def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 );
  238. def.AddAmmoType("StriderMinigun", DMG_BULLET, TRACER_LINE, 5, 5, 15, 1.0 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 1.0kg weight at 750 ft/s
  239. #ifndef PORTAL2
  240. def.AddAmmoType("HelicopterGun", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_npc_dmg_helicopter_to_plr", "sk_npc_dmg_helicopter", "sk_max_smg1", BULLET_IMPULSE(400, 1225), AMMO_FORCE_DROP_IF_CARRIED | AMMO_INTERPRET_PLRDAMAGE_AS_DAMAGE_TO_PLAYER );
  241. #endif
  242. def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, "sk_max_ar2_altfire", 0, 0 );
  243. def.AddAmmoType("PortalTurretBullet", DMG_BULLET, TRACER_LINE_AND_WHIZ, 3, 3, 150, BULLET_IMPULSE(200, 1225), 0 );
  244. }
  245. return &def;
  246. }
  247. ///////////////////////////////////////////////////////////////////////
  248. // Portal singleplayer specific global vscript functions
  249. ///////////////////////////////////////////////////////////////////////
  250. #if !defined ( CLIENT_DLL )
  251. static bool ScriptIsMultiplayer( void )
  252. {
  253. return false;//g_pGameRules->IsMultiplayer();
  254. }
  255. static bool TryDLC1InstalledOrCatch( void )
  256. {
  257. return true;
  258. }
  259. extern float GetPlayerSilenceDuration( int nPlayer );
  260. extern int GetOrangePlayerIndex( void );
  261. extern int GetBluePlayerIndex( void );
  262. extern int GetCoopSectionIndex( void );
  263. extern int GetCoopBranchLevelIndex( int nBranch );
  264. extern int GetHighestActiveBranch( void );
  265. extern void AddBranchLevelName( int nBranch, const char *pchName );
  266. extern void MarkMapComplete( const char *pchName );
  267. extern bool IsLevelComplete( int nBranch, int nLevel );
  268. extern bool IsPlayerLevelComplete( int nPlayer, int nBranch, int nLevel );
  269. extern void AddCoopCreditsName( const char *pchName );
  270. bool ScriptSteamShowURL( const char *pURL )
  271. {
  272. #if !defined(NO_STEAM)
  273. if ( steamapicontext && steamapicontext->SteamFriends() &&
  274. steamapicontext->SteamUtils() && steamapicontext->SteamUtils()->IsOverlayEnabled() )
  275. {
  276. steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( pURL );
  277. return true;
  278. }
  279. #endif
  280. return false;
  281. }
  282. void ScriptShowHudMessageAll( const char *pMsg, float flHoldTime )
  283. {
  284. hudtextparms_t tTextParam = {0};
  285. tTextParam.x = -1;
  286. tTextParam.y = -1;
  287. tTextParam.effect = 0;
  288. tTextParam.r1 = 255;
  289. tTextParam.g1 = 255;
  290. tTextParam.b1 = 255;
  291. tTextParam.a1 = 255;
  292. tTextParam.r2 = 255;
  293. tTextParam.g2 = 255;
  294. tTextParam.b2 = 255;
  295. tTextParam.a2 = 255;
  296. tTextParam.fadeinTime = 0;
  297. tTextParam.fadeoutTime = 0;
  298. tTextParam.holdTime = flHoldTime;
  299. tTextParam.fxTime = 0;
  300. tTextParam.channel = 1;
  301. UTIL_HudMessageAll( tTextParam, pMsg );
  302. }
  303. void GivePlayerPortalgun( void )
  304. {
  305. for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
  306. {
  307. CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
  308. if ( pPlayer )
  309. {
  310. pPlayer->GivePlayerPortalGun( false, true );
  311. }
  312. }
  313. }
  314. void UpgradePlayerPortalgun( void )
  315. {
  316. for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
  317. {
  318. CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
  319. if ( pPlayer )
  320. {
  321. CWeaponPortalgun *pPortalGun = static_cast< CWeaponPortalgun* >( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) );
  322. if ( pPortalGun )
  323. {
  324. pPortalGun->SetCanFirePortal1();
  325. pPortalGun->SetCanFirePortal2();
  326. }
  327. else
  328. {
  329. DevMsg( "Portalgun upgrade failed! Player not holding a portalgun.\n");
  330. }
  331. }
  332. }
  333. }
  334. void UpgradePlayerPotatogun( void )
  335. {
  336. for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
  337. {
  338. CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
  339. if ( pPlayer )
  340. {
  341. CWeaponPortalgun *pPortalGun = static_cast< CWeaponPortalgun* >( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) );
  342. if ( pPortalGun )
  343. {
  344. pPortalGun->SetCanFirePortal1();
  345. pPortalGun->SetCanFirePortal2();
  346. pPortalGun->SetPotatosOnPortalgun( true );
  347. }
  348. else
  349. {
  350. DevMsg( "Potatogun upgrade failed! Player not holding a portalgun.\n");
  351. }
  352. }
  353. }
  354. }
  355. HSCRIPT GetPlayer( void )
  356. {
  357. return ToHScript( UTIL_GetLocalPlayer() );
  358. }
  359. void CPortalGameRules::RegisterScriptFunctions( void )
  360. {
  361. ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsMultiplayer, "IsMultiplayer", "Is this a multiplayer game?" );
  362. ScriptRegisterFunction( g_pScriptVM, GetPlayerSilenceDuration, "Time that the specified player has been silent on the mic." );
  363. ScriptRegisterFunction( g_pScriptVM, GetOrangePlayerIndex, "Player index of the orange player." );
  364. ScriptRegisterFunction( g_pScriptVM, GetBluePlayerIndex, "Player index of the blue player." );
  365. ScriptRegisterFunction( g_pScriptVM, GetCoopSectionIndex, "Section that the coop players have selected to load." );
  366. ScriptRegisterFunction( g_pScriptVM, GetCoopBranchLevelIndex, "Given the 'branch' argument, returns the current chosen level." );
  367. ScriptRegisterFunction( g_pScriptVM, GetHighestActiveBranch, "Returns which branches should be available in the hub." );
  368. ScriptRegisterFunction( g_pScriptVM, AddBranchLevelName, "Adds a level to the specified branche's list." );
  369. ScriptRegisterFunction( g_pScriptVM, MarkMapComplete, "Marks a maps a complete for both players." );
  370. ScriptRegisterFunction( g_pScriptVM, IsLevelComplete, "Returns true if the level in the specified branch is completed by either player." );
  371. ScriptRegisterFunction( g_pScriptVM, IsPlayerLevelComplete, "Returns true if the level in the specified branch is completed by a specific player." );
  372. ScriptRegisterFunction( g_pScriptVM, GetPlayer, "Returns the player (SP Only)." );
  373. ScriptRegisterFunction( g_pScriptVM, PrecacheMovie, "Precaches a named movie. Only valid to call within the entity's 'Precache' function called on mapspawn." );
  374. ScriptRegisterFunction( g_pScriptVM, AddCoopCreditsName, "Adds a name to the coop credit's list." );
  375. ScriptRegisterFunction( g_pScriptVM, ScriptSteamShowURL, "Bring up the steam overlay and shows the specified URL. (Full address with protocol type is required, e.g. http://www.steamgames.com/)" );
  376. ScriptRegisterFunction( g_pScriptVM, ScriptShowHudMessageAll, "Show center print text message." );
  377. ScriptRegisterFunction( g_pScriptVM, GivePlayerPortalgun, "Give player the portalgun." );
  378. ScriptRegisterFunction( g_pScriptVM, UpgradePlayerPortalgun, "Give player the portalgun." );
  379. ScriptRegisterFunction( g_pScriptVM, UpgradePlayerPotatogun, "Give player the portalgun." );
  380. ScriptRegisterFunction( g_pScriptVM, TryDLC1InstalledOrCatch, "Tests if the DLC1 is installed for Try/Catch blocks." );
  381. g_pScriptVM->RegisterInstance( &PlayerVoiceListener(), "PlayerVoiceListener" );
  382. }
  383. #endif // !CLIENT_DLL