//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CTFFreezePanelCallout *CTFFreezePanel::TestAndAddCallout( Vector &origin, Vector &vMins, Vector &vMaxs, CUtlVector<Vector> *vecCalloutsTL, CUtlVector<Vector> *vecCalloutsBR, Vector &vecFreezeTL, Vector &vecFreezeBR, Vector &vecStatTL, Vector &vecStatBR, int *iX, int *iY ) { // This is the offset from the topleft of the callout to the arrow tip const int iXOffset = XRES(25); const int iYOffset = YRES(50); //if ( engine->IsBoxInViewCluster( vMins + origin, vMaxs + origin) && !engine->CullBox( vMins + origin, vMaxs + origin ) ) { if ( GetVectorInScreenSpace( origin, *iX, *iY ) ) { *iX -= iXOffset; *iY -= iYOffset; int iRight = *iX + CALLOUT_WIDE; int iBottom = *iY + CALLOUT_TALL; if ( *iX > 0 && *iY > 0 && (iRight < ScreenWidth()) && (iBottom < (ScreenHeight()-YRES(40))) ) { // Make sure it wouldn't be over the top of the freezepanel or statpanel Vector vecCalloutTL( *iX, *iY, 0 ); Vector vecCalloutBR( iRight, iBottom, 1 ); if ( !QuickBoxIntersectTest( vecCalloutTL, vecCalloutBR, vecFreezeTL, vecFreezeBR ) && !QuickBoxIntersectTest( vecCalloutTL, vecCalloutBR, vecStatTL, vecStatBR ) ) { // Make sure it doesn't intersect any other callouts bool bClear = true; for ( int iCall = 0; iCall < vecCalloutsTL->Count(); iCall++ ) { if ( QuickBoxIntersectTest( vecCalloutTL, vecCalloutBR, vecCalloutsTL->Element(iCall), vecCalloutsBR->Element(iCall) ) ) { bClear = false; break; } } if ( bClear ) { // Verify that we have LOS to the gib trace_t tr; UTIL_TraceLine( origin, MainViewOrigin(), MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr ); bClear = ( tr.fraction >= 1.0f ); } if ( bClear ) { CTFFreezePanelCallout *pCallout = new CTFFreezePanelCallout( g_pClientMode->GetViewport(), "FreezePanelCallout" ); m_pCalloutPanels.AddToTail( vgui::SETUP_PANEL(pCallout) ); vecCalloutsTL->AddToTail( vecCalloutTL ); vecCalloutsBR->AddToTail( vecCalloutBR ); pCallout->SetVisible( true ); pCallout->SetBounds( *iX, *iY, CALLOUT_WIDE, CALLOUT_TALL ); return pCallout; } } } } } return NULL; }
inline void TestPoints( const Vector &vTestPoint, int &minsx, int &minsy, int &maxsx, int &maxsy ) { int tempx, tempy; GetVectorInScreenSpace(vTestPoint, tempx, tempy); if( tempx < minsx ) minsx = tempx; if( tempx > maxsx ) maxsx = tempx; if( tempy < minsy ) minsy = tempy; if( tempy > maxsy ) maxsy = tempy; }
bool CGodRaysEffect::SetMaterialParms( const Vector& vLightPos ) { int nSunX, nSunY; bool bOnScreen = GetVectorInHudSpace( vLightPos, nSunX, nSunY ); if( bOnScreen ) { // Set the material parameters. m_pGrDecayVar->SetFloatValue( gfx_gr_decay.GetFloat() ); m_pGrDensityVar->SetFloatValue( gfx_gr_density.GetFloat() ); m_pGrExposureVar->SetFloatValue( gfx_gr_exposure.GetFloat() ); m_pGrWeightVar->SetFloatValue( gfx_gr_weight.GetFloat() ); // Set the sun position. float flSunX = float( nSunX ) / float( ScreenWidth() ); float flSunY = float( nSunY ) / float( ScreenHeight() ); m_pGrSunPosVar->SetVecValue(flSunX, flSunY); } return bOnScreen; #if 0 // Convert from 3d to 2d. Vector vLightPos2d; int behind = ScreenTransform( vLightPos, vLightPos2d ); if( behind == 0 ) { m_pGrDecayVar->SetFloatValue( gfx_gr_decay.GetFloat() ); m_pGrDensityVar->SetFloatValue( gfx_gr_density.GetFloat() ); m_pGrExposureVar->SetFloatValue( gfx_gr_exposure.GetFloat() ); m_pGrWeightVar->SetFloatValue( gfx_gr_weight.GetFloat() ); int sunX, sunY; GetVectorInScreenSpace( vLightPos, sunX, sunY ); m_pGrSunPosVar->SetVecValue( sunX / ScreenWidth(), sunY / ScreenHeight() ); return true; } return false; #endif }
//----------------------------------------------------------------------------- // Purpose: Get the x & y positions of an entity in screenspace // Returns true if it's onscreen //----------------------------------------------------------------------------- bool GetTargetInScreenSpace( C_BaseEntity *pTargetEntity, int& iX, int& iY, Vector *vecOffset ) { return GetVectorInScreenSpace( pTargetEntity->WorldSpaceCenter(), iX, iY, vecOffset ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFFreezePanel::UpdateCallout( void ) { CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return; // Abort early if we have no gibs or ragdoll CUtlVector<EHANDLE> *pGibList = pPlayer->GetSpawnedGibs(); IRagdoll *pRagdoll = pPlayer->GetRepresentativeRagdoll(); if ( (!pGibList || pGibList->Count() == 0) && !pRagdoll ) return; if ( m_pFreezePanelBG == NULL ) return; // Precalc the vectors of the freezepanel & statpanel int iX, iY; m_pFreezePanelBG->GetPos( iX, iY ); Vector vecFreezeTL( iX, iY, 0 ); Vector vecFreezeBR( iX + m_pFreezePanelBG->GetWide(), iY + m_pFreezePanelBG->GetTall(), 1 ); CUtlVector<Vector> vecCalloutsTL; CUtlVector<Vector> vecCalloutsBR; Vector vecStatTL(0,0,0); Vector vecStatBR(0,0,1); CTFStatPanel *pStatPanel = GET_HUDELEMENT( CTFStatPanel ); if ( pStatPanel && pStatPanel->IsVisible() ) { pStatPanel->GetPos( iX, iY ); vecStatTL.x = iX; vecStatTL.y = iY; vecStatBR.x = vecStatTL.x + pStatPanel->GetWide(); vecStatBR.y = vecStatTL.y + pStatPanel->GetTall(); } Vector vMins, vMaxs; // Check gibs if ( pGibList && pGibList->Count() ) { int iCount = 0; for ( int i = 0; i < pGibList->Count(); i++ ) { CBaseEntity *pGib = pGibList->Element(i); if ( pGib ) { Vector origin = pGib->GetRenderOrigin(); IPhysicsObject *pPhysicsObject = pGib->VPhysicsGetObject(); if( pPhysicsObject ) { Vector vecMassCenter = pPhysicsObject->GetMassCenterLocalSpace(); pGib->CollisionProp()->CollisionToWorldSpace( vecMassCenter, &origin ); } pGib->GetRenderBounds( vMins, vMaxs ); // Try and add the callout CTFFreezePanelCallout *pCallout = TestAndAddCallout( origin, vMins, vMaxs, &vecCalloutsTL, &vecCalloutsBR, vecFreezeTL, vecFreezeBR, vecStatTL, vecStatBR, &iX, &iY ); if ( pCallout ) { pCallout->UpdateForGib( i, iCount ); iCount++; } } } } else if ( pRagdoll ) { Vector origin = pRagdoll->GetRagdollOrigin(); pRagdoll->GetRagdollBounds( vMins, vMaxs ); // Try and add the callout CTFFreezePanelCallout *pCallout = TestAndAddCallout( origin, vMins, vMaxs, &vecCalloutsTL, &vecCalloutsBR, vecFreezeTL, vecFreezeBR, vecStatTL, vecStatBR, &iX, &iY ); if ( pCallout ) { pCallout->UpdateForRagdoll(); } // even if the callout failed, check that our ragdoll is onscreen and our killer is taunting us (for an achievement) if ( GetVectorInScreenSpace( origin, iX, iY ) ) { C_TFPlayer *pKiller = ToTFPlayer( UTIL_PlayerByIndex( GetSpectatorTarget() ) ); if ( pKiller && pKiller->m_Shared.InCond( TF_COND_TAUNTING ) ) { // tell the server our ragdoll just got taunted during our freezecam char cmd[256]; int iPlayerID = pPlayer->GetUserID(); unsigned short mask = UTIL_GetAchievementEventMask(); Q_snprintf( cmd, sizeof( cmd ), "freezecam_taunt %d %d", GetSpectatorTarget() ^ mask, ( iPlayerID ^ GetSpectatorTarget() ) ^ mask ); engine->ClientCmd_Unrestricted( cmd ); } } } }