void CHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event ) { // show event at least for 2 more seconds after it occured const char *name = event->m_Event->GetName(); bool bPlayerHurt = Q_strcmp( "player_hurt", name ) == 0; bool bPlayerKilled = Q_strcmp( "player_death", name ) == 0; bool bRoundStart = Q_strcmp( "round_start", name ) == 0; bool bRoundEnd = Q_strcmp( "round_end", name ) == 0; if ( bPlayerHurt || bPlayerKilled ) { CBaseEntity *victim = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") ); CBaseEntity *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") ); if ( !victim ) return; if ( attacker == victim || attacker == NULL ) { // player killed self or by WORLD StartChaseCameraShot( victim->entindex(), 0, 96, 20, 0, false ); } else // attacker != NULL { // check if we would show it from ineye view bool bInEye = (bPlayerKilled && RandomFloat(0,1) > 0.33) || (bPlayerHurt && RandomFloat(0,1) > 0.66); // if we show ineye view, show it more likely from killer if ( RandomFloat(0,1) > (bInEye?0.3f:0.7f) ) { V_swap( attacker, victim ); } // hurting a victim is shown as chase more often // view from behind over head // lower view point, dramatic // view over shoulder, randomly left or right StartChaseCameraShot( victim->entindex(), attacker->entindex(), 96, -20, (RandomFloat()>0.5)?30:-30, bInEye ); } // shot 2 seconds after death/hurt m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) ); } else if ( bRoundStart || bRoundEnd ) { StartBestFixedCameraShot( false ); } else { DevMsg( "No known TV shot for event %s\n", name ); } }
void CHLTVDirector::StartBestPlayerCameraShot() { float flPlayerRanking[MAX_PLAYERS]; memset( flPlayerRanking, 0, sizeof(flPlayerRanking) ); int firstIndex = FindFirstEvent( m_nBroadcastTick ); int index = firstIndex; float flBestRank = -1.0f; int iBestCamera = -1; int iBestTarget = -1; // sum all ranking values for the cameras while( index != m_EventHistory.InvalidIndex() ) { CHLTVGameEvent &dc = m_EventHistory[index]; if ( dc.m_Tick >= m_nNextShotTick ) break; // search for camera ranking events if ( Q_strcmp( dc.m_Event->GetName(), "hltv_rank_entity") == 0 ) { int index = dc.m_Event->GetInt("index"); if ( index < MAX_PLAYERS ) { flPlayerRanking[index] += dc.m_Event->GetFloat("rank" ); // find best camera if ( flPlayerRanking[index] > flBestRank ) { iBestCamera = index; flBestRank = flPlayerRanking[index]; iBestTarget = dc.m_Event->GetInt("target"); } } } index = m_EventHistory.NextInorder( index ); } if ( iBestCamera != -1 ) { // view over shoulder, randomly left or right StartChaseCameraShot( iBestCamera, iBestTarget, 112.0f, 20, (RandomFloat()>0.5)?20:-20, false ); } else { StartBestFixedCameraShot( true ); } }
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 ); } }