Example #1
0
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 );
	}
}
Example #2
0
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 );
	}
}
Example #3
0
void CHLTVDirector::StartRandomShot() 
{
	int toTick = m_nBroadcastTick + TIME_TO_TICKS ( DEF_SHOT_LENGTH );
	m_nNextShotTick = MIN( m_nNextShotTick, toTick );

	if ( RandomFloat(0,1) < 0.25 && tv_allow_static_shots.GetBool() )
	{
		// create a static shot from a level camera
		StartBestFixedCameraShot( false );
	}
	else
	{
		// follow a player
		StartBestPlayerCameraShot();
	}
}
Example #4
0
void CHLTVDirector::StartDelayMessage()
{
	if ( m_nNextShotTick > gpGlobals->tickcount )
		return;

	// check the next 8 seconds for interrupts/important events
	m_nNextShotTick = gpGlobals->tickcount + TIME_TO_TICKS( DEF_SHOT_LENGTH );

	// game hasn't started yet, we are still in the broadcast delay hole
	IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_message", true );

	if ( msg )
	{
		msg->SetString("text", "Please wait for broadcast to start ..." );

		// send spectators the HLTV director command as a game event
		m_pHLTVServer->BroadcastEvent( msg );
		gameeventmanager->FreeEvent( msg );
	}

	StartBestFixedCameraShot( true );
}
Example #5
0
void CHLTVDirector::StartNewShot()
{
	// we can remove all events the
	int smallestTick = MAX(0, gpGlobals->tickcount - TIME_TO_TICKS(HLTV_MAX_DELAY) );
    RemoveEventsFromHistory( smallestTick );

	if ( m_iCameraMan > 0 )
	{
		// we already have an active camera man,
		// wait until he releases the "record" lock
		FinishCameraManShot();
		return;	
	}

	if ( StartCameraManShot() )
	{
		// now we have an active camera man
		return;
	} 

    // ok, no camera man active, now check how much time
	// we have for the next shot, if the time diff to the next
	// important event we have to switch to is too short (<2sec)
	// just extent the current shot and don't start a new one

	// check the next 8 seconds for interrupts/important events
	m_nNextShotTick = m_nBroadcastTick + TIME_TO_TICKS( MAX_SHOT_LENGTH );

	if ( m_nBroadcastTick <= 0 )
	{
		// game hasn't started yet, we are still in the broadcast delay hole
		IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_message", true );

		if ( msg )
		{
			msg->SetString("text", "Please wait for broadcast to start ..." );
			
			// send spectators the HLTV director command as a game event
			m_pHLTVServer->BroadcastEvent( msg );
			gameeventmanager->FreeEvent( msg );
		}

		StartBestFixedCameraShot( true );
		return;
	}

	int index = FindFirstEvent( m_nBroadcastTick );

	while( index != m_EventHistory.InvalidIndex() )
	{
		CGameEvent &dc = m_EventHistory[index];

		if ( dc.m_Tick >= m_nNextShotTick )
			break; // we have searched enough

		// a camera man is always interrupting auto director
		if ( Q_strcmp( dc.m_Event->GetName(), "hltv_cameraman") == 0 )
		{
			if ( dc.m_Event->GetInt("index") > 0 )
			{
				// stop the next cut when this cameraman starts recording
				m_nNextShotTick = dc.m_Tick;
				break;
			}
		}

		index = m_EventHistory.NextInorder( index );
	} 

	float flDuration = TICKS_TO_TIME(m_nNextShotTick - m_nBroadcastTick);

	if ( flDuration < MIN_SHOT_LENGTH )
		return;	// not enough time for a new shot

	// find the most intesting game event for next shot
	CGameEvent *dc = FindBestGameEvent();

	if ( dc )
	{
		// show the game event
		CreateShotFromEvent( dc );
	}
	else
	{
		// no interesting events found, start random shot
		StartRandomShot();
	}
}
Example #6
0
void CHLTVDirector::CreateShotFromEvent( CGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	IGameEvent *shot = NULL;

	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
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", 0 );
			shot->SetInt( "theta", 0 );	// view from behind over head
			shot->SetInt( "phi", 20 );	// from above
			shot->SetFloat( "distance", 96.0f );
		}
		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)  )
			{
				swap( attacker, victim );
			}
						
			// hurting a victim is shown as chase more often
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", attacker->entindex() );

			// view from behind over head
			shot->SetInt( "phi", -20 ); // lower view point, dramatic
			shot->SetFloat( "distance", 96.0f );
			shot->SetInt( "ineye", bInEye?1:0 );
							
			// view over shoulder, randomly left or right
			if ( RandomFloat(0,1) > 0.5  )
			{
				shot->SetInt( "theta", 30 ); // swing left
			}
			else
			{
				shot->SetInt( "theta", -30 ); // swing right
			}
			
		}
				
		// shot 2 seconds after death/hurt
		m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = victim->entindex();
	}
	else if ( bRoundStart || bRoundEnd )
	{
		StartBestFixedCameraShot( false );
	}
	else
	{
		DevMsg( "No known TV shot for event %s\n", name );
	}


	if ( shot )
	{
		m_pHLTVServer->BroadcastEvent( shot );
		gameeventmanager->FreeEvent( shot );
	}
}
Example #7
0
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() )
	{
		CGameEvent &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 )
	{
		IGameEvent *shot = gameeventmanager->CreateEvent( "hltv_chase", true );

		if ( shot )
		{
			shot->SetInt("target1", iBestCamera );
			shot->SetInt("target2", iBestTarget );
			shot->SetInt("distance", 112 );
			shot->SetInt("phi", 20 );

			// view over shoulder, randomly left or right
			if ( RandomFloat(0,1) > 0.5  )
			{
				shot->SetInt( "theta", 20 ); // swing left
			}
			else
			{
				shot->SetInt( "theta", -20 ); // swing right
			}
			
			m_iPVSEntity = iBestCamera;
			
			// send spectators the HLTV director command as a game event
			m_pHLTVServer->BroadcastEvent( shot );
			gameeventmanager->FreeEvent( shot );
		}
	}
	else
	{
		StartBestFixedCameraShot( true );
	}
}