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

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: The Half-Life 2 game rules, such as the relationship tables and ammo
// damage cvars.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "portal_gamerules.h"
#include "ammodef.h"
#include "hl2_shareddefs.h"
#include "portal_shareddefs.h"
#include "weapon_portalgun_shared.h"
#ifndef CLIENT_DLL
#include "player_voice_listener.h"
#endif // CLIENT_DLL
#ifdef CLIENT_DLL
#ifndef NO_STEAM
#include "steam/steam_api.h"
#endif //NO_STEAM
#include "c_user_message_register.h"
#else
#include "player.h"
#include "game.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "portal_player.h"
#include "globalstate.h"
#include "ai_basenpc.h"
#include "portal/weapon_physcannon.h"
#include "props.h" // For props flags used in making the portal weight box
#include "datacache/imdlcache.h" // For precaching box model
#include "vscript_server.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifdef CLIENT_DLL
extern ConVar locator_lerp_rest;
extern ConVar locator_start_at_crosshair;
extern ConVar locator_topdown_style;
extern ConVar locator_background_style;
extern ConVar locator_background_color;
extern ConVar locator_background_thickness_x;
extern ConVar locator_background_thickness_y;
extern ConVar locator_target_offset_x;
extern ConVar locator_target_offset_y;
extern ConVar locator_background_shift_x;
extern ConVar locator_background_shift_y;
extern ConVar locator_background_border_color;
extern ConVar locator_icon_min_size_non_ss;
extern ConVar locator_icon_max_size_non_ss;
#endif // CLIENT_DLL
REGISTER_GAMERULES_CLASS( CPortalGameRules );
BEGIN_NETWORK_TABLE_NOBASE( CPortalGameRules, DT_PortalGameRules )
END_NETWORK_TABLE()
IMPLEMENT_NETWORKCLASS_ALIASED( PortalGameRulesProxy, DT_PortalGameRulesProxy )
LINK_ENTITY_TO_CLASS_ALIASED( portal_gamerules, PortalGameRulesProxy );
#ifdef CLIENT_DLL
void RecvProxy_PortalGameRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
{
CPortalGameRules *pRules = PortalGameRules();
Assert( pRules );
*pOut = pRules;
}
BEGIN_RECV_TABLE( CPortalGameRulesProxy, DT_PortalGameRulesProxy )
RecvPropDataTable( "portal_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_PortalGameRules ), RecvProxy_PortalGameRules )
END_RECV_TABLE()
#else
void* SendProxy_PortalGameRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
{
CPortalGameRules *pRules = PortalGameRules();
Assert( pRules );
pRecipients->SetAllRecipients();
return pRules;
}
BEGIN_SEND_TABLE( CPortalGameRulesProxy, DT_PortalGameRulesProxy )
SendPropDataTable( "portal_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_PortalGameRules ), SendProxy_PortalGameRules )
END_SEND_TABLE()
#endif
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
CPortalGameRules::CPortalGameRules()
{
#ifndef CLIENT_DLL
g_pCVar->FindVar( "sv_maxreplay" )->SetValue( "1.5" );
if ( !GlobalEntity_IsInTable( "player_regenerates_health" ) )
GlobalEntity_Add( MAKE_STRING("player_regenerates_health"), gpGlobals->mapname, GLOBAL_ON );
else
GlobalEntity_SetState( MAKE_STRING("player_regenerates_health"), GLOBAL_ON );
if ( gpGlobals->mapname.ToCStr() && StringHasPrefix( gpGlobals->mapname.ToCStr(), "mp_coop" ) )
{
static ConVarRef flashlightbrightness( "r_flashlightbrightness" );
if ( flashlightbrightness.IsValid() )
{
// All MP maps use this brightness but don't set it explicitly... we need this here for MP maps in commentary mode
flashlightbrightness.SetValue( 0.25f );
}
}
#else
locator_lerp_rest.SetValue( 0.0f );
locator_start_at_crosshair.SetValue( 0 );
locator_topdown_style.SetValue( 0 );
locator_background_style.SetValue( 0 );
locator_background_color.SetValue( "0 0 0 128");
locator_target_offset_x.SetValue( 0 );
locator_target_offset_y.SetValue( 0 );
locator_background_thickness_x.SetValue( 12 );
locator_background_thickness_y.SetValue( 12 );
locator_background_shift_x.SetValue( 0 );
locator_background_shift_y.SetValue( 0 );
locator_background_border_color.SetValue( "32 32 32 64" );
locator_icon_min_size_non_ss.SetValue( 1.5f );
locator_icon_max_size_non_ss.SetValue( 1.75f );
#endif
}
#ifndef CLIENT_DLL
// ------------------------------------------------------------------------------------
// Parse commands coming down from the client
// ------------------------------------------------------------------------------------
bool CPortalGameRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
{
const char *pcmd = args[0];
if ( FStrEq( pcmd, "lobby_select_day" ) )
{
if ( args.ArgC() < 2 )
return true;
//int nDay = atoi( args[1] );
// Msg("Selecting day %d\n", nDay );
return true;
}
return BaseClass::ClientCommand( pEdict, args );
}
// ------------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------------
const char *CPortalGameRules::GetGameDescription( void )
{
#ifdef PORTAL2
return "Portal 2";
#else
return "Portal";
#endif
}
// ------------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------------
bool CPortalGameRules::AllowDamage( CBaseEntity *pVictim, const CTakeDamageInfo &info )
{
return BaseClass::AllowDamage( pVictim, info );
}
bool CPortalGameRules::IsSavingAllowed( void )
{
if ( UTIL_GetLocalPlayerOrListenServerHost()->GetBonusChallenge() > 0 )
{
return false;
}
return true;
}
#else
// ------------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------------
bool CPortalGameRules::IsBonusChallengeTimeBased( void )
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex( 1 );
if ( !pPlayer )
return true;
int iBonusChallenge = pPlayer->GetBonusChallenge();
if ( iBonusChallenge == PORTAL_CHALLENGE_TIME || iBonusChallenge == PORTAL_CHALLENGE_NONE )
return true;
return false;
}
bool CPortalGameRules::IsChallengeMode()
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex( 1 );
if ( pPlayer )
return pPlayer->GetBonusChallenge() != 0;
return false;
}
#endif// !( CLIENT_DLL )
bool CPortalGameRules::ShouldCollide( int collisionGroup0, int collisionGroup1 )
{
if ( collisionGroup0 > collisionGroup1 )
{
// swap so that lowest is always first
V_swap(collisionGroup0,collisionGroup1);
}
// Cubes shouldn't collide with debris but should otherwise act like COLLISION_GROUP_NONE
if( collisionGroup1 == COLLISION_GROUP_WEIGHTED_CUBE && collisionGroup0 == COLLISION_GROUP_DEBRIS )
return false;
if( collisionGroup0 == COLLISION_GROUP_WEIGHTED_CUBE )
collisionGroup0 = COLLISION_GROUP_NONE;
if( collisionGroup1 == COLLISION_GROUP_WEIGHTED_CUBE )
collisionGroup1 = COLLISION_GROUP_NONE;
return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );
}
// ------------------------------------------------------------------------------------ //
// Global functions.
// ------------------------------------------------------------------------------------ //
// shared ammo definition
// JAY: Trying to make a more physical bullet response
#define BULLET_MASS_GRAINS_TO_LB(grains) (0.002285*(grains)/16.0f)
#define BULLET_MASS_GRAINS_TO_KG(grains) lbs2kg(BULLET_MASS_GRAINS_TO_LB(grains))
// exaggerate all of the forces, but use real numbers to keep them consistent
#define BULLET_IMPULSE_EXAGGERATION 3.5
// convert a velocity in ft/sec and a mass in grains to an impulse in kg in/s
#define BULLET_IMPULSE(grains, ftpersec) ((ftpersec)*12*BULLET_MASS_GRAINS_TO_KG(grains)*BULLET_IMPULSE_EXAGGERATION)
CAmmoDef *GetAmmoDef()
{
static CAmmoDef def;
static bool bInitted = false;
if ( !bInitted )
{
bInitted = true;
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 );
def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 );
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 );
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 );
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 );
def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_crossbow", "sk_npc_dmg_crossbow", "sk_max_crossbow", BULLET_IMPULSE(800, 8000), 0 );
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 );
def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 );
def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 );
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 );
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 );
def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0);
def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 );
def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 );
def.AddAmmoType("Battery", DMG_CLUB, TRACER_NONE, NULL, NULL, NULL, 0, 0 );
#ifndef PORTAL2
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
#endif
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
def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 );
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
#ifndef PORTAL2
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 );
#endif
def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, "sk_max_ar2_altfire", 0, 0 );
def.AddAmmoType("PortalTurretBullet", DMG_BULLET, TRACER_LINE_AND_WHIZ, 3, 3, 150, BULLET_IMPULSE(200, 1225), 0 );
}
return &def;
}
///////////////////////////////////////////////////////////////////////
// Portal singleplayer specific global vscript functions
///////////////////////////////////////////////////////////////////////
#if !defined ( CLIENT_DLL )
static bool ScriptIsMultiplayer( void )
{
return false;//g_pGameRules->IsMultiplayer();
}
static bool TryDLC1InstalledOrCatch( void )
{
return true;
}
extern float GetPlayerSilenceDuration( int nPlayer );
extern int GetOrangePlayerIndex( void );
extern int GetBluePlayerIndex( void );
extern int GetCoopSectionIndex( void );
extern int GetCoopBranchLevelIndex( int nBranch );
extern int GetHighestActiveBranch( void );
extern void AddBranchLevelName( int nBranch, const char *pchName );
extern void MarkMapComplete( const char *pchName );
extern bool IsLevelComplete( int nBranch, int nLevel );
extern bool IsPlayerLevelComplete( int nPlayer, int nBranch, int nLevel );
extern void AddCoopCreditsName( const char *pchName );
bool ScriptSteamShowURL( const char *pURL )
{
#if !defined(NO_STEAM)
if ( steamapicontext && steamapicontext->SteamFriends() &&
steamapicontext->SteamUtils() && steamapicontext->SteamUtils()->IsOverlayEnabled() )
{
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( pURL );
return true;
}
#endif
return false;
}
void ScriptShowHudMessageAll( const char *pMsg, float flHoldTime )
{
hudtextparms_t tTextParam = {0};
tTextParam.x = -1;
tTextParam.y = -1;
tTextParam.effect = 0;
tTextParam.r1 = 255;
tTextParam.g1 = 255;
tTextParam.b1 = 255;
tTextParam.a1 = 255;
tTextParam.r2 = 255;
tTextParam.g2 = 255;
tTextParam.b2 = 255;
tTextParam.a2 = 255;
tTextParam.fadeinTime = 0;
tTextParam.fadeoutTime = 0;
tTextParam.holdTime = flHoldTime;
tTextParam.fxTime = 0;
tTextParam.channel = 1;
UTIL_HudMessageAll( tTextParam, pMsg );
}
void GivePlayerPortalgun( void )
{
for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
{
CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer )
{
pPlayer->GivePlayerPortalGun( false, true );
}
}
}
void UpgradePlayerPortalgun( void )
{
for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
{
CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer )
{
CWeaponPortalgun *pPortalGun = static_cast< CWeaponPortalgun* >( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) );
if ( pPortalGun )
{
pPortalGun->SetCanFirePortal1();
pPortalGun->SetCanFirePortal2();
}
else
{
DevMsg( "Portalgun upgrade failed! Player not holding a portalgun.\n");
}
}
}
}
void UpgradePlayerPotatogun( void )
{
for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
{
CPortal_Player *pPlayer = ToPortalPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer )
{
CWeaponPortalgun *pPortalGun = static_cast< CWeaponPortalgun* >( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) );
if ( pPortalGun )
{
pPortalGun->SetCanFirePortal1();
pPortalGun->SetCanFirePortal2();
pPortalGun->SetPotatosOnPortalgun( true );
}
else
{
DevMsg( "Potatogun upgrade failed! Player not holding a portalgun.\n");
}
}
}
}
HSCRIPT GetPlayer( void )
{
return ToHScript( UTIL_GetLocalPlayer() );
}
void CPortalGameRules::RegisterScriptFunctions( void )
{
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsMultiplayer, "IsMultiplayer", "Is this a multiplayer game?" );
ScriptRegisterFunction( g_pScriptVM, GetPlayerSilenceDuration, "Time that the specified player has been silent on the mic." );
ScriptRegisterFunction( g_pScriptVM, GetOrangePlayerIndex, "Player index of the orange player." );
ScriptRegisterFunction( g_pScriptVM, GetBluePlayerIndex, "Player index of the blue player." );
ScriptRegisterFunction( g_pScriptVM, GetCoopSectionIndex, "Section that the coop players have selected to load." );
ScriptRegisterFunction( g_pScriptVM, GetCoopBranchLevelIndex, "Given the 'branch' argument, returns the current chosen level." );
ScriptRegisterFunction( g_pScriptVM, GetHighestActiveBranch, "Returns which branches should be available in the hub." );
ScriptRegisterFunction( g_pScriptVM, AddBranchLevelName, "Adds a level to the specified branche's list." );
ScriptRegisterFunction( g_pScriptVM, MarkMapComplete, "Marks a maps a complete for both players." );
ScriptRegisterFunction( g_pScriptVM, IsLevelComplete, "Returns true if the level in the specified branch is completed by either player." );
ScriptRegisterFunction( g_pScriptVM, IsPlayerLevelComplete, "Returns true if the level in the specified branch is completed by a specific player." );
ScriptRegisterFunction( g_pScriptVM, GetPlayer, "Returns the player (SP Only)." );
ScriptRegisterFunction( g_pScriptVM, PrecacheMovie, "Precaches a named movie. Only valid to call within the entity's 'Precache' function called on mapspawn." );
ScriptRegisterFunction( g_pScriptVM, AddCoopCreditsName, "Adds a name to the coop credit's list." );
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/)" );
ScriptRegisterFunction( g_pScriptVM, ScriptShowHudMessageAll, "Show center print text message." );
ScriptRegisterFunction( g_pScriptVM, GivePlayerPortalgun, "Give player the portalgun." );
ScriptRegisterFunction( g_pScriptVM, UpgradePlayerPortalgun, "Give player the portalgun." );
ScriptRegisterFunction( g_pScriptVM, UpgradePlayerPotatogun, "Give player the portalgun." );
ScriptRegisterFunction( g_pScriptVM, TryDLC1InstalledOrCatch, "Tests if the DLC1 is installed for Try/Catch blocks." );
g_pScriptVM->RegisterInstance( &PlayerVoiceListener(), "PlayerVoiceListener" );
}
#endif // !CLIENT_DLL