|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "hltvdirector.h"
#include "team_control_point.h"
CBaseEntity* GetCapturePointByIndex( int iCaptureIndex ) { CTeamControlPoint *pTeamControlPoint = (CTeamControlPoint *)gEntList.FindEntityByClassname( NULL, "team_control_point" );
while ( pTeamControlPoint ) { if ( pTeamControlPoint->GetPointIndex() == iCaptureIndex ) { return pTeamControlPoint; }
pTeamControlPoint = (CTeamControlPoint *)gEntList.FindEntityByClassname( pTeamControlPoint, "team_control_point" ); }
return NULL; }
class CTFHLTVDirector : public CHLTVDirector { public: DECLARE_CLASS( CTFHLTVDirector, CHLTVDirector );
const char** GetModEvents(); void SetHLTVServer( IHLTVServer *hltv ); void CreateShotFromEvent( CHLTVGameEvent *event );
virtual char *GetFixedCameraEntityName( void ) { return "info_observer_point"; } };
void CTFHLTVDirector::SetHLTVServer( IHLTVServer *hltv ) { BaseClass::SetHLTVServer( hltv );
if ( m_pHLTVServer ) { // mod specific events the director uses to find interesting shots
ListenForGameEvent( "teamplay_point_captured" ); ListenForGameEvent( "teamplay_capture_blocked" ); ListenForGameEvent( "teamplay_point_startcapture" ); ListenForGameEvent( "teamplay_flag_event" ); ListenForGameEvent( "ctf_flag_captured" ); } }
void CTFHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event ) { // show event at least for 2 more seconds after it occured
const char *name = event->m_Event->GetName();
int thera = RandomFloat()>0.5?20:-20;
if ( !Q_strcmp( "teamplay_point_startcapture", name ) || !Q_strcmp( "teamplay_point_captured", name ) || !Q_strcmp( "teamplay_capture_blocked", name ) ) { CBaseEntity *pCapturePoint = GetCapturePointByIndex( event->m_Event->GetInt( "cp" ) );
int iCameraIndex = -1; float flClosest = 99999.9f; if ( pCapturePoint ) { // Does it have an associated viewpoint?
for ( int i = 0; i<m_nNumFixedCameras; i++ ) { CBaseEntity *pCamera = m_pFixedCameras[ i ]; if ( pCamera ) { byte pvs[MAX_MAP_CLUSTERS/8]; int clusterIndex = engine->GetClusterForOrigin( pCamera->GetAbsOrigin() ); engine->GetPVSForCluster( clusterIndex, sizeof(pvs), pvs ); bool bCameraInPVS = engine->CheckOriginInPVS( pCapturePoint->GetAbsOrigin(), pvs, sizeof( pvs ) );
if ( bCameraInPVS == true ) { float flDistance = (pCapturePoint->GetAbsOrigin() - pCamera->GetAbsOrigin()).Length(); if ( flDistance <= flClosest ) { iCameraIndex = i; flClosest = flDistance; } } } } }
CBasePlayer *pPlayer = NULL;
if ( !Q_strcmp( "teamplay_point_captured", name ) ) { const char *pszCappers = event->m_Event->GetString("cappers"); int nLength = Q_strlen(pszCappers);
if ( nLength > 0 ) { int iRandomCapper = pszCappers[ RandomInt(0,nLength-1) ]; pPlayer = UTIL_PlayerByIndex( iRandomCapper ); } } else if ( !Q_strcmp( "teamplay_capture_blocked", name ) ) { int iBlocker = event->m_Event->GetInt("blocker"); pPlayer = UTIL_PlayerByIndex( iBlocker ); }
if ( pPlayer ) { if ( iCameraIndex >= 0 && RandomFloat() > 0.66f ) { StartFixedCameraShot( iCameraIndex, pPlayer->entindex() ); } else if ( pCapturePoint ) { StartChaseCameraShot( pPlayer->entindex(), pCapturePoint->entindex(), 96, 20, thera, false ); } else { StartChaseCameraShot( pPlayer->entindex(), 0, 96, 20, 0, false ); } } else if ( iCameraIndex >= 0 && pCapturePoint ) { // no player known for this event
StartFixedCameraShot( iCameraIndex, pCapturePoint->entindex() ); }
// shot 2 seconds after event
m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(1.0)) ); } else if ( !Q_strcmp( "object_destroyed", name ) ) { CBasePlayer *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") ); if ( attacker ) { int iObjectIndex = event->m_Event->GetInt("index"); StartChaseCameraShot( attacker->entindex(), iObjectIndex, 96, 20, thera, false ); } } else if ( !Q_strcmp( "ctf_flag_captured", name ) ) { CBasePlayer *capper = UTIL_PlayerByUserId( event->m_Event->GetInt("capper") ); if ( capper ) { StartChaseCameraShot( capper->entindex(), 0, 96, 20, 0, false ); } } else if ( !Q_strcmp( "teamplay_flag_event", name ) ) { StartChaseCameraShot( event->m_Event->GetInt("player"), 0, 96, 20, 0, false ); } else {
// let baseclass create a shot
BaseClass::CreateShotFromEvent( event ); } }
const char** CTFHLTVDirector::GetModEvents() { // game events relayed to spectator clients
static const char *s_modevents[] = { "game_newmap", "hltv_status", "hltv_chat", "player_connect", "player_disconnect", "player_changeclass", "player_team", "player_info", "player_death", "player_chat", "player_spawn", "round_start", "round_end", "server_cvar", "server_spawn", // additional TF events:
"controlpoint_starttouch", "controlpoint_endtouch", "ctf_flag_captured", "teamplay_broadcast_audio", "teamplay_capture_blocked", "teamplay_flag_event", "teamplay_game_over", "teamplay_point_captured", "teamplay_round_stalemate", "teamplay_round_start", "teamplay_round_win", "teamplay_timer_time_added", "teamplay_update_timer", "teamplay_win_panel", "training_complete", "tf_game_over", "object_destroyed", NULL };
return s_modevents; }
static CTFHLTVDirector s_HLTVDirector; // singleton
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHLTVDirector, IHLTVDirector, INTERFACEVERSION_HLTVDIRECTOR, s_HLTVDirector );
CHLTVDirector* HLTVDirector() { return &s_HLTVDirector; }
IGameSystem* HLTVDirectorSystem() { return &s_HLTVDirector; }
|