Пример #1
0
//-----------------------------------------------------------------------------
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
//			by this player, otherwise draw the worldmodel.
//-----------------------------------------------------------------------------
int C_BaseCombatWeapon::DrawModel( int flags )
{
	VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
	if ( !m_bReadyToDraw )
		return 0;

	if ( !IsVisible() )
		return 0;

	// check if local player chases owner of this weapon in first person
	C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();

	if ( localplayer && localplayer->IsObserver() && GetOwner() )
	{
		// don't draw weapon if chasing this guy as spectator
		// we don't check that in ShouldDraw() since this may change
		// without notification 
		
		if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
			 localplayer->GetObserverTarget() == GetOwner() ) 
			return false;
	}

	return BaseClass::DrawModel( flags );
}
Пример #2
0
bool IsLocalPlayerSpectator( void )
{
	C_BasePlayer * player = C_BasePlayer::GetLocalPlayer();

	if ( player )
		return player->IsObserver();
	else
		return false;	// game not started yet
}
Пример #3
0
void C_HLTVCamera::SpecNextPlayer( bool bInverse )
{
	int start = 0;

	if ( m_iTraget1 > 0 && m_iTraget1 <= gpGlobals->maxClients )
		start = m_iTraget1;
	else if (GetBall() && m_iTraget1 == GetBall()->entindex())
		start = 0;

	int index = start;

	while ( true )
	{	
		// got next/prev player
		if ( bInverse )
			index--;
		else
			index++;

		// check bounds
		if ( index < 0 )
		{
			index = gpGlobals->maxClients;
		}
		else if ( index > gpGlobals->maxClients )
		{
			index = 0;
		}

		if ( index == start )
			break; // couldn't find a new valid player

		if (index > 0 && index <= gpGlobals->maxClients)
		{
			C_BasePlayer *pPlayer =	UTIL_PlayerByIndex( index );

			if ( !pPlayer )
				continue;

			// only follow living players 
			if ( pPlayer->IsObserver() )
				continue;
		}

		break; // found a new player
	}

	if (index == 0 && GetBall())
		index = GetBall()->entindex();

	if (index != 0)
		SetPrimaryTarget( index );

	// turn off auto director once user tried to change view settings
	SetAutoDirector( false );
}
Пример #4
0
void C_Camera::SpecNextTarget(bool inverse)
{
	int start = 0;

	if (m_nTarget > 0 && m_nTarget <= gpGlobals->maxClients)
		start = m_nTarget;
	else if (GetMatchBall() && m_nTarget == GetMatchBall()->entindex())
		start = 0;

	int index = start;

	while ( true )
	{	
		// got next/prev player
		if (inverse)
			index--;
		else
			index++;

		// check bounds
		if ( index < 0 )
		{
			index = gpGlobals->maxClients;
		}
		else if ( index > gpGlobals->maxClients )
		{
			index = 0;
		}

		if ( index == start )
			break; // couldn't find a new valid player

		if (index > 0 && index <= gpGlobals->maxClients)
		{
			C_BasePlayer *pPlayer =	UTIL_PlayerByIndex( index );

			if ( !pPlayer )
				continue;

			// only follow living players 
			if ( pPlayer->IsObserver() )
				continue;
		}

		break; // found a new player
	}

	if (index == 0 && GetMatchBall())
		index = GetMatchBall()->entindex();

	if (index != 0)
		SetTarget( index );
}
Пример #5
0
void OpenVoiceMenu( int index )
{
	// do not show the menu if the player is dead or is an observer
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	if ( !pPlayer->IsAlive() || pPlayer->IsObserver() )
		return;

	CHudMenu *pMenu = (CHudMenu *) gHUD.FindElement( "CHudMenu" );
	if ( !pMenu )
		return;

	// if they hit the key again, close the menu
	if ( g_ActiveVoiceMenu == index )
	{
		if ( pMenu->IsMenuOpen() )
		{
			pMenu->HideMenu();
			g_ActiveVoiceMenu = 0;
			return;
		}
	}

	if ( index > 0 && index < 9 )
	{
		KeyValues *pKV = new KeyValues( "MenuItems" );

		CMultiplayRules *pRules = dynamic_cast< CMultiplayRules * >( GameRules() );
		if ( pRules )
		{			
			if ( !pRules->GetVoiceMenuLabels( index-1, pKV ) )
			{ 
				pKV->deleteThis();
				return;
			}
		}

		pMenu->ShowMenu_KeyValueItems( pKV );

		pKV->deleteThis();

		g_ActiveVoiceMenu = index;
	}
	else
	{
		g_ActiveVoiceMenu = 0;
	}
}
Пример #6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
int CBasePlayer::GetDefaultFOV( void ) const
{
#if defined( CLIENT_DLL )
	if ( GetObserverMode() == OBS_MODE_IN_EYE )
	{
		C_BasePlayer *pTargetPlayer = dynamic_cast<C_BasePlayer*>( GetObserverTarget() );

		if ( pTargetPlayer && !pTargetPlayer->IsObserver() )
		{
			return pTargetPlayer->GetDefaultFOV();
		}
	}
#endif

	int iFOV = ( m_iDefaultFOV == 0 ) ? g_pGameRules->DefaultFOV() : m_iDefaultFOV;

	return iFOV;
}
Пример #7
0
void C_HLTVCamera::SpecNamedPlayer( const char *szPlayerName )
{
	for ( int index = 1; index <= gpGlobals->maxClients; ++index )
	{
		C_BasePlayer *pPlayer =	UTIL_PlayerByIndex( index );

		if ( !pPlayer )
			continue;

		if ( !FStrEq( szPlayerName, pPlayer->GetPlayerName() ) )
			continue;

		// only follow living players or dedicated spectators
		if ( pPlayer->IsObserver() && pPlayer->GetTeamNumber() != TEAM_SPECTATOR )
			continue;

		SetPrimaryTarget( index );
		return;
	}
}
bool CGEObjectives::ShouldDraw( void )
{
	// Forget about drawing without our resource
	if ( !g_RR )
		return false;

	// Never draw if our CVars don't allow it
	// unless we are forcing it with our gameplay
	if ( cl_ge_showobjectives.GetInt() == 0 )
		return false;

	// Don't show if we are in intermission time!
	if ( GEMPRules() && GEMPRules()->IsIntermission() )
		return false;

	// Always show if we are observing and passed the tests above
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( pPlayer && pPlayer->IsObserver() )
		return true;

	return CHudElement::ShouldDraw();
}
//----------------------------------------------------------------------------
// Hooks into the fast path render system
//----------------------------------------------------------------------------
IClientModelRenderable*	C_BaseCombatWeapon::GetClientModelRenderable()
{
	if ( !m_bReadyToDraw )
		return 0;

	// check if local player chases owner of this weapon in first person
	C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
	if ( localplayer && localplayer->IsObserver() && GetOwner() )
	{
		// don't draw weapon if chasing this guy as spectator
		// we don't check that in ShouldDraw() since this may change
		// without notification 
		if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
			localplayer->GetObserverTarget() == GetOwner() ) 
			return NULL;
	}

	if ( !BaseClass::GetClientModelRenderable() )
		return NULL;

	EnsureCorrectRenderingModel();
	return this;
}
Пример #10
0
//-----------------------------------------------------------------------------
// Purpose: Render current view into specified rectangle
// Input  : *rect - is computed by CVideoMode_Common::GetClientViewRect()
//-----------------------------------------------------------------------------
void CViewRender::Render( vrect_t *rect )
{
	Assert(s_DbgSetupOrigin == m_View.origin);
	Assert(s_DbgSetupAngles == m_View.angles);

	VPROF_BUDGET( "CViewRender::Render", "CViewRender::Render" );
	tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );

	vrect_t vr = *rect;

	// Stub out the material system if necessary.
	CMatStubHandler matStub;

	engine->EngineStats_BeginFrame();
	
	// Assume normal vis
	m_bForceNoVis			= false;
	
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();


    // Set for console commands, etc.
    render->SetMainView ( m_View.origin, m_View.angles );

    for( StereoEye_t eEye = GetFirstEye(); eEye <= GetLastEye(); eEye = (StereoEye_t)(eEye+1) )
	{
		CViewSetup &view = GetView( eEye );

		#if 0 && defined( CSTRIKE_DLL )
			const bool bPlayingBackReplay = g_pEngineClientReplay && g_pEngineClientReplay->IsPlayingReplayDemo();
			if ( pPlayer && !bPlayingBackReplay )
			{
				C_BasePlayer *pViewTarget = pPlayer;

				if ( pPlayer->IsObserver() && pPlayer->GetObserverMode() == OBS_MODE_IN_EYE )
				{
					pViewTarget = dynamic_cast<C_BasePlayer*>( pPlayer->GetObserverTarget() );
				}

				if ( pViewTarget )
				{
					float targetFOV = (float)pViewTarget->m_iFOV;

					if ( targetFOV == 0 )
					{
						// FOV of 0 means use the default FOV
						targetFOV = g_pGameRules->DefaultFOV();
					}

					float deltaFOV = view.fov - m_flLastFOV;
					float FOVDirection = targetFOV - pViewTarget->m_iFOVStart;

					// Clamp FOV changes to stop FOV oscillation
					if ( ( deltaFOV < 0.0f && FOVDirection > 0.0f ) ||
						( deltaFOV > 0.0f && FOVDirection < 0.0f ) )
					{
						view.fov = m_flLastFOV;
					}

					// Catch case where FOV overshoots its target FOV
					if ( ( view.fov < targetFOV && FOVDirection <= 0.0f ) ||
						( view.fov > targetFOV && FOVDirection >= 0.0f ) )
					{
						view.fov = targetFOV;
					}

					m_flLastFOV = view.fov;
				}
			}
		#endif

	    static ConVarRef sv_restrict_aspect_ratio_fov( "sv_restrict_aspect_ratio_fov" );
	    float aspectRatio = engine->GetScreenAspectRatio() * 0.75f;	 // / (4/3)
	    float limitedAspectRatio = aspectRatio;
	    if ( ( sv_restrict_aspect_ratio_fov.GetInt() > 0 && engine->IsWindowedMode() && gpGlobals->maxClients > 1 ) ||
		    sv_restrict_aspect_ratio_fov.GetInt() == 2 )
	    {
		    limitedAspectRatio = MIN( aspectRatio, 1.85f * 0.75f ); // cap out the FOV advantage at a 1.85:1 ratio (about the widest any legit user should be)
	    }

	    view.fov = ScaleFOVByWidthRatio( view.fov, limitedAspectRatio );
	    view.fovViewmodel = ScaleFOVByWidthRatio( view.fovViewmodel, aspectRatio );

	    // Let the client mode hook stuff.
	    g_pClientMode->PreRender(&view);

	    g_pClientMode->AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height );

	    ToolFramework_AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height );

	    float flViewportScale = mat_viewportscale.GetFloat();

		view.m_nUnscaledX = vr.x;
		view.m_nUnscaledY = vr.y;
		view.m_nUnscaledWidth = vr.width;
		view.m_nUnscaledHeight = vr.height;

        switch( eEye )
		{
			case STEREO_EYE_MONO:
			{
#if 0
                // Good test mode for debugging viewports that are not full-size.
	            view.width			= vr.width * flViewportScale * 0.75f;
	            view.height			= vr.height * flViewportScale * 0.75f;
	            view.x				= vr.x + view.width * 0.10f;
	            view.y				= vr.y + view.height * 0.20f;
#else
	            view.x				= vr.x * flViewportScale;
				view.y				= vr.y * flViewportScale;
				view.width			= vr.width * flViewportScale;
				view.height			= vr.height * flViewportScale;
#endif
			    float engineAspectRatio = engine->GetScreenAspectRatio();
			    view.m_flAspectRatio	= ( engineAspectRatio > 0.0f ) ? engineAspectRatio : ( (float)view.width / (float)view.height );
			}
			break;

			case STEREO_EYE_RIGHT:
			case STEREO_EYE_LEFT:
			{
				g_pSourceVR->GetViewportBounds( (ISourceVirtualReality::VREye)(eEye - 1 ), &view.x, &view.y, &view.width, &view.height );
				view.m_nUnscaledWidth = view.width;
				view.m_nUnscaledHeight = view.height;
				view.m_nUnscaledX = view.x;
				view.m_nUnscaledY = view.y;
			}
			break;

            default:
                Assert ( false );
                break;
		}

		// if we still don't have an aspect ratio, compute it from the view size
		if( view.m_flAspectRatio <= 0.f )
		    view.m_flAspectRatio	= (float)view.width / (float)view.height;

	    int nClearFlags = VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL;

	    if( gl_clear_randomcolor.GetBool() )
	    {
		    CMatRenderContextPtr pRenderContext( materials );
		    pRenderContext->ClearColor3ub( rand()%256, rand()%256, rand()%256 );
		    pRenderContext->ClearBuffers( true, false, false );
		    pRenderContext->Release();
	    }
	    else if ( gl_clear.GetBool() )
	    {
		    nClearFlags |= VIEW_CLEAR_COLOR;
	    }
	    else if ( IsPosix() )
	    {
		    MaterialAdapterInfo_t adapterInfo;
		    materials->GetDisplayAdapterInfo( materials->GetCurrentAdapter(), adapterInfo );

		    // On Posix, on ATI, we always clear color if we're antialiasing
		    if ( adapterInfo.m_VendorID == 0x1002 )
		    {
			    if ( g_pMaterialSystem->GetCurrentConfigForVideoCard().m_nAASamples > 0 )
			    {
				    nClearFlags |= VIEW_CLEAR_COLOR;
			    }
		    }
	    }

	    // Determine if we should draw view model ( client mode override )
	    bool drawViewModel = g_pClientMode->ShouldDrawViewModel();

	    if ( cl_leveloverview.GetFloat() > 0 )
	    {
		    SetUpOverView();		
		    nClearFlags |= VIEW_CLEAR_COLOR;
		    drawViewModel = false;
	    }

	    // Apply any player specific overrides
	    if ( pPlayer )
	    {
		    // Override view model if necessary
		    if ( !pPlayer->m_Local.m_bDrawViewmodel )
		    {
			    drawViewModel = false;
		    }
	    }

	    int flags = 0;
		if( eEye == STEREO_EYE_MONO || eEye == STEREO_EYE_LEFT || ( g_ClientVirtualReality.ShouldRenderHUDInWorld() ) )
		{
			flags = RENDERVIEW_DRAWHUD;
		}
	    if ( drawViewModel )
	    {
		    flags |= RENDERVIEW_DRAWVIEWMODEL;
	    }
		if( eEye == STEREO_EYE_RIGHT )
		{
			// we should use the monitor view from the left eye for both eyes
			flags |= RENDERVIEW_SUPPRESSMONITORRENDERING;
		}

	    RenderView( view, nClearFlags, flags );

		if ( UseVR() )
		{
			bool bDoUndistort = ! engine->IsTakingScreenshot();

			if ( bDoUndistort )
			{
				g_ClientVirtualReality.PostProcessFrame( eEye );
			}

			// logic here all cloned from code in viewrender.cpp around RenderHUDQuad:

			// figure out if we really want to draw the HUD based on freeze cam
			bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM );

			// draw the HUD after the view model so its "I'm closer" depth queues work right.
			if( !bInFreezeCam && g_ClientVirtualReality.ShouldRenderHUDInWorld() )
			{
				// TODO - a bit of a shonky test - basically trying to catch the main menu, the briefing screen, the loadout screen, etc.
				bool bTranslucent = !g_pMatSystemSurface->IsCursorVisible();
				g_ClientVirtualReality.OverlayHUDQuadWithUndistort( view, bDoUndistort, g_pClientMode->ShouldBlackoutAroundHUD(), bTranslucent );
			}
		}
    }


	// TODO: should these be inside or outside the stereo eye stuff?
	g_pClientMode->PostRender();
	engine->EngineStats_EndFrame();

#if !defined( _X360 )
	// Stop stubbing the material system so we can see the budget panel
	matStub.End();
#endif


	// Draw all of the UI stuff "fullscreen"
    // (this is not health, ammo, etc. Nor is it pre-game briefing interface stuff - this is the stuff that appears when you hit Esc in-game)
	// In stereo mode this is rendered inside of RenderView so it goes into the render target
	if( !g_ClientVirtualReality.ShouldRenderHUDInWorld() )
	{
		CViewSetup view2d;
		view2d.x				= rect->x;
		view2d.y				= rect->y;
		view2d.width			= rect->width;
		view2d.height			= rect->height;

		render->Push2DView( view2d, 0, NULL, GetFrustum() );
		render->VGui_Paint( PAINT_UIPANELS | PAINT_CURSOR );
		render->PopView( GetFrustum() );
	}


}
void CGERadar::WorldToRadar( CGERadarContact *contact )
{
	// If we are out of range don't bother
	if ( !IsContactInRange( contact ) )
		return;

	C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pLocalPlayer )
		return;

	Vector vContact = GetContactPosition(contact);

	float x_diff = vContact.x - pLocalPlayer->GetAbsOrigin().x;
	float y_diff = vContact.y - pLocalPlayer->GetAbsOrigin().y;

	// Supply epsilon values to avoid divide-by-zero
	if(x_diff == 0.0f )
		x_diff = 0.001f;

	if(y_diff == 0.0f )
		y_diff = 0.001f;

	float fRadarRadius = m_flRadarDiameter * 0.500f;
	float fRange = GetRadarRange();
	float fScale = fRange >= 1.000f ? fRadarRadius / fRange : 0.000f;
	float dist = min( GetContactRange( vContact ), fRange );

	float flOffset = atan(y_diff/x_diff);
	float flPlayerY;

	// If we're in first person spectate mode we should use the rotation of whoever we're spectating.
	if (pLocalPlayer->IsObserver() && pLocalPlayer->GetObserverTarget() && pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE)
		flPlayerY = (pLocalPlayer->GetLocalAngles().y * M_PI) * 0.0055555f;
	else
		flPlayerY = (pLocalPlayer->LocalEyeAngles().y * M_PI) * 0.0055555f;

	// Always add because atan will return neg angle w/ neg coeff
	if ( x_diff < 0 )
		flOffset += M_PI;
	else
		flOffset += M_TWOPI;

	flOffset = flPlayerY - flOffset;

	// Transform relative to radar source
	float xnew_diff = dist * sin(flOffset);
	float ynew_diff = -dist * cos(flOffset);

	// Scale the dot's position to match radar scale
	xnew_diff *= fScale;
	ynew_diff *= fScale;

	// Make sure we never leave our radar circle!
	contact->m_vScaledPos.x = fRadarRadius + xnew_diff + m_iSideBuff;
	contact->m_vScaledPos.y = fRadarRadius + ynew_diff + m_iSideBuff;
	contact->m_vScaledPos.z = vContact.z - pLocalPlayer->GetAbsOrigin().z;

	// Figure out our alpha modulation
	if ( !contact->m_bAlwaysVisible && dist > fRange * 0.8f )
		contact->m_flAlphaMod = RemapValClamped( dist, fRange * 0.8f, fRange, 1.0, 0 );
	else
		contact->m_flAlphaMod = 1.0f;
}