mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-11 19:29:08 +00:00
1
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
//========= 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;
|
||||
}
|
||||
Reference in New Issue
Block a user