//----------------------------------------------------------------------------- // Purpose: Update this client's target entity //----------------------------------------------------------------------------- void C_HL2MP_Player::UpdateIDTarget() { if ( !IsLocalPlayer() ) return; // Clear old target and find a new one m_iIDEntIndex = 0; // don't show IDs in chase spec mode if ( GetObserverMode() == OBS_MODE_CHASE || GetObserverMode() == OBS_MODE_DEATHCAM ) return; trace_t tr; Vector vecStart, vecEnd; VectorMA( MainViewOrigin(), 1500, MainViewForward(), vecEnd ); VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart ); UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( !tr.startsolid && tr.DidHitNonWorldEntity() ) { C_BaseEntity *pEntity = tr.m_pEnt; if ( pEntity && (pEntity != this) ) { m_iIDEntIndex = pEntity->entindex(); } } }
//----------------------------------------------------------------------------- // Purpose: Update this client's target entity //----------------------------------------------------------------------------- void C_SDKPlayer::UpdateIDTarget() { if ( !IsLocalPlayer() ) return; // Clear old target and find a new one m_iIDEntIndex = 0; // don't show id's in any state but active. if ( State_Get() != PLAYER_STATE_ACTIVE ) return; trace_t tr; Vector vecStart, vecEnd; VectorMA( MainViewOrigin(), 1500, MainViewForward(), vecEnd ); VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart ); UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( !tr.startsolid && tr.DidHitNonWorldEntity() ) { C_BaseEntity *pEntity = tr.m_pEnt; if ( pEntity && (pEntity != this) ) { m_iIDEntIndex = pEntity->entindex(); } } }
//----------------------------------------------------------------------------- // Actual Eye position + angles //----------------------------------------------------------------------------- Vector CBasePlayer::EyePosition( ) { #ifdef CLIENT_DLL IClientVehicle *pVehicle = GetVehicle(); #else IServerVehicle *pVehicle = GetVehicle(); #endif if ( pVehicle ) { Assert( pVehicle ); int nRole = pVehicle->GetPassengerRole( this ); Vector vecEyeOrigin; QAngle angEyeAngles; pVehicle->GetVehicleViewPosition( nRole, &vecEyeOrigin, &angEyeAngles ); return vecEyeOrigin; } else { #ifdef CLIENT_DLL if ( IsObserver() ) { if ( m_iObserverMode == OBS_MODE_CHASE ) { if ( IsLocalPlayer() ) { return MainViewOrigin(); } } } #endif return BaseClass::EyePosition(); } }
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; } } } }
//----------------------------------------------------------------------------- // Actual Eye position + angles //----------------------------------------------------------------------------- Vector CBasePlayer::EyePosition( ) { if ( GetVehicle() != NULL ) { // Return the cached result CacheVehicleView(); return m_vecVehicleViewOrigin; } else { #ifdef CLIENT_DLL if ( IsObserver() ) { if ( m_iObserverMode == OBS_MODE_CHASE ) { if ( IsLocalPlayer() ) { return MainViewOrigin(); } } } #endif return BaseClass::EyePosition(); } }
//----------------------------------------------------------------------------- // Purpose: Compute the size of the panel based upon the commander's zoom level //----------------------------------------------------------------------------- void CEntityPanel::ComputeAndSetSize( void ) { m_flScale = 1.0; // Scale the image // Use different scales in tactical / normal if ( IsLocalPlayerInTactical() ) { CClientModeCommander *commander = ( CClientModeCommander * )ClientModeCommander(); Assert( commander ); float flZoom = commander->GetCommanderOverlayPanel()->GetZoom(); // Scale our size m_flScale = 0.75 + (0.25 * (1.0 - flZoom)); // 1/2 size at max zoomed out, full size by half zoomed in } else if ( m_pBaseEntity ) { // Get distance to entity float flDistance = (m_pBaseEntity->GetRenderOrigin() - MainViewOrigin()).Length(); flDistance *= 2; m_flScale = 0.25 + MAX( 0, 2.0 - (flDistance / 2048) ); } // Update the size int w = m_iOrgWidth * m_flScale; int h = m_iOrgHeight * m_flScale; SetSize( w,h ); // Update the offsets too m_OffsetX = m_iOrgOffsetX * m_flScale; m_OffsetY = m_iOrgOffsetY * m_flScale; }
//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHLClient::View_Render( vrect_t *rect ) { VPROF( "View_Render" ); // This is the main render entry point... g_SmokeFogOverlayAlpha = 0; // Reset the overlay alpha. view->Render( rect ); // Draw an overlay to make it even harder to see inside smoke particle systems. g_SmokeFogOverlayColor = engine->GetLightForPoint(MainViewOrigin(), true); DrawSmokeFogOverlay(); // Rope_ShowRSpeeds(); }
static void GetPos( const CCommand &args, Vector &vecOrigin, QAngle &angles ) { vecOrigin = MainViewOrigin(); angles = MainViewAngles(); if ( args.ArgC() == 2 && atoi( args[1] ) == 2 ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { vecOrigin = pPlayer->GetAbsOrigin(); angles = pPlayer->GetAbsAngles(); } } }
void vParticleOperator_GravityWorld::Simulate( vParticle *parent ) { float dot_z = DotProduct( MainViewForward(), Vector( 0, 0, -1 ) ); float rotation_dir = Sign( dot_z ); int vx, vy, w, t; vgui::surface()->GetFullscreenViewport( vx, vy, w, t ); Vector screen; if ( ScreenTransform( MainViewOrigin() + Vector( 0, 0, 100 ), screen ) ) ScreenTransform( MainViewOrigin() - Vector( 0, 0, 100 ), screen ); screen *= Vector( 0.5f, -0.5f, 0 ); screen += Vector( 0.5f, 0.5f, 0 ); Vector2D gravity_center( w * screen.x, t * screen.y ); Vector2D delta = parent->vecPos - gravity_center; float screenLength = delta.NormalizeInPlace(); delta *= rotation_dir * -1.0f; Vector2D accel = delta * vParticle::GetRelativeScale() * GetImpulse( parent ) * amt; float speedMult = 1.0f; if ( rotation_dir > 0 ) { float drag = RemapValClamped( rotation_dir, 0.5f, 1, 1, 0.00001f ); ScaleByFrametime( drag ); speedMult = RemapValClamped( (screenLength/vParticle::GetRelativeScale()), 0, 1000, 0, 1 ) * (1.0f - drag) + drag; } parent->vecVelocity += accel; parent->vecVelocity *= speedMult; }
//----------------------------------------------------------------------------- // Purpose: // Input : &pos - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool EffectOccluded(const Vector &pos, pixelvis_handle_t *queryHandle) { if (!queryHandle) { // NOTE: This is called by networking code before the current view is set up. // so use the main view instead trace_t tr; UTIL_TraceLine(pos, MainViewOrigin(), MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr); return (tr.fraction < 1.0f) ? true : false; } pixelvis_queryparams_t params; params.Init(pos); return PixelVisibility_FractionVisible(params, queryHandle) > 0.0f ? false : true; }
//----------------------------------------------------------------------------- // Actual Eye position + angles //----------------------------------------------------------------------------- Vector CBasePlayer::EyePosition( ) { #ifdef CLIENT_DLL if ( IsObserver() ) { if ( GetObserverMode() == OBS_MODE_CHASE ) { if ( IsLocalPlayer() ) { return MainViewOrigin(); } } } #endif return BaseClass::EyePosition(); }
void CGodRaysEffect::GetLightPosition( Vector& vLightPos ) { // Default to world center. vLightPos = vec3_origin; if( m_pSun ) { // Get the directory vector of the sun. Vector vDirection = m_pSun->m_vDirection; // Retrieve the origin of the current view. const Vector vCurOrigin = MainViewOrigin(); // Construct a sunlight position. vLightPos = vCurOrigin + vDirection * view->GetViewSetup()->zFar * 0.999f; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool C_FuncPhysicsRespawnZone::CanMovePropAt( Vector vecOrigin, const Vector &vecMins, const Vector &vecMaxs ) { float flDist = cl_phys_props_respawndist.GetFloat(); // Do a distance check first. We don't want to move props when the player is near 'em. if ( (MainViewOrigin() - vecOrigin).LengthSqr() < (flDist*flDist) ) return false; // Now make sure it's not in view if( engine->IsBoxInViewCluster( vecMins + vecOrigin, vecMaxs + vecOrigin) ) return false; if( !engine->CullBox( vecMins + vecOrigin, vecMaxs + vecOrigin ) ) return false; return true; }
/* ==================== // if( r_drawtranslucentworld ) // { // bSaveDrawTranslucentWorld = r_drawtranslucentworld->GetBool(); // NOTE! : We use to set this to 0 for HDR. // r_drawtranslucentworld->SetValue( 0 ); // } // if( r_drawtranslucentrenderables ) R_TimeRefresh_f For program optimization ==================== */ void R_TimeRefresh_f (void) { int i; float start, stop, time; CViewSetup view; materials->Flush( true ); Q_memset(&view, 0, sizeof(view)); view.origin = MainViewOrigin(); view.angles[0] = 0; view.angles[1] = 0; view.angles[2] = 0; view.x = 0; view.y = 0; view.width = videomode->GetModeWidth(); view.height = videomode->GetModeHeight(); view.fov = 75; view.fovViewmodel = 75; view.m_flAspectRatio = 1.0f; view.zNear = 4; view.zFar = MAX_COORD_FLOAT; view.zNearViewmodel = 4; view.zFarViewmodel = MAX_COORD_FLOAT; int savedeveloper = developer.GetInt(); developer.SetValue( 0 ); start = Sys_FloatTime (); for (i=0 ; i<128 ; i++) { view.angles[1] = i/128.0*360.0; g_ClientDLL->RenderView( view, VIEW_CLEAR_COLOR, RENDERVIEW_DRAWVIEWMODEL | RENDERVIEW_DRAWHUD ); Shader_SwapBuffers(); } materials->Flush( true ); Shader_SwapBuffers(); stop = Sys_FloatTime (); time = stop-start; developer.SetValue( savedeveloper ); ConMsg ("%f seconds (%f fps)\n", time, 128/time); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_EnvStarfield::ClientThink( void ) { if ( !m_bOn || !m_flDensity ) return; PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" ); // Find a start & end point for the particle // Start particles straight ahead of the client Vector vecViewOrigin = MainViewOrigin(engine->GetActiveSplitScreenPlayerSlot()); // Determine the number of particles m_flNumParticles += 1.0 * (m_flDensity); int iNumParticles = floor(m_flNumParticles); m_flNumParticles -= iNumParticles; // Add particles for ( int i = 0; i < iNumParticles; i++ ) { float flDiameter = cl_starfield_diameter.GetFloat(); Vector vecStart = vecViewOrigin + (MainViewForward(engine->GetActiveSplitScreenPlayerSlot()) * cl_starfield_distance.GetFloat() ); Vector vecEnd = vecViewOrigin + (MainViewRight(engine->GetActiveSplitScreenPlayerSlot()) * RandomFloat(-flDiameter,flDiameter)) + (MainViewUp(engine->GetActiveSplitScreenPlayerSlot()) * RandomFloat(-flDiameter,flDiameter)); Vector vecDir = (vecEnd - vecStart); float flDistance = VectorNormalize( vecDir ); float flTravelTime = 2.0; // Start a random amount along the path vecStart += vecDir * ( RandomFloat(0.1,0.3) * flDistance ); TrailParticle *pParticle = (TrailParticle *) m_pEmitter->AddParticle( sizeof(TrailParticle), hParticleMaterial, vecStart ); if ( pParticle ) { pParticle->m_vecVelocity = vecDir * (flDistance / flTravelTime); pParticle->m_flDieTime = flTravelTime; pParticle->m_flLifetime = 0; pParticle->m_flWidth = RandomFloat( 1, 3 ); pParticle->m_flLength = RandomFloat( 0.05, 0.4 ); pParticle->m_color.r = 255; pParticle->m_color.g = 255; pParticle->m_color.b = 255; pParticle->m_color.a = 255; } } }
//----------------------------------------------------------------------------- // Purpose: // Input : updateType - //----------------------------------------------------------------------------- void C_EnvStarfield::OnDataChanged( DataUpdateType_t updateType ) { if ( updateType == DATA_UPDATE_CREATED ) { m_pEmitter = CTrailParticles::Create( "EnvStarfield" ); Vector vecCenter = MainViewOrigin(engine->GetActiveSplitScreenPlayerSlot()) + (MainViewForward(engine->GetActiveSplitScreenPlayerSlot()) * cl_starfield_distance.GetFloat() ); m_pEmitter->Setup( (Vector &) vecCenter, NULL, 0.0, 0, 64, 0, 0, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN | bitsPARTICLE_TRAIL_FADE | bitsPARTICLE_TRAIL_FADE_IN ); // Start thinking SetNextClientThink( CLIENT_THINK_ALWAYS ); } BaseClass::OnDataChanged( updateType ); }
void CDistanceMeter::Paint( void ) { int nShowDist = cl_showdist.GetInt(); if ( !nShowDist ) return; BaseClass::Paint(); int vx, vy, vw, vh; vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); // Draw it to the left and above the center of the screen. int x = ( vw / 2 ) + 20; int y = ( vh / 2 ) - 20; // Calculate the distance from player's eyes to his aiming point. Vector vecSrc, vecDir, vecEnd; vecSrc = MainViewOrigin(); vecDir = MainViewForward(); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( nShowDist == 2 ) { if ( pPlayer ) { pPlayer->EyePositionAndVectors( &vecSrc, &vecDir, NULL, NULL ); } } vecEnd = vecSrc + vecDir * MAX_TRACE_LENGTH; trace_t tr; UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); vecDir = tr.endpos - vecSrc; g_pMatSystemSurface->DrawColoredText( m_hFont, x, y, 255, 255, 255, 255, "%.02f", vecDir.Length() ); }
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(); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void FX_TFTracerSound( const Vector &start, const Vector &end, int iTracerType ) { // don't play on very short hits if ( ( start - end ).Length() < 200 ) return; const char *pszSoundName = "Bullets.DefaultNearmiss"; float flWhizDist = 64; Vector vecListenOrigin = MainViewOrigin(); switch( iTracerType ) { case TRACER_TYPE_DEFAULT: flWhizDist = 96; // fall through ! default: { Ray_t bullet, listener; bullet.Init( start, end ); Vector vecLower = vecListenOrigin; vecLower.z -= LISTENER_HEIGHT; listener.Init( vecListenOrigin, vecLower ); float s, t; IntersectRayWithRay( bullet, listener, s, t ); t = clamp( t, 0, 1 ); vecListenOrigin.z -= t * LISTENER_HEIGHT; } break; } static float flNextWhizTime = 0; // Is it time yet? float dt = flNextWhizTime - gpGlobals->curtime; if ( dt > 0 ) return; // Did the thing pass close enough to our head? float vDist = CalcDistanceSqrToLineSegment( vecListenOrigin, start, end ); if ( vDist >= (flWhizDist * flWhizDist) ) return; CSoundParameters params; if( C_BaseEntity::GetParametersForSound( pszSoundName, params, NULL ) ) { // Get shot direction Vector shotDir; VectorSubtract( end, start, shotDir ); VectorNormalize( shotDir ); CLocalPlayerFilter filter; enginesound->EmitSound( filter, SOUND_FROM_WORLD, CHAN_STATIC, params.soundname, params.volume, SNDLVL_TO_ATTN(params.soundlevel), 0, params.pitch, 0, &start, &shotDir, false); } // Don't play another bullet whiz for this client until this time has run out flNextWhizTime = gpGlobals->curtime + 0.1f; }
//----------------------------------------------------------------------------- // Purpose: // Input : timeDelta - //----------------------------------------------------------------------------- void C_Flare::Update( float timeDelta ) { if ( !IsVisible() ) return; CSimpleEmitter::Update( timeDelta ); //Make sure our stored resources are up to date RestoreResources(); //Don't do this if the console is down if ( timeDelta <= 0.0f ) return; //Check for LOS pixelvis_queryparams_t params; params.Init(GetAbsOrigin()); params.proxySize = 8.0f; // Inches float visible = PixelVisibility_FractionVisible( params, &m_queryHandle ); float fColor; #ifdef HL2_CLIENT_DLL float baseScale = m_flScale; #else // NOTE!!! This is bigger by a factor of 1.2 to deal with fixing a bug from HL2. See dlight_t.h float baseScale = m_flScale * 1.2f; #endif //Account for fading out if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) ) { baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f ); } bool bVisible = (baseScale < 0.01f || visible == 0.0f) ? false : true; //Clamp the scale if vanished if ( !bVisible ) { if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_flDieTime = gpGlobals->curtime; m_pParticle[0]->m_uchStartSize = m_pParticle[0]->m_uchEndSize = 0; m_pParticle[0]->m_uchColor[0] = 0; m_pParticle[0]->m_uchColor[1] = 0; m_pParticle[0]->m_uchColor[2] = 0; } if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_flDieTime = gpGlobals->curtime; m_pParticle[1]->m_uchStartSize = m_pParticle[1]->m_uchEndSize = 0; m_pParticle[1]->m_uchColor[0] = 0; m_pParticle[1]->m_uchColor[1] = 0; m_pParticle[1]->m_uchColor[2] = 0; } } if ( baseScale < 0.01f ) return; // // Dynamic light // if ( m_bLight ) { dlight_t *dl= effects->CL_AllocDlight( index ); if ( m_bPropFlare == false ) { dl->origin = GetAbsOrigin(); dl->color.r = 255; dl->die = gpGlobals->curtime + 0.1f; dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f ); dl->color.g = dl->color.b = random->RandomInt( 32, 64 ); } else { if ( m_iAttachment == -1 ) { m_iAttachment = LookupAttachment( "fuse" ); } if ( m_iAttachment != -1 ) { Vector effect_origin; QAngle effect_angles; GetAttachment( m_iAttachment, effect_origin, effect_angles ); //Raise the light a little bit away from the flare so it lights it up better. dl->origin = effect_origin + Vector( 0, 0, 4 ); dl->color.r = 255; dl->die = gpGlobals->curtime + 0.1f; dl->radius = baseScale * random->RandomFloat( 245.0f, 256.0f ); dl->color.g = dl->color.b = random->RandomInt( 95, 128 ); dlight_t *el= effects->CL_AllocElight( index ); el->origin = effect_origin; el->color.r = 255; el->color.g = dl->color.b = random->RandomInt( 95, 128 ); el->radius = baseScale * random->RandomFloat( 260.0f, 290.0f ); el->die = gpGlobals->curtime + 0.1f; } } } // // Smoke // float dt = timeDelta; if ( m_bSmoke ) { while ( m_teSmokeSpawn.NextEvent( dt ) ) { Vector smokeOrg = GetAbsOrigin(); Vector flareScreenDir = ( smokeOrg - MainViewOrigin() ); VectorNormalize( flareScreenDir ); smokeOrg = smokeOrg + ( flareScreenDir * 2.0f ); smokeOrg[2] += baseScale * 4.0f; SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg ); if ( sParticle == NULL ) return; sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 1.0f; sParticle->m_vecVelocity = Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f ); if ( m_bPropFlare ) { sParticle->m_uchColor[0] = 255; sParticle->m_uchColor[1] = 100; sParticle->m_uchColor[2] = 100; } else { sParticle->m_uchColor[0] = 255; sParticle->m_uchColor[1] = 48; sParticle->m_uchColor[2] = 48; } sParticle->m_uchStartAlpha = random->RandomInt( 64, 90 ); sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomInt( 2, 4 ); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 8.0f; sParticle->m_flRoll = random->RandomInt( 0, 2*M_PI ); sParticle->m_flRollDelta = random->RandomFloat( -(M_PI/6.0f), M_PI/6.0f ); } } if ( !bVisible ) return; // // Outer glow // Vector offset; //Cause the base of the effect to shake offset.Random( -0.5f * baseScale, 0.5f * baseScale ); offset += GetAbsOrigin(); if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_Pos = offset; m_pParticle[0]->m_flLifetime = 0.0f; m_pParticle[0]->m_flDieTime = 2.0f; m_pParticle[0]->m_vecVelocity.Init(); fColor = random->RandomInt( 100.0f, 128.0f ) * visible; m_pParticle[0]->m_uchColor[0] = fColor; m_pParticle[0]->m_uchColor[1] = fColor; m_pParticle[0]->m_uchColor[2] = fColor; m_pParticle[0]->m_uchStartAlpha = fColor; m_pParticle[0]->m_uchEndAlpha = fColor; m_pParticle[0]->m_uchStartSize = baseScale * (float) random->RandomInt( 32, 48 ); m_pParticle[0]->m_uchEndSize = m_pParticle[0]->m_uchStartSize; m_pParticle[0]->m_flRollDelta = 0.0f; if ( random->RandomInt( 0, 4 ) == 3 ) { m_pParticle[0]->m_flRoll += random->RandomInt( 2, 8 ); } } // // Inner core // //Cause the base of the effect to shake offset.Random( -1.0f * baseScale, 1.0f * baseScale ); offset += GetAbsOrigin(); if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_Pos = offset; m_pParticle[1]->m_flLifetime = 0.0f; m_pParticle[1]->m_flDieTime = 2.0f; m_pParticle[1]->m_vecVelocity.Init(); fColor = 255 * visible; m_pParticle[1]->m_uchColor[0] = fColor; m_pParticle[1]->m_uchColor[1] = fColor; m_pParticle[1]->m_uchColor[2] = fColor; m_pParticle[1]->m_uchStartAlpha = fColor; m_pParticle[1]->m_uchEndAlpha = fColor; m_pParticle[1]->m_uchStartSize = baseScale * (float) random->RandomInt( 2, 4 ); m_pParticle[1]->m_uchEndSize = m_pParticle[0]->m_uchStartSize; m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 ); } }
void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType ) { const char *pszSoundName = NULL; float flWhizDist = TRACER_MAX_HEAR_DIST; float flMinWhizTime = TRACER_SOUND_TIME_MIN; float flMaxWhizTime = TRACER_SOUND_TIME_MAX; Vector vecListenOrigin = MainViewOrigin(); switch( iTracerType ) { case TRACER_TYPE_DEFAULT: { pszSoundName = "Bullets.DefaultNearmiss"; flWhizDist = 24; Ray_t bullet, listener; bullet.Init( start, end ); Vector vecLower = vecListenOrigin; vecLower.z -= LISTENER_HEIGHT; listener.Init( vecListenOrigin, vecLower ); float s, t; IntersectRayWithRay( bullet, listener, s, t ); t = clamp( t, 0, 1 ); vecListenOrigin.z -= t * LISTENER_HEIGHT; } break; case TRACER_TYPE_GUNSHIP: pszSoundName = "Bullets.GunshipNearmiss"; break; case TRACER_TYPE_STRIDER: pszSoundName = "Bullets.StriderNearmiss"; break; case TRACER_TYPE_WATERBULLET: pszSoundName = "Underwater.BulletImpact"; flWhizDist = 48; flMinWhizTime = 0.3f; flMaxWhizTime = 0.6f; break; default: return; } if( !pszSoundName ) return; // Is it time yet? float dt = g_BulletWhiz.m_nextWhizTime - gpGlobals->curtime; if ( dt > 0 ) return; // Did the thing pass close enough to our head? float vDist = CalcDistanceSqrToLineSegment( vecListenOrigin, start, end ); if ( vDist >= (flWhizDist * flWhizDist) ) return; CSoundParameters params; if( C_BaseEntity::GetParametersForSound( pszSoundName, params, NULL ) ) { // Get shot direction Vector shotDir; VectorSubtract( end, start, shotDir ); VectorNormalize( shotDir ); CLocalPlayerFilter filter; enginesound->EmitSound( filter, SOUND_FROM_WORLD, CHAN_STATIC, params.soundname, params.volume, SNDLVL_TO_ATTN(params.soundlevel), 0, params.pitch, &start, &shotDir, false); } // FIXME: This has a bad behavior when both bullet + strider shots are whizzing by at the same time // Could use different timers for the different types. // Don't play another bullet whiz for this client until this time has run out g_BulletWhiz.m_nextWhizTime = gpGlobals->curtime + random->RandomFloat( flMinWhizTime, flMaxWhizTime ); }
//----------------------------------------------------------------------------- // Purpose: Intercepts the blood spray message. //----------------------------------------------------------------------------- void TFBloodSprayCallback( Vector vecOrigin, Vector vecNormal, ClientEntityHandle_t hEntity ) { QAngle vecAngles; VectorAngles( -vecNormal, vecAngles ); // determine if the bleeding player is underwater bool bUnderwater = false; C_TFPlayer *pPlayer = dynamic_cast<C_TFPlayer*>( ClientEntityList().GetBaseEntityFromHandle( hEntity ) ); if ( pPlayer && ( WL_Eyes == pPlayer->GetWaterLevel() ) ) { bUnderwater = true; } if ( !bUnderwater && TFGameRules() && TFGameRules()->IsBirthday() && RandomFloat(0,1) < 0.2 ) { DispatchParticleEffect( "bday_blood", vecOrigin, vecAngles, pPlayer ); } else { DispatchParticleEffect( bUnderwater ? "water_blood_impact_red_01" : "blood_impact_red_01", vecOrigin, vecAngles, pPlayer ); } // if underwater, don't add additional spray if ( bUnderwater ) return; // Now throw out a spray away from the view // Get the distance to the view float flDistance = (vecOrigin - MainViewOrigin()).Length(); float flLODDistance = 0.25 * (flDistance / 512); Vector right, up; if (vecNormal != Vector(0, 0, 1) ) { right = vecNormal.Cross( Vector(0, 0, 1) ); up = right.Cross( vecNormal ); } else { right = Vector(0, 0, 1); up = right.Cross( vecNormal ); } // If the normal's too close to being along the view, push it out Vector vecForward, vecRight; AngleVectors( MainViewAngles(), &vecForward, &vecRight, NULL ); float flDot = DotProduct( vecNormal, vecForward ); if ( fabs(flDot) > 0.5 ) { float flPush = random->RandomFloat(0.5, 1.5) + flLODDistance; float flRightDot = DotProduct( vecNormal, vecRight ); // If we're up close, randomly move it around. If we're at a distance, always push it to the side // Up close, this can move it back towards the view, but the random chance still looks better if ( ( flDistance >= 512 && flRightDot > 0 ) || ( flDistance < 512 && RandomFloat(0,1) > 0.5 ) ) { // Turn it to the right vecNormal += (vecRight * flPush); } else { // Turn it to the left vecNormal -= (vecRight * flPush); } } VectorAngles( vecNormal, vecAngles ); if ( flDistance < 400 ) { DispatchParticleEffect( "blood_spray_red_01", vecOrigin, vecAngles, pPlayer ); } else { DispatchParticleEffect( "blood_spray_red_01_far", vecOrigin, vecAngles, pPlayer ); } }
void C_FuncSmokeVolume::Update( float fTimeDelta ) { // Update our world space bbox if we've moved at all. // We do this manually because sometimes people make HUGE bboxes, and if they're constantly changing because their // particles wander outside the current bounds sometimes, it'll be linking them into all the leaves repeatedly. const Vector &curOrigin = GetAbsOrigin(); const QAngle &curAngles = GetAbsAngles(); if ( !VectorsAreEqual( curOrigin, m_vLastOrigin, 0.1 ) || fabs( curAngles.x - m_vLastAngles.x ) > 0.1 || fabs( curAngles.y - m_vLastAngles.y ) > 0.1 || fabs( curAngles.z - m_vLastAngles.z ) > 0.1 || m_bFirstUpdate ) { m_bFirstUpdate = false; m_vLastAngles = curAngles; m_vLastOrigin = curOrigin; Vector vWorldMins, vWorldMaxs; CollisionProp()->WorldSpaceAABB( &vWorldMins, &vWorldMaxs ); vWorldMins -= Vector( m_ParticleRadius, m_ParticleRadius, m_ParticleRadius ); vWorldMaxs += Vector( m_ParticleRadius, m_ParticleRadius, m_ParticleRadius ); m_ParticleEffect.SetBBox( vWorldMins, vWorldMaxs ); } float minViewOrigingDistance = FLT_MAX; FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh ) { float d = CollisionProp()->CalcDistanceFromPoint( MainViewOrigin(hh) ); if ( d < minViewOrigingDistance ) minViewOrigingDistance = d; } float targetDensity = m_Density; if ( m_maxDrawDistance > 0 && minViewOrigingDistance > m_maxDrawDistance ) { targetDensity = 0.0f; } // lerp m_CurrentDensity towards m_Density at a rate of m_DensityRampSpeed if( m_CurrentDensity < targetDensity ) { m_CurrentDensity += m_DensityRampSpeed * fTimeDelta; if( m_CurrentDensity > targetDensity ) { m_CurrentDensity = targetDensity; } } else if( m_CurrentDensity > targetDensity ) { m_CurrentDensity -= m_DensityRampSpeed * fTimeDelta; if( m_CurrentDensity < targetDensity ) { m_CurrentDensity = targetDensity; } } if( m_CurrentDensity == 0.0f ) { return; } // This is used to randomize the direction it chooses to move a particle in. int offsetLookup[3] = {-1,0,1}; float tradeDurationMax = m_ParticleSpacingDistance / ( m_MovementSpeed + 0.1f ); float tradeDurationMin = tradeDurationMax * 0.5f; if ( IS_NAN( tradeDurationMax ) || IS_NAN( tradeDurationMin ) ) return; // Warning( "tradeDuration: [%f,%f]\n", tradeDurationMin, tradeDurationMax ); // Update all the moving traders and establish new ones. int nTotal = m_xCount * m_yCount * m_zCount; for( int i=0; i < nTotal; i++ ) { SmokeParticleInfo *pInfo = &m_pSmokeParticleInfos[i]; if(!pInfo->m_pParticle) continue; if(pInfo->m_TradeIndex == -1) { pInfo->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha; pInfo->m_pParticle->m_Color[0] = pInfo->m_Color[0]; pInfo->m_pParticle->m_Color[1] = pInfo->m_Color[1]; pInfo->m_pParticle->m_Color[2] = pInfo->m_Color[2]; // Is there an adjacent one that's not trading? int x, y, z; GetParticleInfoXYZ(i, x, y, z); int xCountOffset = rand(); int yCountOffset = rand(); int zCountOffset = rand(); bool bFound = false; for(int xCount=0; xCount < 3 && !bFound; xCount++) { for(int yCount=0; yCount < 3 && !bFound; yCount++) { for(int zCount=0; zCount < 3; zCount++) { int testX = x + offsetLookup[(xCount+xCountOffset) % 3]; int testY = y + offsetLookup[(yCount+yCountOffset) % 3]; int testZ = z + offsetLookup[(zCount+zCountOffset) % 3]; if(testX == x && testY == y && testZ == z) continue; if(IsValidXYZCoords(testX, testY, testZ)) { SmokeParticleInfo *pOther = GetSmokeParticleInfo(testX, testY, testZ); if(pOther->m_pParticle && pOther->m_TradeIndex == -1) { // Ok, this one is looking to trade also. pInfo->m_TradeIndex = GetSmokeParticleIndex(testX, testY, testZ); pOther->m_TradeIndex = i; pInfo->m_TradeClock = pOther->m_TradeClock = 0; pOther->m_TradeDuration = pInfo->m_TradeDuration = FRand( tradeDurationMin, tradeDurationMax ); bFound = true; break; } } } } } } else { SmokeParticleInfo *pOther = &m_pSmokeParticleInfos[pInfo->m_TradeIndex]; assert(pOther->m_TradeIndex == i); // This makes sure the trade only gets updated once per frame. if(pInfo < pOther) { // Increment the trade clock.. pInfo->m_TradeClock = (pOther->m_TradeClock += fTimeDelta); int x, y, z; GetParticleInfoXYZ(i, x, y, z); Vector myPos = GetSmokeParticlePos(x, y, z); int otherX, otherY, otherZ; GetParticleInfoXYZ(pInfo->m_TradeIndex, otherX, otherY, otherZ); Vector otherPos = GetSmokeParticlePos(otherX, otherY, otherZ); // Is the trade finished? if(pInfo->m_TradeClock >= pInfo->m_TradeDuration) { pInfo->m_TradeIndex = pOther->m_TradeIndex = -1; pInfo->m_pParticle->m_Pos = otherPos; pOther->m_pParticle->m_Pos = myPos; SmokeGrenadeParticle *temp = pInfo->m_pParticle; pInfo->m_pParticle = pOther->m_pParticle; pOther->m_pParticle = temp; } else { // Ok, move them closer. float percent = (float)cos(pInfo->m_TradeClock * 2 * 1.57079632f / pInfo->m_TradeDuration); percent = percent * 0.5 + 0.5; pInfo->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha + (pOther->m_FadeAlpha - pInfo->m_FadeAlpha) * (1 - percent); pOther->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha + (pOther->m_FadeAlpha - pInfo->m_FadeAlpha) * percent; InterpColor(pInfo->m_pParticle->m_Color, pInfo->m_Color, pOther->m_Color, 1-percent); InterpColor(pOther->m_pParticle->m_Color, pInfo->m_Color, pOther->m_Color, percent); pInfo->m_pParticle->m_Pos = myPos + (otherPos - myPos) * (1 - percent); pOther->m_pParticle->m_Pos = myPos + (otherPos - myPos) * percent; } } } } }
void CMumbleSystem::PostRender() { #ifndef NO_STEAM if ( !g_pMumbleMemory || !sv_mumble_positionalaudio.GetBool() ) return; if ( g_pMumbleMemory->uiVersion != 2 ) { V_wcscpy_safe( g_pMumbleMemory->name, L"Source engine: " ); wchar_t wcsGameDir[MAX_PATH]; Q_UTF8ToUnicode( COM_GetModDirectory(), wcsGameDir, sizeof(wcsGameDir) ); V_wcscat_safe( g_pMumbleMemory->name, wcsGameDir ); V_wcscpy_safe( g_pMumbleMemory->description, L"Links Source engine games to Mumble." ); g_pMumbleMemory->uiVersion = 2; } g_pMumbleMemory->uiTick++; Vector vecOriginPlayer, vecOriginCamera = MainViewOrigin(); QAngle anglesPlayer, anglesCamera = MainViewAngles(); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { vecOriginPlayer = pPlayer->EyePosition(); anglesPlayer = pPlayer->GetAbsAngles(); } else { vecOriginPlayer = vecOriginCamera; anglesPlayer = anglesCamera; } anglesPlayer.x = 0; Vector vecPlayerForward, vecPlayerUp, vecCameraForward, vecCameraUp; AngleVectors( anglesPlayer, &vecPlayerForward, NULL, &vecPlayerUp ); AngleVectors( anglesCamera, &vecCameraForward, NULL, &vecCameraUp ); // 1 Source unit is about one inch // 1 mumble unit = 1 meter vecOriginPlayer *= METERS_PER_INCH; vecOriginCamera *= METERS_PER_INCH; VectorToMumbleFloatArray( vecPlayerForward, g_pMumbleMemory->fAvatarFront ); VectorToMumbleFloatArray( vecPlayerUp, g_pMumbleMemory->fAvatarTop ); VectorToMumbleFloatArray( vecOriginPlayer, g_pMumbleMemory->fAvatarPosition ); VectorToMumbleFloatArray( vecCameraForward, g_pMumbleMemory->fCameraFront ); VectorToMumbleFloatArray( vecCameraUp, g_pMumbleMemory->fCameraTop ); VectorToMumbleFloatArray( vecOriginCamera, g_pMumbleMemory->fCameraPosition ); if ( pPlayer && m_bHasSetPlayerUniqueId && m_nTeamSetInUniqueId != pPlayer->GetTeamNumber() ) { // Player changed team since we set the unique ID. Set it again. m_bHasSetPlayerUniqueId = false; } if ( !m_bHasSetPlayerUniqueId && steamapicontext && steamapicontext->SteamUser() ) { CSteamID steamid = steamapicontext->SteamUser()->GetSteamID(); if ( steamid.IsValid() ) { int unTeam = pPlayer ? pPlayer->GetTeamNumber() : 0; char szSteamId[256]; V_sprintf_safe( szSteamId, "universe:%u;account_type:%u;id:%u;instance:%u;team:%d", steamid.GetEUniverse(), steamid.GetEAccountType(), steamid.GetAccountID(), steamid.GetUnAccountInstance(), unTeam ); wchar_t wcsSteamId[256]; Q_UTF8ToUnicode( szSteamId, wcsSteamId, sizeof(wcsSteamId) ); // Identifier which uniquely identifies a certain player in a context. V_wcscpy_safe( g_pMumbleMemory->identity, wcsSteamId ); m_bHasSetPlayerUniqueId = true; m_nTeamSetInUniqueId = unTeam; } } // Context should be equal for players which should be able to hear each other positional and // differ for those who shouldn't (e.g. it could contain the server+port and team) memcpy( g_pMumbleMemory->context, &m_szSteamIDCurrentServer, m_cubSteamIDCurrentServer ); g_pMumbleMemory->context_len = m_cubSteamIDCurrentServer; #endif // NO_STEAM }