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.
556 lines
13 KiB
556 lines
13 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//===========================================================================// |
|
#include "cbase.h" |
|
#include "hud.h" |
|
#include "clientmode_dod.h" |
|
#include "cdll_client_int.h" |
|
#include "iinput.h" |
|
#include "vgui/ISurface.h" |
|
#include "vgui/IPanel.h" |
|
#include <vgui_controls/AnimationController.h> |
|
#include "ivmodemanager.h" |
|
#include "buymenu.h" |
|
#include "filesystem.h" |
|
#include "vgui/IVGui.h" |
|
#include "hud_basechat.h" |
|
#include "view_shared.h" |
|
#include "view.h" |
|
#include "ivrenderview.h" |
|
#include "model_types.h" |
|
#include "iefx.h" |
|
#include "dlight.h" |
|
#include <imapoverview.h> |
|
#include "c_playerresource.h" |
|
#include <KeyValues.h> |
|
#include "text_message.h" |
|
#include "panelmetaclassmgr.h" |
|
#include "dod_shareddefs.h" |
|
#include "c_dod_player.h" |
|
#include "physpropclientside.h" |
|
#include "engine/IEngineSound.h" |
|
#include "bitbuf.h" |
|
#include "usermessages.h" |
|
#include "prediction.h" |
|
#include "vgui/ILocalize.h" |
|
#include "dod_hud_freezepanel.h" |
|
#include "dod_hud_chat.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
class CHudChat; |
|
|
|
ConVar default_fov( "default_fov", "90", FCVAR_CHEAT ); |
|
|
|
ConVar dod_playwinmusic( "dod_playwinmusic", "1", FCVAR_ARCHIVE ); |
|
|
|
IClientMode *g_pClientMode = NULL; |
|
|
|
void MsgFunc_KillCam(bf_read &msg) |
|
{ |
|
C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
if ( !pPlayer ) |
|
return; |
|
|
|
int newMode = msg.ReadByte(); |
|
|
|
if ( newMode != g_nKillCamMode ) |
|
{ |
|
#if !defined( NO_ENTITY_PREDICTION ) |
|
if ( g_nKillCamMode == OBS_MODE_NONE ) |
|
{ |
|
// kill cam is switch on, turn off prediction |
|
g_bForceCLPredictOff = true; |
|
} |
|
else if ( newMode == OBS_MODE_NONE ) |
|
{ |
|
// kill cam is switched off, restore old prediction setting is we switch back to normal mode |
|
g_bForceCLPredictOff = false; |
|
} |
|
#endif |
|
g_nKillCamMode = newMode; |
|
} |
|
|
|
g_nKillCamTarget1 = msg.ReadByte(); |
|
g_nKillCamTarget2 = msg.ReadByte(); |
|
} |
|
|
|
// --------------------------------------------------------------------------------- // |
|
// CDODModeManager. |
|
// --------------------------------------------------------------------------------- // |
|
|
|
class CDODModeManager : public IVModeManager |
|
{ |
|
public: |
|
virtual void Init(); |
|
virtual void SwitchMode( bool commander, bool force ) {} |
|
virtual void LevelInit( const char *newmap ); |
|
virtual void LevelShutdown( void ); |
|
virtual void ActivateMouse( bool isactive ) {} |
|
}; |
|
|
|
static CDODModeManager g_ModeManager; |
|
IVModeManager *modemanager = ( IVModeManager * )&g_ModeManager; |
|
|
|
// --------------------------------------------------------------------------------- // |
|
// CDODModeManager implementation. |
|
// --------------------------------------------------------------------------------- // |
|
|
|
#define SCREEN_FILE "scripts/vgui_screens.txt" |
|
|
|
void CDODModeManager::Init() |
|
{ |
|
g_pClientMode = GetClientModeNormal(); |
|
|
|
PanelMetaClassMgr()->LoadMetaClassDefinitionFile( SCREEN_FILE ); |
|
} |
|
|
|
void CDODModeManager::LevelInit( const char *newmap ) |
|
{ |
|
g_pClientMode->LevelInit( newmap ); |
|
|
|
#if !defined( NO_ENTITY_PREDICTION ) |
|
if ( g_nKillCamMode > OBS_MODE_NONE ) |
|
{ |
|
g_bForceCLPredictOff = false; |
|
} |
|
#endif |
|
|
|
g_nKillCamMode = OBS_MODE_NONE; |
|
g_nKillCamTarget1 = 0; |
|
g_nKillCamTarget2 = 0; |
|
} |
|
|
|
void CDODModeManager::LevelShutdown( void ) |
|
{ |
|
g_pClientMode->LevelShutdown(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
ClientModeDODNormal::ClientModeDODNormal() |
|
{ |
|
m_pFreezePanel = NULL; |
|
} |
|
|
|
void ClientModeDODNormal::Init() |
|
{ |
|
BaseClass::Init(); |
|
|
|
ListenForGameEvent( "dod_round_start" ); |
|
ListenForGameEvent( "dod_broadcast_audio" ); |
|
ListenForGameEvent( "player_team" ); |
|
ListenForGameEvent( "dod_bomb_planted" ); |
|
ListenForGameEvent( "dod_bomb_defused" ); |
|
ListenForGameEvent( "dod_timer_flash" ); |
|
|
|
usermessages->HookMessage( "KillCam", MsgFunc_KillCam ); |
|
|
|
m_szLastRadioSound[0] = '\0'; |
|
|
|
m_pFreezePanel = ( CDODFreezePanel * )GET_HUDELEMENT( CDODFreezePanel ); |
|
Assert( m_pFreezePanel ); |
|
} |
|
void ClientModeDODNormal::InitViewport() |
|
{ |
|
m_pViewport = new DODViewport(); |
|
m_pViewport->Start( gameuifuncs, gameeventmanager ); |
|
} |
|
|
|
ClientModeDODNormal g_ClientModeNormal; |
|
|
|
IClientMode *GetClientModeNormal() |
|
{ |
|
return &g_ClientModeNormal; |
|
} |
|
|
|
|
|
ClientModeDODNormal* GetClientModeDODNormal() |
|
{ |
|
Assert( dynamic_cast< ClientModeDODNormal* >( GetClientModeNormal() ) ); |
|
|
|
return static_cast< ClientModeDODNormal* >( GetClientModeNormal() ); |
|
} |
|
|
|
ConVar r_viewmodelfov( "r_viewmodelfov", "0", FCVAR_CHEAT ); |
|
|
|
float ClientModeDODNormal::GetViewModelFOV( void ) |
|
{ |
|
float flFov = 90.0f; |
|
|
|
if( r_viewmodelfov.GetFloat() > 0 ) |
|
return r_viewmodelfov.GetFloat(); |
|
|
|
C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
if( !pPlayer ) |
|
return flFov; |
|
|
|
CWeaponDODBase *pWpn = pPlayer->GetActiveDODWeapon(); |
|
|
|
if( pWpn ) |
|
{ |
|
flFov = pWpn->GetDODWpnData().m_flViewModelFOV; |
|
} |
|
|
|
return flFov; |
|
} |
|
|
|
int ClientModeDODNormal::GetDeathMessageStartHeight( void ) |
|
{ |
|
return m_pViewport->GetDeathMessageStartHeight(); |
|
} |
|
|
|
void ClientModeDODNormal::FireGameEvent( IGameEvent * event) |
|
{ |
|
const char *eventname = event->GetName(); |
|
|
|
if ( !eventname || !eventname[0] ) |
|
return; |
|
|
|
if ( Q_strcmp( "dod_round_start", eventname ) == 0 ) |
|
{ |
|
// Just tell engine to clear decals |
|
engine->ClientCmd( "r_cleardecals\n" ); |
|
|
|
// recreate all client side physics props |
|
// check for physenv, because we sometimes crash on changelevel |
|
// if we get this message before fully connecting |
|
if ( physenv ) |
|
{ |
|
C_PhysPropClientside::RecreateAll(); |
|
} |
|
} |
|
else if( Q_strcmp( "dod_broadcast_audio", eventname ) == 0 ) |
|
{ |
|
CLocalPlayerFilter filter; |
|
const char *pszSoundName = event->GetString("sound"); |
|
|
|
if ( dod_playwinmusic.GetBool() == false ) |
|
{ |
|
if ( FStrEq( pszSoundName, "Game.USWin" ) || FStrEq( pszSoundName, "Game.GermanWin" ) ) |
|
{ |
|
return; |
|
} |
|
} |
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, pszSoundName ); |
|
} |
|
else if ( Q_strcmp( "dod_bomb_planted", eventname ) == 0 ) |
|
{ |
|
int defendingTeam = event->GetInt( "team" ); |
|
|
|
C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
const char *pszSound = ""; |
|
const char *pszMessage = ""; |
|
|
|
int localTeam = pLocalPlayer->GetTeamNumber(); |
|
|
|
const char *pPlanterName = NULL; |
|
|
|
int iPlanterIndex = 0; |
|
|
|
if ( defendingTeam == localTeam ) |
|
{ |
|
// play defend sound |
|
switch( localTeam ) |
|
{ |
|
case TEAM_ALLIES: |
|
{ |
|
pszSound = "Voice.US_C4EnemyPlanted"; |
|
pszMessage = "#dod_bomb_us_enemy_planted"; |
|
} |
|
break; |
|
case TEAM_AXIS: |
|
{ |
|
pszSound = "Voice.German_C4EnemyPlanted"; |
|
pszMessage = "#dod_bomb_ger_enemy_planted"; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
// play planting sound |
|
switch( localTeam ) |
|
{ |
|
case TEAM_ALLIES: |
|
{ |
|
pszSound = "Voice.US_C4TeamPlanted"; |
|
pszMessage = "#dod_bomb_us_team_planted"; |
|
} |
|
break; |
|
case TEAM_AXIS: |
|
{ |
|
pszSound = "Voice.German_C4TeamPlanted"; |
|
pszMessage = "#dod_bomb_ger_team_planted"; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
// Only show the planter name if its a team plant, not enemy plant |
|
iPlanterIndex = engine->GetPlayerForUserID( event->GetInt("userid") ); |
|
pPlanterName = g_PR->GetPlayerName( iPlanterIndex ); |
|
} |
|
|
|
RadioMessage( pszSound, pszMessage, pPlanterName, iPlanterIndex ); |
|
} |
|
else if ( Q_strcmp( "dod_bomb_defused", eventname ) == 0 ) |
|
{ |
|
int defusingTeam = event->GetInt( "team" ); |
|
|
|
C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
const char *pszSound = ""; |
|
const char *pszMessage = ""; |
|
|
|
int localTeam = pLocalPlayer->GetTeamNumber(); |
|
|
|
if ( defusingTeam == localTeam ) |
|
{ |
|
// play defused sound |
|
switch( localTeam ) |
|
{ |
|
case TEAM_ALLIES: |
|
{ |
|
pszSound = "Voice.US_C4Defused"; |
|
pszMessage = "#dod_bomb_us_defused"; |
|
} |
|
break; |
|
case TEAM_AXIS: |
|
{ |
|
pszSound = "Voice.German_C4Defused"; |
|
pszMessage = "#dod_bomb_ger_defused"; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
int iDefuser = engine->GetPlayerForUserID( event->GetInt("userid") ); |
|
const char *pDefuserName = g_PR->GetPlayerName( iDefuser ); |
|
|
|
RadioMessage( pszSound, pszMessage, pDefuserName, iDefuser ); |
|
} |
|
} |
|
else if ( Q_strcmp( "player_team", eventname ) == 0 ) |
|
{ |
|
C_BasePlayer *pPlayer = USERID2PLAYER( event->GetInt("userid") ); |
|
|
|
if ( !pPlayer ) |
|
return; |
|
|
|
bool bDisconnected = event->GetBool("disconnect"); |
|
|
|
if ( bDisconnected ) |
|
return; |
|
|
|
int team = event->GetInt( "team" ); |
|
|
|
if ( pPlayer->IsLocalPlayer() ) |
|
{ |
|
// that's me |
|
pPlayer->TeamChange( team ); |
|
} |
|
|
|
CBaseHudChat *hudChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat ); |
|
|
|
if ( !hudChat ) |
|
return; |
|
|
|
const char *pTemplate = NULL; |
|
|
|
if ( team == TEAM_ALLIES ) |
|
{ |
|
pTemplate = "#game_joined_allies"; |
|
} |
|
else if ( team == TEAM_AXIS ) |
|
{ |
|
pTemplate = "#game_joined_axis"; |
|
} |
|
else |
|
{ |
|
pTemplate = "#game_joined_spectators"; |
|
} |
|
|
|
wchar_t szPlayerName[MAX_PLAYER_NAME_LENGTH]; |
|
g_pVGuiLocalize->ConvertANSIToUnicode( pPlayer->GetPlayerName(), szPlayerName, sizeof(szPlayerName) ); |
|
|
|
wchar_t wszPrint[128]; |
|
char szPrint[128]; |
|
|
|
g_pVGuiLocalize->ConstructString( wszPrint, sizeof(wszPrint), g_pVGuiLocalize->Find(pTemplate), 1, szPlayerName ); |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( wszPrint, szPrint, sizeof(szPrint) ); |
|
|
|
hudChat->Printf( CHAT_FILTER_TEAMCHANGE, "%s",szPrint ); |
|
} |
|
else if ( Q_strcmp( "dod_timer_flash", eventname ) == 0 ) |
|
{ |
|
C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
const char *pszSound = ""; |
|
const char *pszMessage = ""; |
|
|
|
int localTeam = pLocalPlayer->GetTeamNumber(); |
|
|
|
int iTimeRemaining = event->GetInt( "time_remaining", 0 ); |
|
|
|
switch( iTimeRemaining ) |
|
{ |
|
case 60: |
|
switch( localTeam ) |
|
{ |
|
case TEAM_ALLIES: |
|
{ |
|
pszSound = "Voice.US_OneMinute"; |
|
pszMessage = "#dod_time_remaining_us_1_min"; |
|
} |
|
break; |
|
case TEAM_AXIS: |
|
{ |
|
pszSound = "Voice.German_OneMinute"; |
|
pszMessage = "#dod_time_remaining_ger_1_min"; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
break; |
|
case 120: |
|
switch( localTeam ) |
|
{ |
|
case TEAM_ALLIES: |
|
{ |
|
pszSound = "Voice.US_TwoMinute"; |
|
pszMessage = "#dod_time_remaining_us_2_min"; |
|
} |
|
break; |
|
case TEAM_AXIS: |
|
{ |
|
pszSound = "Voice.German_TwoMinute"; |
|
pszMessage = "#dod_time_remaining_ger_2_min"; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
RadioMessage( pszSound, pszMessage ); |
|
} |
|
else |
|
BaseClass::FireGameEvent( event ); |
|
} |
|
|
|
|
|
void ClientModeDODNormal::PostRenderVGui() |
|
{ |
|
} |
|
|
|
bool ClientModeDODNormal::ShouldDrawViewModel() |
|
{ |
|
C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
|
|
CWeaponDODBase *pWpn = pPlayer->GetActiveDODWeapon(); |
|
|
|
if( pWpn && pWpn->ShouldDrawViewModel() == false ) |
|
{ |
|
return false; |
|
} |
|
|
|
return BaseClass::ShouldDrawViewModel(); |
|
} |
|
|
|
void ClientModeDODNormal::RadioMessage( const char *pszSoundName, const char *pszSubtitle, const char *pszSender /* = NULL */, int iSenderIndex /* = 0 */ ) |
|
{ |
|
C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
if ( !pLocalPlayer ) |
|
{ |
|
return; |
|
} |
|
|
|
int color = COLOR_PLAYERNAME; |
|
|
|
// stop the last played radio message |
|
if ( Q_strlen( m_szLastRadioSound ) > 0 ) |
|
{ |
|
C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); |
|
if ( pLocalPlayer ) |
|
{ |
|
pLocalPlayer->StopSound( m_szLastRadioSound ); |
|
} |
|
} |
|
|
|
Q_strncpy( m_szLastRadioSound, pszSoundName, sizeof(m_szLastRadioSound) ); |
|
|
|
// Play the radio alert |
|
char szCmd[128]; |
|
Q_snprintf( szCmd, sizeof(szCmd), "playgamesound %s", pszSoundName ); |
|
|
|
engine->ClientCmd( szCmd ); |
|
|
|
// Print a message to chat |
|
wchar_t wszPrint[128]; |
|
char szPrint[128]; |
|
|
|
g_pVGuiLocalize->ConstructString( wszPrint, sizeof(wszPrint), g_pVGuiLocalize->Find(pszSubtitle), 0 ); |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( wszPrint, szPrint, sizeof(szPrint) ); |
|
|
|
CBaseHudChat *hudChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat ); |
|
|
|
if ( !hudChat ) |
|
return; |
|
|
|
wchar_t *pwLoc = g_pVGuiLocalize->Find( "#dod_radio_prefix" ); |
|
char szPrefix[16]; |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( pwLoc, szPrefix, sizeof(szPrefix) ); |
|
|
|
pwLoc = g_pVGuiLocalize->Find( pszSubtitle ); |
|
char szSuffix[512]; |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( pwLoc, szSuffix, sizeof(szSuffix) ); |
|
|
|
if ( pszSender ) |
|
{ |
|
hudChat->ChatPrintf( iSenderIndex, CHAT_FILTER_NONE, "%c%s %s %c: %s", COLOR_PLAYERNAME, szPrefix, g_PR->GetPlayerName( iSenderIndex ), COLOR_NORMAL, szSuffix ); |
|
} |
|
else |
|
{ |
|
hudChat->Printf( CHAT_FILTER_NONE, "%c%s %c: %s", color, szPrefix, COLOR_NORMAL, szSuffix ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: See if hud elements want key input. Return 0 if the key is swallowed |
|
//----------------------------------------------------------------------------- |
|
int ClientModeDODNormal::HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) |
|
{ |
|
if ( m_pFreezePanel ) |
|
{ |
|
m_pFreezePanel->HudElementKeyInput( down, keynum, pszCurrentBinding ); |
|
} |
|
|
|
return BaseClass::HudElementKeyInput( down, keynum, pszCurrentBinding ); |
|
}
|
|
|