//----------------------------------------------------------------------------- // Purpose: This is called every time the DLL is loaded //----------------------------------------------------------------------------- void CHud::Init( void ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); m_nSplitScreenSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); g_HudHelper.Init(); InitFonts(); // Create all the Hud elements CHudElementHelper::CreateAllElements(); gLCD.Init(); // Initialize all created elements for ( int i = 0; i < GetHudList().Count(); i++ ) { GetHudList()[ i ]->Init(); } KeyValues *kv = new KeyValues( "layout" ); if ( kv ) { if ( kv->LoadFromFile( filesystem, "scripts/HudLayout.res" ) ) { int numelements = GetHudList().Count(); for ( int i = 0; i < numelements; i++ ) { CHudElement *element = GetHudList()[i]; vgui::Panel *pPanel = GetHudPanelList()[i]; KeyValues *key = kv->FindKey( pPanel->GetName(), false ); if ( !key ) { Msg( "Hud element '%s' doesn't have an entry '%s' in scripts/HudLayout.res\n", element->GetName(), pPanel->GetName() ); } // Note: When a panel is parented to the module root, it's "parent" is returned as NULL. if ( !element->IsParentedToClientDLLRootPanel() && !pPanel->GetParent() ) { DevMsg( "Hud element '%s'/'%s' doesn't have a parent\n", element->GetName(), pPanel->GetName() ); } } } kv->deleteThis(); } if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 ) { HudIcons().Init(); } }
void CParticleSystemQuery::GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight, Vector *pUp ) { #ifdef CLIENT_DLL // HACK_GETLOCALPLAYER_GUARD( "CParticleSystemQuery::GetLocalPlayerPos" ); int slot = GET_ACTIVE_SPLITSCREEN_SLOT(); ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot ); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) { *pForward = vec3_origin; *pRight = vec3_origin; *pUp = vec3_origin; return; } pPlayer->EyeVectors( pForward, pRight, pUp ); #else CBasePlayer *pPlayer = AI_GetSinglePlayer(); if ( !pPlayer ) { *pForward = vec3_origin; *pRight = vec3_origin; *pUp = vec3_origin; return; } pPlayer->EyeVectors( pForward, pRight, pUp ); #endif }
void C_ParticleSmokeGrenade::ClientThink() { if ( m_CurrentStage == 1 ) { // Add our influence to the global smoke fog alpha. ASSERT_LOCAL_PLAYER_RESOLVABLE(); int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); float testDist = (MainViewOrigin(nSlot) - m_SmokeBasePos).Length(); float fadeEnd = m_ExpandRadius; // The center of the smoke cloud that always gives full fog overlay float flCoreDistance = fadeEnd * 0.15; if(testDist < fadeEnd) { if( testDist < flCoreDistance ) { EngineGetSmokeFogOverlayAlpha() += m_FadeAlpha; } else { EngineGetSmokeFogOverlayAlpha() += (1 - ( testDist - flCoreDistance ) / ( fadeEnd - flCoreDistance ) ) * m_FadeAlpha; } } } }
virtual float GetFloat() const { if ( !sv_cheats ) sv_cheats = cvar->FindVar( "sv_cheats" ); float flBaseValue; // If sv_cheats is on then it can be anything. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); if ( nSlot != 0 ) { static SplitScreenConVarRef s_m_pitch( "m_pitch" ); flBaseValue = s_m_pitch.GetFloat( nSlot ); } else { flBaseValue = GetBaseFloatValue(); } if ( !sv_cheats || sv_cheats->GetBool() ) return flBaseValue; // If sv_cheats is off than it can only be 0.022 or -0.022 (if they've reversed the mouse in the options). if ( flBaseValue > 0 ) return 0.022f; else return -0.022f; }
CHud &GetHud( int nSlot /*= -1*/ ) { if ( nSlot == -1 ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); } return gHUD[ nSlot ]; }
const CViewSetup &CViewRender::GetView(int nSlot /*= -1*/) const { Assert( m_bAllowViewAccess ); if ( nSlot == -1 ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return m_UserView[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; } return m_UserView[ nSlot ]; }
//----------------------------------------------------------------------------- // Purpose: // Output : const CViewSetup //----------------------------------------------------------------------------- const CViewSetup *CViewRender::GetPlayerViewSetup( int nSlot /*= -1*/ ) const { // NOTE: This code path doesn't require m_bAllowViewAccess == true!!! if ( nSlot == -1 ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return &m_UserView[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; } return &m_UserView[ nSlot ]; }
static inline Vector& EngineGetVecRenderOrigin() { #if defined(PARTICLEPROTOTYPE_APP) static Vector dummy(0,0,0); return dummy; #else extern Vector g_vecRenderOrigin[ MAX_SPLITSCREEN_PLAYERS ]; return g_vecRenderOrigin[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; #endif }
Vector CParticleSystemQuery::GetCurrentViewOrigin() { #ifdef CLIENT_DLL int slot = GET_ACTIVE_SPLITSCREEN_SLOT(); ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot ); return CurrentViewOrigin(); #else return vec3_origin; #endif }
//----------------------------------------------------------------------------- CFlashlightEffectManager & FlashlightEffectManager( int32 nSplitscreenPlayerOverride ) { static CFlashlightEffectManager s_flashlightEffectManagerArray[ MAX_SPLITSCREEN_PLAYERS ]; if ( nSplitscreenPlayerOverride != -1 ) { return s_flashlightEffectManagerArray[ nSplitscreenPlayerOverride ]; } ASSERT_LOCAL_PLAYER_RESOLVABLE(); return s_flashlightEffectManagerArray[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; }
float CParticleSystemQuery::GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale ) { #ifdef CLIENT_DLL int slot = GET_ACTIVE_SPLITSCREEN_SLOT(); ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot ); pixelvis_queryparams_t params; params.Init( vecOrigin, flScale, 1.0 ); float flVisibility = PixelVisibility_FractionVisible( params, pQueryHandle ); flVisibility = MAX( 0.0f, flVisibility ); return flVisibility; #else return 0.0f; #endif }
//----------------------------------------------------------------------------- // Purpose: Inform client(s) they can mark the indicated achievement as completed (SERVER VERSION) // Input : filter - which client(s) to send this to // iAchievementID - The enumeration value of the achievement to mark (see TODO:Kerry, what file will have the mod's achievement enum?) //----------------------------------------------------------------------------- void CGameRules::MarkAchievement( IRecipientFilter& filter, char const *pchAchievementName ) { gamestats->Event_IncrementCountedStatistic( vec3_origin, pchAchievementName, 1.0f ); IAchievementMgr *pAchievementMgr = engine->GetAchievementMgr(); if ( !pAchievementMgr ) return; #ifdef GAME_DLL pAchievementMgr->OnMapEvent( pchAchievementName, SINGLE_PLAYER_SLOT ); #else pAchievementMgr->OnMapEvent( pchAchievementName, GET_ACTIVE_SPLITSCREEN_SLOT() ); #endif }
//----------------------------------------------------------------------------- // Purpose: // Input : *name - // hook - //----------------------------------------------------------------------------- void CUserMessages::HookMessage( const char *name, pfnUserMsgHook hook ) { #if defined( CLIENT_DLL ) Assert( name ); Assert( hook ); int idx = m_UserMessages.Find( name ); if ( idx == m_UserMessages.InvalidIndex() ) { DevMsg( "CUserMessages::HookMessage: no such message %s\n", name ); Assert( 0 ); return; } ASSERT_LOCAL_PLAYER_RESOLVABLE(); int i = m_UserMessages[ idx ]->clienthooks[ GET_ACTIVE_SPLITSCREEN_SLOT() ].AddToTail(); m_UserMessages[ idx ]->clienthooks[GET_ACTIVE_SPLITSCREEN_SLOT()][i] = hook; #else Error( "CUserMessages::HookMessage called from server code!!!\n" ); #endif }
Vector CParticleSystemQuery::GetLocalPlayerPos( void ) { #ifdef CLIENT_DLL // HACK_GETLOCALPLAYER_GUARD( "CParticleSystemQuery::GetLocalPlayerPos" ); int slot = GET_ACTIVE_SPLITSCREEN_SLOT(); ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot ); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return vec3_origin; return pPlayer->WorldSpaceCenter(); #else CBasePlayer *pPlayer = AI_GetSinglePlayer(); if ( !pPlayer ) return vec3_origin; return pPlayer->WorldSpaceCenter(); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHud::Shutdown( void ) { gLCD.Shutdown(); // Delete all the Hud elements int iMax = GetHudList().Count(); for ( int i = iMax-1; i >= 0; i-- ) { delete GetHudList()[i]; } GetHudList().Purge(); GetHudPanelList().Purge(); if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 ) { HudIcons().Shutdown(); } }
//----------------------------------------------------------------------------- // Purpose: Adds a member to the HUD //----------------------------------------------------------------------------- void CHud::AddHudElement( CHudElement *pHudElement ) { pHudElement->SetSplitScreenPlayerSlot( GET_ACTIVE_SPLITSCREEN_SLOT() ); // Add the hud element to the end of the array GetHudList().AddToTail( pHudElement ); vgui::Panel *pPanel = dynamic_cast< vgui::Panel * >( pHudElement ); if ( !pPanel ) { Error( "All hud elements must derive from vgui::Panel * (%s)\n", pHudElement->GetName() ); } GetHudPanelList().AddToTail( pPanel ); pHudElement->SetHud( this ); pHudElement->SetNeedsRemove( true ); }
const Vector &C_BaseViewModel::GetRenderOrigin() { m_vecRender = BaseClass::GetRenderOrigin(); if ( ShouldFlipViewModel() ) { int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); Assert( nSlot != -1 ); const CViewSetup *pViewSetup = view->GetPlayerViewSetup( nSlot ); Vector right, delta = m_vecRender - pViewSetup->origin; AngleVectors( pViewSetup->angles, NULL, &right, NULL ); float flRight = DotProduct( right, delta ); m_vecRender += right * flRight * -2.0f; } return m_vecRender; }
void C_ColorCorrection::Update( C_BasePlayer *pPlayer, float ccScale ) { Assert( m_CCHandle != INVALID_CLIENT_CCHANDLE ); if ( mat_colcorrection_disableentities.GetInt() ) { // Allow the colorcorrectionui panel (or user) to turn off color-correction entities g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); return; } int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); bool bEnabled = IsClientSide() ? m_bEnabledOnClient[nSlot] : m_bEnabled; // fade weight on client if ( IsClientSide() ) { m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f ); } float flCurWeight = IsClientSide() ? m_flCurWeightOnClient[nSlot] : m_flCurWeight; if( !bEnabled && flCurWeight == 0.0f ) { g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); return; } Vector playerOrigin = pPlayer->GetAbsOrigin(); float weight = 0; if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff ) { float dist = (playerOrigin - m_vecOrigin).Length(); weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff); if ( weight<0.0f ) weight = 0.0f; if ( weight>1.0f ) weight = 1.0f; } g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, flCurWeight * ( 1.0 - weight ) * ccScale, m_bExclusive ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pszName - // iSize - // *pbuf - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CUserMessages::DispatchUserMessage( int msg_type, bf_read &msg_data ) { #if defined( CLIENT_DLL ) if ( msg_type < 0 || msg_type >= (int)m_UserMessages.Count() ) { DevMsg( "CUserMessages::DispatchUserMessage: Bogus msg type %i (max == %i)\n", msg_type, m_UserMessages.Count() ); Assert( 0 ); return false; } CUserMessage *entry = m_UserMessages[ msg_type ]; if ( !entry ) { DevMsg( "CUserMessages::DispatchUserMessage: Missing client entry for msg type %i\n", msg_type ); Assert( 0 ); return false; } int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); if ( entry->clienthooks[nSlot].Count() == 0 ) { // not hooking a usermessage is acceptable, pretend we parsed it return true; } for (int i = 0; i < entry->clienthooks[nSlot].Count(); i++ ) { bf_read msg_copy = msg_data; pfnUserMsgHook hook = entry->clienthooks[nSlot][i]; (*hook)( msg_copy ); } return true; #else Error( "CUserMessages::DispatchUserMessage called from server code!!!\n" ); return false; #endif }
void C_ColorCorrection::EnableOnClient( bool bEnable, bool bSkipFade ) { if ( !IsClientSide() ) { return; } int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); if( m_bEnabledOnClient[nSlot] == bEnable ) { return; } m_bFadingIn[nSlot] = bEnable; m_bEnabledOnClient[nSlot] = bEnable; // initialize countdown timer m_flFadeStartWeight[nSlot] = m_flCurWeightOnClient[nSlot]; float flFadeTimeScale = 1.0f; if ( m_flMaxWeight != 0.0f ) { flFadeTimeScale = m_flCurWeightOnClient[nSlot] / m_flMaxWeight; } if ( m_bFadingIn[nSlot] ) { flFadeTimeScale = 1.0f - flFadeTimeScale; } if ( bSkipFade ) { flFadeTimeScale = 0.0f; } StartFade( nSlot, flFadeTimeScale * ( m_bFadingIn[nSlot] ? m_flFadeInDuration : m_flFadeOutDuration ) ); // update the clientside weight once here, in case the fade duration is 0 m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f ); }
//----------------------------------------------------------------------------- // Purpose: Static class creation factory // Searches list of registered factories for a match and then instances the // requested technology by name // Input : *name - // Output : CBaseTFTechnology //----------------------------------------------------------------------------- void CHudElementHelper::CreateAllElements( void ) { // Start of list CHudElementHelper *p = m_sHelpers; while ( p ) { // only create this element in slot 0 if ( ( p->m_iFlags & HUDELEMENT_SS_FULLSCREEN_ONLY ) && ( GET_ACTIVE_SPLITSCREEN_SLOT() != 0 ) ) { p = p->m_pNext; continue; } // Dispatch creation function directly CHudElement *( *fCreate )( void ) = p->m_pfnCreate; CHudElement *newElement = (fCreate)(); if ( newElement ) { GetHud().AddHudElement( newElement ); } p = p->GetNext(); } }
static void GetPos( const CCommand &args, Vector &vecOrigin, QAngle &angles ) { int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); vecOrigin = MainViewOrigin(nSlot); angles = MainViewAngles(nSlot); #ifdef INFESTED_DLL C_ASW_Marine *pMarine = C_ASW_Marine::GetLocalMarine(); if ( pMarine ) { vecOrigin = pMarine->GetAbsOrigin(); angles = pMarine->GetAbsAngles(); } #endif if ( ( args.ArgC() == 2 && atoi( args[1] ) == 2 ) || FStrEq( args[0], "getpos_exact" ) ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { vecOrigin = pPlayer->GetAbsOrigin(); angles = pPlayer->GetAbsAngles(); } } }
IClientMode *GetClientMode() { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return g_pClientMode[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; }
void FX_Tesla( const CTeslaInfo &teslaInfo ) { C_BaseEntity *pEntity = ClientEntityList().GetEnt( teslaInfo.m_nEntIndex ); // Send out beams around us int iNumBeamsAround = (teslaInfo.m_nBeams * 2) / 3; // (2/3 of the beams are placed around in a circle) int iNumRandomBeams = teslaInfo.m_nBeams - iNumBeamsAround; int iTotalBeams = iNumBeamsAround + iNumRandomBeams; float flYawOffset = RandomFloat(0,360); for ( int i = 0; i < iTotalBeams; i++ ) { // Make a couple of tries at it int iTries = -1; Vector vecForward; trace_t tr; do { iTries++; // Some beams are deliberatly aimed around the point, the rest are random. if ( i < iNumBeamsAround ) { QAngle vecTemp = teslaInfo.m_vAngles; vecTemp[YAW] += anglemod( flYawOffset + ((360 / iTotalBeams) * i) ); AngleVectors( vecTemp, &vecForward ); // Randomly angle it up or down vecForward.z = RandomFloat( -1, 1 ); } else { vecForward = RandomVector( -1, 1 ); } VectorNormalize( vecForward ); UTIL_TraceLine( teslaInfo.m_vPos, teslaInfo.m_vPos + (vecForward * teslaInfo.m_flRadius), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr ); } while ( tr.fraction >= 1.0 && iTries < 3 ); Vector vecEnd = tr.endpos - (vecForward * 8); // Only spark & glow if we hit something if ( tr.fraction < 1.0 ) { if ( !EffectOccluded( tr.endpos, 0 ) ) { int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); // Move it towards the camera Vector vecFlash = tr.endpos; Vector vecForward; AngleVectors( MainViewAngles(nSlot), &vecForward ); vecFlash -= (vecForward * 8); g_pEffects->EnergySplash( vecFlash, -vecForward, false ); // End glow CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" ); pSimple->SetSortOrigin( vecFlash ); SimpleParticle *pParticle; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RandomFloat( 0.5, 1 ); pParticle->m_vecVelocity = vec3_origin; Vector color( 1,1,1 ); float colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomFloat( 6,13 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 10; pParticle->m_flRoll = RandomFloat( 0,360 ); pParticle->m_flRollDelta = 0; } } } // Build the tesla FX_BuildTesla( pEntity, teslaInfo.m_vPos, tr.endpos, teslaInfo.m_pszSpriteName, teslaInfo.m_flBeamWidth, teslaInfo.m_vColor, FBEAM_ONLYNOISEONCE, teslaInfo.m_flTimeVisible ); } }
//----------------------------------------------------------------------------- // Purpose: Tesla effect //----------------------------------------------------------------------------- void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset ) { Vector vecOrigin; QAngle vecAngles; MatrixGetColumn( hitboxToWorld, 3, vecOrigin ); MatrixAngles( hitboxToWorld, vecAngles.Base() ); C_BaseEntity *pEntity = GetMoveParent(); // Make a couple of tries at it int iTries = -1; Vector vecForward; trace_t tr; do { iTries++; // Some beams are deliberatly aimed around the point, the rest are random. if ( !bRandom ) { QAngle vecTemp = vecAngles; vecTemp[YAW] += flYawOffset; AngleVectors( vecTemp, &vecForward ); // Randomly angle it up or down vecForward.z = RandomFloat( -1, 1 ); } else { vecForward = RandomVector( -1, 1 ); } UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr ); } while ( tr.fraction >= 1.0 && iTries < 3 ); Vector vecEnd = tr.endpos - (vecForward * 8); // Only spark & glow if we hit something if ( tr.fraction < 1.0 ) { if ( !EffectOccluded( tr.endpos ) ) { int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); // Move it towards the camera Vector vecFlash = tr.endpos; Vector vecForward; AngleVectors( MainViewAngles(nSlot), &vecForward ); vecFlash -= (vecForward * 8); g_pEffects->EnergySplash( vecFlash, -vecForward, false ); // End glow CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" ); pSimple->SetSortOrigin( vecFlash ); SimpleParticle *pParticle; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RandomFloat( 0.5, 1 ); pParticle->m_vecVelocity = vec3_origin; Vector color( 1,1,1 ); float colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomFloat( 6,13 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 10; pParticle->m_flRoll = RandomFloat( 0,360 ); pParticle->m_flRollDelta = 0; } } } // Build the tesla FX_BuildTesla( pEntity, vecOrigin, tr.endpos ); }
void FormatViewModelAttachment( C_BasePlayer *pPlayer, Vector &vOrigin, bool bInverse ) { int nSlot = 0; if ( pPlayer ) { int nPlayerSlot = C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ); if ( nPlayerSlot == -1 ) { nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); } else { nSlot = nPlayerSlot; } } Assert( nSlot != -1 ); // Presumably, SetUpView has been called so we know our FOV and render origin. const CViewSetup *pViewSetup = view->GetPlayerViewSetup( nSlot ); float worldx = tan( pViewSetup->fov * M_PI/360.0 ); float viewx = tan( pViewSetup->fovViewmodel * M_PI/360.0 ); // aspect ratio cancels out, so only need one factor // the difference between the screen coordinates of the 2 systems is the ratio // of the coefficients of the projection matrices (tan (fov/2) is that coefficient) float factorX = worldx / viewx; float factorY = factorX; // Get the coordinates in the viewer's space. Vector tmp = vOrigin - pViewSetup->origin; Vector vTransformed( MainViewRight(nSlot).Dot( tmp ), MainViewUp(nSlot).Dot( tmp ), MainViewForward(nSlot).Dot( tmp ) ); // Now squash X and Y. if ( bInverse ) { if ( factorX != 0 && factorY != 0 ) { vTransformed.x /= factorX; vTransformed.y /= factorY; } else { vTransformed.x = 0.0f; vTransformed.y = 0.0f; } } else { vTransformed.x *= factorX; vTransformed.y *= factorY; } // Transform back to world space. Vector vOut = (MainViewRight(nSlot) * vTransformed.x) + (MainViewUp(nSlot) * vTransformed.y) + (MainViewForward(nSlot) * vTransformed.z); vOrigin = pViewSetup->origin + vOut; }
CASW_Video_Face_BIKHandles* CASW_Video::GetVideoFaceBIKHandles( void ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return &( s_VideoFaceBIKHandles[ GET_ACTIVE_SPLITSCREEN_SLOT() ] ); }
void MsgFunc_ResetHUD( bf_read &msg ) { ASSERT_LOCAL_PLAYER_RESOLVABLE(); gHUD[ GET_ACTIVE_SPLITSCREEN_SLOT() ].MsgFunc_ResetHUD( msg ); }
//----------------------------------------------------------------------------- // Sets up the view parameters //----------------------------------------------------------------------------- void CViewRender::SetUpView() { ASSERT_LOCAL_PLAYER_RESOLVABLE(); int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); m_bAllowViewAccess = true; VPROF("CViewRender::SetUpView"); // Initialize view structure with default values float farZ = GetZFar(); CViewSetup &view = GetView(); view.zFar = farZ; view.zFarViewmodel = farZ; // UNDONE: Make this farther out? // closest point of approach seems to be view center to top of crouched box view.zNear = GetZNear(); view.zNearViewmodel = 1; view.fov = default_fov.GetFloat(); view.m_bOrtho = false; // Enable spatial partition access to edicts partition->SuppressLists( PARTITION_ALL_CLIENT_EDICTS, false ); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); bool bNoViewEnt = false; if( pPlayer == NULL ) { pPlayer = GetSplitScreenViewPlayer( nSlot ); bNoViewEnt = true; } if ( g_bEngineIsHLTV ) { HLTVCamera()->CalcView( view.origin, view.angles, view.fov ); } #if defined( REPLAY_ENABLED ) else if ( engine->IsReplay() ) { ReplayCamera()->CalcView( view.origin, view.angles, view.fov ); } #endif else { // FIXME: Are there multiple views? If so, then what? // FIXME: What happens when there's no player? if (pPlayer) { pPlayer->CalcView( view.origin, view.angles, view.zNear, view.zFar, view.fov ); // If we are looking through another entities eyes, then override the angles/origin for GetView() int viewentity = render->GetViewEntity(); if ( !bNoViewEnt && !g_nKillCamMode && (pPlayer->entindex() != viewentity) ) { C_BaseEntity *ve = cl_entitylist->GetEnt( viewentity ); if ( ve ) { VectorCopy( ve->GetAbsOrigin(), view.origin ); VectorCopy( ve->GetAbsAngles(), view.angles ); } } pPlayer->CalcViewModelView( view.origin, view.angles ); // Is this the proper place for this code? if ( cl_camera_follow_bone_index.GetInt() >= -1 && input->CAM_IsThirdPerson() ) { VectorCopy( g_cameraFollowPos, view.origin ); } } // Even if the engine is paused need to override the view // for keeping the camera control during pause. GetClientMode()->OverrideView( &GetView() ); } // give the toolsystem a chance to override the view ToolFramework_SetupEngineView( view.origin, view.angles, view.fov ); if ( engine->IsPlayingDemo() ) { if ( cl_demoviewoverride.GetFloat() > 0.0f ) { // Retreive view angles from engine ( could have been set in IN_AdjustAngles above ) CalcDemoViewOverride( view.origin, view.angles ); } else { s_DemoView = view.origin; s_DemoAngle = view.angles; } } // Disable spatial partition access partition->SuppressLists( PARTITION_ALL_CLIENT_EDICTS, true ); //Find the offset our current FOV is from the default value float flFOVOffset = default_fov.GetFloat() - view.fov; //Adjust the viewmodel's FOV to move with any FOV offsets on the viewer's end view.fovViewmodel = GetClientMode()->GetViewModelFOV() - flFOVOffset; // Compute the world->main camera transform ComputeCameraVariables( view.origin, view.angles, &g_vecVForward[ nSlot ], &g_vecVRight[ nSlot ], &g_vecVUp[ nSlot ], &g_matCamInverse[ nSlot ] ); // set up the hearing origin... AudioState_t audioState; audioState.m_Origin = view.origin; audioState.m_Angles = view.angles; audioState.m_bIsUnderwater = pPlayer && pPlayer->AudioStateIsUnderwater( view.origin ); ToolFramework_SetupAudioState( audioState ); view.origin = audioState.m_Origin; view.angles = audioState.m_Angles; GetClientMode()->OverrideAudioState( &audioState ); engine->SetAudioState( audioState ); g_vecPrevRenderOrigin[ nSlot ] = g_vecRenderOrigin[ nSlot ]; g_vecPrevRenderAngles[ nSlot ] = g_vecRenderAngles[ nSlot ]; g_vecRenderOrigin[ nSlot ] = view.origin; g_vecRenderAngles[ nSlot ] = view.angles; #ifdef DBGFLAG_ASSERT s_DbgSetupOrigin[ nSlot ] = view.origin; s_DbgSetupAngles[ nSlot ] = view.angles; #endif m_bAllowViewAccess = false; }
//==================================================================== //==================================================================== InClientMode* GetInClientMode() { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return &g_ClientModeNormal[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; }