int C_BeamQuadratic::DrawModel( int ) { Vector points[3]; QAngle tmpAngle; if ( !m_active ) return 0; C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_viewModelIndex ); if ( !pEnt ) return 0; pEnt->GetAttachment( 1, points[0], tmpAngle ); points[1] = 0.5 * (m_targetPosition + points[0]); // a little noise 11t & 13t should be somewhat non-periodic looking //points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 ); points[2] = m_worldPosition; IMaterial *pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS ); Vector color; if ( m_glueTouching ) { color.Init(1,0,0); } else { color.Init(1,1,1); } float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime; materials->Bind( pMat ); DrawBeamQuadratic( points[0], points[1], points[2], 13, color, scrollOffset ); return 1; }
//----------------------------------------------------------------------------- // Purpose: Gets the attachment point to spawn at //----------------------------------------------------------------------------- void C_ParticleTrail::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles ) { C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity(); if ( pEnt && (m_nAttachment > 0) ) { pEnt->GetAttachment( m_nAttachment, *pAbsOrigin, *pAbsAngles ); return; } BaseClass::GetAimEntOrigin( pAttachedTo, pAbsOrigin, pAbsAngles ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CSprite::GetToolRecordingState( KeyValues *msg ) { if ( !ToolsEnabled() ) return; VPROF_BUDGET( "CSprite::GetToolRecordingState", VPROF_BUDGETGROUP_TOOLS ); BaseClass::GetToolRecordingState( msg ); // Use attachment point if ( m_hAttachedToEntity ) { C_BaseEntity *ent = m_hAttachedToEntity->GetBaseEntity(); if ( ent ) { BaseEntityRecordingState_t *pState = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" ); // override position if we're driven by an attachment QAngle temp; pState->m_vecRenderOrigin = GetAbsOrigin(); ent->GetAttachment( m_nAttachment, pState->m_vecRenderOrigin, temp ); // override viewmodel if we're driven by an attachment bool bViewModel = ToBaseViewModel( ent ) != NULL; msg->SetInt( "viewmodel", bViewModel ); } } float renderscale = GetRenderScale(); if ( m_bWorldSpaceScale ) { CEngineSprite *psprite = ( CEngineSprite * )modelinfo->GetModelExtraData( GetModel() ); float flMinSize = MIN( psprite->GetWidth(), psprite->GetHeight() ); renderscale /= flMinSize; } color24 c = GetRenderColor(); // sprite params static SpriteRecordingState_t state; state.m_flRenderScale = renderscale; state.m_flFrame = m_flFrame; state.m_flProxyRadius = m_flGlowProxySize; state.m_nRenderMode = GetRenderMode(); state.m_nRenderFX = GetRenderFX() ? true : false; state.m_Color.SetColor( c.r, c.g, c.b, GetRenderBrightness() ); msg->SetPtr( "sprite", &state ); }
//----------------------------------------------------------------------------- // Returns the attachment render origin + origin //----------------------------------------------------------------------------- void C_VGuiScreen::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pOrigin, QAngle *pAngles ) { C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity(); if (pEnt && (m_nAttachmentIndex > 0)) { pEnt->GetAttachment( m_nAttachmentIndex, *pOrigin, *pAngles ); if ( IsAttachedToViewModel() ) { FormatViewModelAttachment( *pOrigin, true ); } } else { BaseClass::GetAimEntOrigin( pAttachedTo, pOrigin, pAngles ); } }
//----------------------------------------------------------------------------- // Purpose: // Output : Vector const& //----------------------------------------------------------------------------- const Vector &CSpriteTrail::GetRenderOrigin( void ) { static Vector vOrigin; vOrigin = GetAbsOrigin(); if ( m_hAttachedToEntity ) { C_BaseEntity *ent = m_hAttachedToEntity->GetBaseEntity(); if ( ent ) { QAngle dummyAngles; ent->GetAttachment( m_nAttachment, vOrigin, dummyAngles ); } } return vOrigin; }
//----------------------------------------------------------------------------- // Returns the attachment render origin + origin //----------------------------------------------------------------------------- void C_VGuiScreen::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pOrigin, QAngle *pAngles ) { C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity(); const char* panelName = PanelName(); vgui::Panel panel = m_PanelWrapper.GetPanel(); if ( Q_strcmp(panelName, "health_screen") == 0 ) { QAngle weapAngles = pEnt->GetAbsAngles(); Vector weapForward, weapRight, weapUp; AngleVectors(weapAngles, &weapForward, &weapRight, &weapUp); VMatrix worldFromPanel; AngleMatrix(weapAngles, worldFromPanel.As3x4()); MatrixRotate(worldFromPanel, Vector(0, 0, 1), 180.f); MatrixRotate(worldFromPanel, Vector(1, 0, 0), -90.f); MatrixAngles(worldFromPanel.As3x4(), *pAngles); // move it right and over *pOrigin = pEnt->GetAbsOrigin() + weapRight*1.75 + weapUp*2.3 + weapForward*5; return; } //todo: set alpha per view ... m_PanelWrapper.GetPanel()->SetAlpha(200); if (pEnt && (m_nAttachmentIndex > 0)) { { C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, true ); pEnt->GetAttachment( m_nAttachmentIndex, *pOrigin, *pAngles ); } if ( IsAttachedToViewModel() ) { FormatViewModelAttachment( *pOrigin, true ); } } else { BaseClass::GetAimEntOrigin( pAttachedTo, pOrigin, pAngles ); } // Msg("%s origin %.1f %.1f %.1f angles %.1f %.1f %.1f \n", PanelName(), pOrigin->x, pOrigin->y, pOrigin->z, pAngles->x, pAngles->y, pAngles->z); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Vector GetTracerOrigin( const CEffectData &data ) { Vector vecStart = data.m_vStart; QAngle vecAngles; int iEntIndex = data.m_nEntIndex; // Attachment? if ( data.m_fFlags & TRACER_FLAG_USEATTACHMENT ) { int iAttachment = data.m_vStart[0]; C_BaseViewModel *pViewModel = NULL; // If the entity specified is a weapon being carried by this player, use the viewmodel instead C_BaseEntity *pEnt = ClientEntityList().GetEnt( iEntIndex ); if ( !pEnt ) return vecStart; C_BaseCombatWeapon *pWpn = dynamic_cast<C_BaseCombatWeapon *>(pEnt); if ( pWpn && pWpn->IsCarriedByLocalPlayer() ) { C_BasePlayer *player = ToBasePlayer( pWpn->GetOwner() ); pViewModel = player ? player->GetViewModel( 0 ) : NULL; if ( pViewModel ) { // Get the viewmodel and use it instead pEnt = pViewModel; } } // Get the attachment origin if ( !pEnt->GetAttachment( iAttachment, vecStart, vecAngles ) ) { Msg( "GetTracerOrigin: Couldn't find attachment %d on model %s\n", iAttachment, pEnt->GetModelName() ); } } return vecStart; }
void C_NEOPlayer::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov ) { C_BaseEntity* ragdoll = m_hRagdoll.Get(); if ( m_lifeState != LIFE_ALIVE && ragdoll && m_bIsOnDeathScreen ) { int attachment = ragdoll->LookupAttachment( "eyes" ); if ( !attachment ) return; Vector origin; QAngle angles; if ( !ragdoll->GetAttachment( attachment, origin, angles ) ) return; Vector forward; AngleVectors( angles, &forward ); Vector start; start = forward; start.z += 64.f; trace_t trace; UTIL_TraceHull( start, forward, -Vector( 12, 12, 12 ), Vector( 12, 12, 12 ), CONTENTS_MOVEABLE | CONTENTS_GRATE | CONTENTS_AUX | CONTENTS_WINDOW | CONTENTS_SOLID, this, 0, &trace ); if ( trace.fraction < 1.f ) forward = trace.endpos; if ( gpGlobals->curtime >= (m_fRagdollCreationTime + 10.f) ) m_bIsOnDeathScreen = false; } // The original game has a check for mobile armor in here else BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov ); }
//----------------------------------------------------------------------------- // Purpose: Return the origin & angles for a projectile fired from the player's gun //----------------------------------------------------------------------------- void CTFWeaponBaseGun::GetProjectileFireSetup( CTFPlayer *pPlayer, Vector vecOffset, Vector *vecSrc, QAngle *angForward, bool bHitTeammates /* = true */ ) { Vector vecForward, vecRight, vecUp; AngleVectors( pPlayer->EyeAngles(), &vecForward, &vecRight, &vecUp ); Vector vecShootPos = pPlayer->Weapon_ShootPosition(); // Estimate end point Vector endPos = vecShootPos + vecForward * 2000; // Trace forward and find what's in front of us, and aim at that trace_t tr; if ( bHitTeammates ) { CTraceFilterSimple filter( pPlayer, COLLISION_GROUP_NONE ); UTIL_TraceLine( vecShootPos, endPos, MASK_SOLID, &filter, &tr ); } else { CTraceFilterIgnoreTeammates filter( pPlayer, COLLISION_GROUP_NONE, pPlayer->GetTeamNumber() ); UTIL_TraceLine( vecShootPos, endPos, MASK_SOLID, &filter, &tr ); } #ifndef CLIENT_DLL // Offset actual start point *vecSrc = vecShootPos + (vecForward * vecOffset.x) + (vecRight * vecOffset.y) + (vecUp * vecOffset.z); #else // If we're seeing another player shooting the projectile, move their start point to the weapon origin if ( pPlayer ) { C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pLocalPlayer != pPlayer || ::input->CAM_IsThirdPerson() ) { if ( pPlayer->GetActiveWeapon() ) { pPlayer->GetActiveWeapon()->GetAttachment( "muzzle", *vecSrc ); } } else { C_BaseEntity *pViewModel = pLocalPlayer->GetViewModel(); if ( pViewModel ) { QAngle vecAngles; int iMuzzleFlashAttachment = pViewModel->LookupAttachment( "muzzle" ); pViewModel->GetAttachment( iMuzzleFlashAttachment, *vecSrc, vecAngles ); Vector vForward; AngleVectors( vecAngles, &vForward ); trace_t trace; UTIL_TraceLine( *vecSrc + vForward * -50, *vecSrc, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &trace ); *vecSrc = trace.endpos; } } } #endif // Find angles that will get us to our desired end point // Only use the trace end if it wasn't too close, which results // in visually bizarre forward angles if ( tr.fraction > 0.1 ) { VectorAngles( tr.endpos - *vecSrc, *angForward ); } else { VectorAngles( endPos - *vecSrc, *angForward ); } }
//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int C_SpriteRenderer::DrawSprite( IClientEntity *entity, const model_t *model, const Vector& origin, const QAngle& angles, float frame, IClientEntity *attachedto, int attachmentindex, int rendermode, int renderfx, int alpha, int r, int g, int b, float scale, float flHDRColorScale ) { VPROF_BUDGET( "C_SpriteRenderer::DrawSprite", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( !r_drawsprites.GetBool() || !model || modelinfo->GetModelType( model ) != mod_sprite ) { return 0; } // Get extra data CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData( model ); if ( !psprite ) { return 0; } Vector effect_origin; VectorCopy( origin, effect_origin ); // Use attachment point if ( attachedto ) { C_BaseEntity *ent = attachedto->GetBaseEntity(); if ( ent ) { // don't draw viewmodel effects in reflections if ( CurrentViewID() == VIEW_REFLECTION ) { if ( g_pClientLeafSystem->IsRenderingWithViewModels( ent->RenderHandle() ) ) return 0; } QAngle temp; ent->GetAttachment( attachmentindex, effect_origin, temp ); } } if ( rendermode != kRenderNormal ) { float blend = render->GetBlend(); // kRenderGlow and kRenderWorldGlow have a special blending function if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow )) { blend *= GlowBlend( psprite, effect_origin, rendermode, renderfx, alpha, &scale ); // Fade out the sprite depending on distance from the view origin. r *= blend; g *= blend; b *= blend; } render->SetBlend( blend ); if ( blend <= 0.0f ) { return 0; } } // Get orthonormal basis Vector forward, right, up; GetSpriteAxes( (SPRITETYPE)psprite->GetOrientation(), origin, angles, forward, right, up ); // Draw DrawSpriteModel( entity, psprite, effect_origin, scale, frame, rendermode, r, g, b, alpha, forward, right, up, flHDRColorScale ); return 1; }
//----------------------------------------------------------------------------- // Purpose: // Input : int - //----------------------------------------------------------------------------- int C_GunshipFX::DrawModel( int ) { static color32 white = {255,255,255,255}; Vector params[GUNSHIPFX_PARAMETERS]; bool hasParam[GUNSHIPFX_PARAMETERS]; if ( !m_active ) return 1; C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex ); if ( ent ) { QAngle angles; ent->GetAttachment( m_attachment, m_worldPosition, angles ); } Vector test; m_t += gpGlobals->frametime; if ( m_tMax > 0 ) { m_t = clamp( m_t, 0, m_tMax ); m_beamEndPosition = m_worldPosition; } float t = m_t; bool hasAny = false; memset( hasParam, 0, sizeof(hasParam) ); for ( int i = 0; i < GUNSHIPFX_PARAMETERS; i++ ) { hasParam[i] = g_GunshipCannonEnvelope.m_parameters[i].Interp( params[i], t ); hasAny = hasAny || hasParam[i]; } // draw the narrow beam if ( hasParam[GUNSHIPFX_NARROW_BEAM_COLOR] && hasParam[GUNSHIPFX_NARROW_BEAM_SIZE] ) { IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS ); float width = NARROW_BEAM_WIDTH * params[GUNSHIPFX_NARROW_BEAM_SIZE].x; color32 color; float bright = params[GUNSHIPFX_NARROW_BEAM_COLOR].x; ScaleColor( color, white, bright ); //Gunship_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color ); FX_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color ); } // glowy blue flare sprite if ( hasParam[GUNSHIPFX_FLARE_COLOR] && hasParam[GUNSHIPFX_FLARE_SIZE] ) { IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS ); float size = FLARE_SIZE * params[GUNSHIPFX_FLARE_SIZE].x; color32 color; float bright = params[GUNSHIPFX_FLARE_COLOR].x; ScaleColor( color, white, bright ); color.a = (int)(255 * params[GUNSHIPFX_DARKNESS].x); materials->Bind( pMat, (IClientRenderable*)this ); Gunship_DrawSprite( m_worldPosition, size, color, true ); } if ( hasParam[GUNSHIPFX_AFTERGLOW_COLOR] ) { // Muzzle effect dlight_t *dl = effects->CL_AllocDlight( m_entityIndex ); dl->origin = m_worldPosition; dl->color.r = 40*params[GUNSHIPFX_AFTERGLOW_COLOR].x; dl->color.g = 60*params[GUNSHIPFX_AFTERGLOW_COLOR].x; dl->color.b = 255*params[GUNSHIPFX_AFTERGLOW_COLOR].x; dl->color.exponent = 5; dl->radius = 128.0f; dl->die = gpGlobals->curtime + 0.001; } if ( m_t >= 4.0 && !hasAny ) { EffectShutdown(); } return 1; }
int C_StriderFX::DrawModel( int ) { static color32 white = {255,255,255,255}; Vector params[STRIDERFX_PARAMETERS]; bool hasParam[STRIDERFX_PARAMETERS]; if ( !m_active ) return 1; C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex ); if ( ent ) { QAngle angles; ent->GetAttachment( m_attachment, m_worldPosition, angles ); } // This forces time to drive from the main clock instead of being integrated per-draw below // that way the effect moves on even when culled for visibility if ( m_limitHitTime > 0 && m_tMax > 0 ) { float dt = m_limitHitTime - gpGlobals->curtime; if ( dt < 0 ) { dt = 0; } // if the clock needs to move, update it. if ( m_tMax - dt > m_t ) { m_t = m_tMax - dt; m_beamEndPosition = m_worldPosition; } } else { // don't have enough info to derive the time, integrate current frame time m_t += gpGlobals->frametime; if ( m_tMax > 0 ) { m_t = clamp( m_t, 0, m_tMax ); m_beamEndPosition = m_worldPosition; } } float t = m_t; bool hasAny = false; memset( hasParam, 0, sizeof(hasParam) ); for ( int i = 0; i < STRIDERFX_PARAMETERS; i++ ) { hasParam[i] = g_StriderCannonEnvelope.m_parameters[i].Interp( params[i], t ); hasAny = hasAny || hasParam[i]; } pixelvis_queryparams_t gunParams; gunParams.Init(m_worldPosition, 4.0f); float gunFractionVisible = PixelVisibility_FractionVisible( gunParams, &m_queryHandleGun ); bool gunVisible = gunFractionVisible > 0.0f ? true : false; // draw the narrow beam if ( hasParam[STRIDERFX_NARROW_BEAM_COLOR] && hasParam[STRIDERFX_NARROW_BEAM_SIZE] ) { IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS ); float width = NARROW_BEAM_WIDTH * params[STRIDERFX_NARROW_BEAM_SIZE].x; color32 color; float bright = params[STRIDERFX_NARROW_BEAM_COLOR].x; ScaleColor( color, white, bright ); Strider_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color ); } // draw the wide beam if ( hasParam[STRIDERFX_WIDE_BEAM_COLOR] && hasParam[STRIDERFX_WIDE_BEAM_SIZE] ) { IMaterial *pMat = materials->FindMaterial( "effects/blueblacklargebeam", TEXTURE_GROUP_CLIENT_EFFECTS ); float width = WIDE_BEAM_WIDTH * params[STRIDERFX_WIDE_BEAM_SIZE].x; color32 color; float bright = params[STRIDERFX_WIDE_BEAM_COLOR].x; ScaleColor( color, white, bright ); Vector wideBeamEnd = m_beamEndPosition; if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] ) { float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x; wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt); } Strider_DrawLine( wideBeamEnd, m_targetPosition, width, pMat, color ); } // after glow sprite bool updated = false; CMatRenderContextPtr pRenderContext( materials ); // warpy sprite bit if ( hasParam[STRIDERFX_WARP_SCALE] && !hasParam[STRIDERFX_BUBBLE_SIZE] && gunVisible ) { if ( !updated ) { updated = true; pRenderContext->Flush(); UpdateRefractTexture(); } IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS ); float size = WARP_SIZE; float refract = params[STRIDERFX_WARP_SCALE].x * WARP_REFRACT * gunFractionVisible; pRenderContext->Bind( pMat, (IClientRenderable*)this ); IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL ); pVar->SetFloatValue( refract ); Strider_DrawSprite( m_worldPosition, size, white ); } // darkening sprite // glowy blue flare sprite if ( hasParam[STRIDERFX_FLARE_COLOR] && hasParam[STRIDERFX_FLARE_SIZE] && hasParam[STRIDERFX_DARKNESS] && gunVisible ) { IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS ); float size = FLARE_SIZE * params[STRIDERFX_FLARE_SIZE].x; color32 color; float bright = params[STRIDERFX_FLARE_COLOR].x * gunFractionVisible; ScaleColor( color, white, bright ); color.a = (int)(255 * params[STRIDERFX_DARKNESS].x); pRenderContext->Bind( pMat, (IClientRenderable*)this ); Strider_DrawSprite( m_worldPosition, size, color ); } // bubble warpy sprite if ( hasParam[STRIDERFX_BUBBLE_SIZE] ) { Vector wideBeamEnd = m_beamEndPosition; if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] ) { float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x; wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt); } pixelvis_queryparams_t endParams; endParams.Init(wideBeamEnd, 4.0f, 0.001f); float endFractionVisible = PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd ); bool endVisible = endFractionVisible > 0.0f ? true : false; if ( endVisible ) { if ( !updated ) { updated = true; pRenderContext->Flush(); UpdateRefractTexture(); } IMaterial *pMat = materials->FindMaterial( "effects/strider_bulge_dudv", TEXTURE_GROUP_CLIENT_EFFECTS ); float refract = endFractionVisible * WARP_BUBBLE_REFRACT * params[STRIDERFX_BUBBLE_REFRACT].x; float size = WARP_BUBBLE_SIZE * params[STRIDERFX_BUBBLE_SIZE].x; IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL ); pVar->SetFloatValue( refract ); pRenderContext->Bind( pMat, (IClientRenderable*)this ); Strider_DrawSprite( wideBeamEnd, size, white ); } } else { // call this to have the check ready on the first frame pixelvis_queryparams_t endParams; endParams.Init(m_beamEndPosition, 4.0f, 0.001f); PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd ); } if ( hasParam[STRIDERFX_AFTERGLOW_COLOR] && gunVisible ) { IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS ); float size = AFTERGLOW_SIZE;// * params[STRIDERFX_FLARE_SIZE].x; color32 color; float bright = params[STRIDERFX_AFTERGLOW_COLOR].x * gunFractionVisible; ScaleColor( color, white, bright ); pRenderContext->Bind( pMat, (IClientRenderable*)this ); Strider_DrawSprite( m_worldPosition, size, color ); dlight_t *dl = effects->CL_AllocDlight( m_entityIndex ); dl->origin = m_worldPosition; dl->color.r = 40; dl->color.g = 60; dl->color.b = 255; dl->color.exponent = 5; dl->radius = bright * 128; dl->die = gpGlobals->curtime + 0.001; } if ( m_t >= STRIDERFX_END_ALL_TIME && !hasAny ) { EffectShutdown(); } return 1; }
//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int C_SpriteRenderer::DrawSprite( IClientEntity *entity, const model_t *model, const Vector& origin, const QAngle& angles, float frame, IClientEntity *attachedto, int attachmentindex, int rendermode, int renderfx, int alpha, int r, int g, int b, float scale, float flHDRColorScale ) { VPROF_BUDGET( "C_SpriteRenderer::DrawSprite", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( !r_drawsprites.GetBool() || !model || modelinfo->GetModelType( model ) != mod_sprite ) return 0; // Get extra data CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData(model); if ( !psprite ) return 0; Vector effect_origin; VectorCopy(origin, effect_origin); // Use attachment point if ( attachedto ) { C_BaseEntity *ent = attachedto->GetBaseEntity(); if ( ent ) { if ( ent->GetBaseAnimating() && ent->GetBaseAnimating()->IsViewModel() && ::input->CAM_IsThirdPersonOverShoulder() ) { C_BaseViewModel *pVm = (C_BaseViewModel*)ent; C_BasePlayer *pOwner = ( pVm->GetOwner() && pVm->GetOwner()->IsPlayer() ) ? (C_BasePlayer*)pVm->GetOwner() : NULL; if ( pOwner && pOwner->GetActiveWeapon() ) return 0; //worldmodels don't have the same attachments, so just get out (crossbow) } // don't draw viewmodel effects in reflections if ( CurrentViewID() == VIEW_REFLECTION ) { int group = ent->GetRenderGroup(); if ( group == RENDER_GROUP_VIEW_MODEL_TRANSLUCENT || group == RENDER_GROUP_VIEW_MODEL_OPAQUE ) return 0; } QAngle temp; ent->GetAttachment(attachmentindex, effect_origin, temp); } } if ( rendermode != kRenderNormal ) { float blend = render->GetBlend(); // kRenderGlow and kRenderWorldGlow have a special blending function if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow )) { blend *= GlowBlend( psprite, effect_origin, rendermode, renderfx, alpha, &scale ); // Fade out the sprite depending on distance from the view origin. r *= blend; g *= blend; b *= blend; } render->SetBlend( blend ); if ( blend <= 0.0f ) { return 0; } } // Get orthonormal basis Vector forward, right, up; GetSpriteAxes( (SPRITETYPE)psprite->GetOrientation(), origin, angles, forward, right, up ); // Draw DrawSpriteModel( entity, psprite, effect_origin, scale, frame, rendermode, r, g, b, alpha, forward, right, up, flHDRColorScale ); return 1; }