|
|
//========= 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
|