//----------------------------------------------------------------------------- // Purpose: Handle weapon impacts from the helicopter shooting (cheaper versions) //----------------------------------------------------------------------------- void ImpactHelicopterCallback( const CEffectData &data ) { VPROF_BUDGET( "ImpactHelicopterCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); trace_t tr; Vector vecOrigin, vecStart, vecShotDir; int iMaterial, iDamageType, iHitbox; short nSurfaceProp; C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox ); if ( !pEntity ) { // This happens for impacts that occur on an object that's then destroyed. // Clear out the fraction so it uses the server's data tr.fraction = 1.0; PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp ); return; } // If we hit, perform our custom effects and play the sound. Don't create decals if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) ) { FX_AirboatGunImpact( vecOrigin, tr.plane.normal, IsXbox() ? 1 : 2 ); // Only do metal + computer custom effects if ( (iMaterial == CHAR_TEX_METAL) || (iMaterial == CHAR_TEX_COMPUTER) ) { PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0, FLAGS_CUSTIOM_EFFECTS_NOFLECKS ); } } PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp ); }
//----------------------------------------------------------------------------- // Purpose: Handle weapon impacts from the airboat gun shooting (cheaper versions) //----------------------------------------------------------------------------- void ImpactAirboatGunCallback( const CEffectData &data ) { VPROF_BUDGET( "ImpactAirboatGunCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); trace_t tr; Vector vecOrigin, vecStart, vecShotDir; int iMaterial, iDamageType, iHitbox; short nSurfaceProp; C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox ); if ( !pEntity ) { // This happens for impacts that occur on an object that's then destroyed. // Clear out the fraction so it uses the server's data tr.fraction = 1.0; PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp ); return; } #if !defined( _XBOX ) // If we hit, perform our custom effects and play the sound. Don't create decals if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) ) { FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 2 ); } #else FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 1 ); #endif }
//=============================================================================== // Actualiza la ubicación de la luz //=============================================================================== void CBaseFlashlightEffect::Update( const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp ) { VPROF_BUDGET( __FUNCTION__, VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); // No esta encendida if ( !IsOn() ) return; FlashlightState_t state; if ( UpdateDefaultFlashlightState( state, vecPos, vecForward, vecRight, vecUp ) == false ) return; UpdateLightProjection( state ); #ifndef NO_TOOLFRAMEWORK if ( clienttools->IsInRecordingMode() ) { KeyValues *msg = new KeyValues( "FlashlightState" ); msg->SetFloat( "time", gpGlobals->curtime ); msg->SetInt( "entindex", m_iEntIndex ); msg->SetInt( "flashlightHandle", m_nFlashlightHandle ); msg->SetPtr( "flashlightState", &state ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } #endif }
//=============================================================================== //=============================================================================== bool CBaseFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp ) { VPROF_BUDGET( __FUNCTION__, VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); // No esta encendida if ( !IsOn() ) return false; if ( ComputeLightPosAndOrientation( vecPos, vecForward, vecRight, vecUp, state.m_vecLightOrigin, state.m_quatOrientation ) == false ) return false; state.m_fQuadraticAtten = m_flQuadratic; state.m_fConstantAtten = m_flConstant; // Color de la luz state.m_Color[0] = 1.0f; state.m_Color[1] = 1.0f; state.m_Color[2] = 1.0f; state.m_Color[3] = m_flAlpha; // Distancia y FOV state.m_NearZ = m_flNear + r_flashlightnearoffsetscale.GetFloat() * m_flCurrentPullBackDist; state.m_FarZ = state.m_FarZAtten = m_flFar; state.m_fHorizontalFOVDegrees = state.m_fVerticalFOVDegrees = m_flFOV; // Es el efecto de un "MuzzleFlash" if ( m_bMuzzleFlashEnabled ) { state.m_pSpotlightTexture = m_nMuzzleFlashTexture; state.m_fLinearAtten = m_flMuzzleFlashBrightness; state.m_bShadowHighRes = false; state.m_nShadowQuality = 0; state.m_flShadowFilterSize = 2.0f; } // Es una linterna normal else { state.m_pSpotlightTexture = m_nFlashlightTexture; state.m_fLinearAtten = m_flBrightness; state.m_bShadowHighRes = true; state.m_nShadowQuality = 1; state.m_flShadowFilterSize = r_projectedtexture_filter.GetFloat(); } state.m_pProjectedMaterial = NULL; state.m_nSpotlightTextureFrame = 0; // Propiedades de las sombras generadas state.m_bEnableShadows = m_bCastsShadows; state.m_flShadowAtten = r_flashlightshadowatten.GetFloat(); state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias(); state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias(); return true; }
void FX_MetalScrape(Vector &position, Vector &normal) { VPROF_BUDGET("FX_MetalScrape", VPROF_BUDGETGROUP_PARTICLE_RENDERING); Vector offset = position + (normal * 1.0f); CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create("FX_MetalScrape 1"); if (!sparkEmitter) return; sparkEmitter->SetSortOrigin(offset); //Setup our collision information sparkEmitter->Setup(offset, &normal, METAL_SCRAPE_SPREAD, METAL_SCRAPE_MINSPEED, METAL_SCRAPE_MAXSPEED, METAL_SCRAPE_GRAVITY, METAL_SCRAPE_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); int numSparks = random->RandomInt(4, 8); if (g_Material_Spark == NULL) { g_Material_Spark = sparkEmitter->GetPMaterial("effects/spark"); } Vector dir; TrailParticle *pParticle; float length = 0.06f; //Dump out sparks for (int i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) sparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, offset); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; float spreadOfs = random->RandomFloat(0.0f, 2.0f); dir[0] = normal[0] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); dir[1] = normal[1] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); dir[2] = normal[2] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); pParticle->m_flWidth = random->RandomFloat(2.0f, 5.0f); pParticle->m_flLength = random->RandomFloat(length*0.25f, length); pParticle->m_flDieTime = random->RandomFloat(2.0f, 2.0f); pParticle->m_vecVelocity = dir * random->RandomFloat((METAL_SCRAPE_MINSPEED*(2.0f - spreadOfs)), (METAL_SCRAPE_MAXSPEED*(2.0f - spreadOfs))); Color32Init(pParticle->m_color, 255, 255, 255, 255); } }
ActionResult<CTFBot> CTFBotPayloadGuard::OnResume(CTFBot *actor, Action<CTFBot> *action) { VPROF_BUDGET("CTFBotPayloadGuard::OnResume", "NextBot"); // Invalidate CT @ 0x4828 // Invalidate CT @ 0x4810 return ActionResult<CTFBot>::Continue(); }
ActionResult<CTFBot> CTFBotCapturePoint::OnStart(CTFBot *actor, Action<CTFBot> *action) { VPROF_BUDGET("CTFBotCapturePoint::OnStart", "NextBot"); this->m_PathFollower.SetMinLookAheadDistance(actor->GetDesiredPathLookAheadRange()); this->m_PathFollower.Invalidate(); return ActionResult<CTFBot>::Continue(); }
EventDesiredResult<CTFBot> CTFBotPayloadGuard::OnStuck(CTFBot *actor) { VPROF_BUDGET("CTFBotPayloadGuard::OnStuck", "NextBot"); // Invalidate CT @ 0x4810 actor->GetLocomotionInterface()->ClearStuckStatus(""); return EventDesiredResult<CTFBot>::Continue(); }
EventDesiredResult<CTFBot> CTFBotPayloadGuard::OnMoveToFailure(CTFBot *actor, const Path *path, MoveToFailureType fail) { VPROF_BUDGET("CTFBotPayloadGuard::OnMoveToFailure", "NextBot"); // Invalidate CT @ 0x4828 // Invalidate CT @ 0x4810 return EventDesiredResult<CTFBot>::Continue(); }
int CParticleEffectBinding::DrawModel( int flags ) { VPROF_BUDGET( "CParticleEffectBinding::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); #ifndef PARTICLEPROTOTYPE_APP if ( !r_DrawParticles.GetInt() ) return 0; #endif Assert( flags != 0 ); // If we're in commander mode and it's trying to draw the effect, // exit out. If the effect has FLAGS_ALWAYSSIMULATE set, then it'll come back // in here and simulate at the end of the frame. if( !g_pClientMode->ShouldDrawParticles() ) return 0; SetDrawn( true ); // Don't do anything if there are no particles. if( !m_nActiveParticles ) return 1; // Reset the transformation matrix to identity. VMatrix mTempModel, mTempView; RenderStart( mTempModel, mTempView ); // Setup to redo our bbox? bool bBucketSort = random->RandomInt( 0, BUCKET_SORT_EVERY_N ) == 0; // Set frametime to zero if we've already rendered this frame. float flFrameTime = 0; if ( m_FrameCode != m_pParticleMgr->m_FrameCode ) { m_FrameCode = m_pParticleMgr->m_FrameCode; flFrameTime = Helper_GetFrameTime(); } // For each material, render... // This does an incremental bubble sort. It only does one pass every frame, and it will shuffle // unsorted particles one step towards where they should be. bool bWireframe = false; FOR_EACH_LL( m_Materials, iMaterial ) { CEffectMaterial *pMaterial = m_Materials[iMaterial]; if ( pMaterial->m_pGroup->m_pPageMaterial && pMaterial->m_pGroup->m_pPageMaterial->NeedsPowerOfTwoFrameBufferTexture() ) { UpdateRefractTexture(); } DrawMaterialParticles( bBucketSort, pMaterial, flFrameTime, bWireframe ); }
void ChasePath::RefreshPath(INextBot *nextbot, CBaseEntity *ent, const IPathCost& cost_func, Vector *vec) { VPROF_BUDGET("ChasePath::RefreshPath", "NextBot"); if (this->IsValid() && nextbot->GetLocomotionInterface()->IsUsingLadder()) { if (nextbot->IsDebugging(DEBUG_PATH)) { DevMsg("%3.2f: bot(#%d) ChasePath::RefreshPath failed. Bot is on a ladder.\n", gpGlobals->curtime, ENTINDEX(nextbot->GetEntity())); } this->m_ctTimer2.Start(1.0f); return; } if (ent == nullptr) { if (nextbot->IsDebugging(DEBUG_PATH)) { /* misspelling is in original */ DevMsg("%3.2f: bot(#%d) CasePath::RefreshPath failed. No subject.\n", gpGlobals->curtime, ENTINDEX(nextbot->GetEntity())); } } if (this->m_ctTimer1.IsElapsed()) { CBaseEntity *subject = this->m_hChaseSubject(); if (subject == nullptr || subject != ent) { if (nextbot->IsDebugging(DEBUG_PATH)) { DevMsg("%3.2f: bot(#%d) ChasePath::RefreshPath subject changed (from %p to %p).\n", gpGlobals->curtime, ENTINDEX(nextbot->GetEntity()), this->m_hChaseSubject(), ent); } this->Invalidate(); this->m_ctTimer1.Invalidate(); } if (!this->IsValid() || this->m_ctTimer2.IsElapsed()) { if (this->IsValid() && this->m_ctTimer3.HasStarted() && this->m_ctTimer3.IsElapsed()) { this->Invalidate(); } if (!this->IsValid() || this->IsRepathNeeded(nextbot, ent)) { // TODO // eventually: this->Compute(...) } // TODO } // TODO } }
//----------------------------------------------------------------------------- // Spew out dust! //----------------------------------------------------------------------------- void FX_Dust( const Vector &vecOrigin, const Vector &vecDirection, float flSize, float flSpeed ) { VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); int numPuffs = (flSize*0.5f); if ( numPuffs < 1 ) numPuffs = 1; if ( numPuffs > 32 ) numPuffs = 32; float speed = flSpeed * 0.1f; if ( speed < 0 ) speed = 1.0f; if (speed > 48.0f ) speed = 48.0f; //FIXME: Better sampling area Vector offset = vecOrigin + ( vecDirection * flSize ); //Find area ambient light color and use it to tint smoke Vector worldLight = WorldGetLightForPoint( offset, true ); // Throw puffs SimpleParticle particle; for ( int i = 0; i < numPuffs; i++ ) { offset.Random( -(flSize*0.25f), flSize*0.25f ); offset += vecOrigin + ( vecDirection * flSize ); particle.m_Pos = offset; particle.m_flLifetime = 0.0f; particle.m_flDieTime = random->RandomFloat( 0.4f, 1.0f ); particle.m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i; particle.m_vecVelocity[2] = 0.0f; int color = random->RandomInt( 48, 64 ); particle.m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color ); particle.m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color ); particle.m_uchColor[2] = color + ( worldLight[2] * (float) color ); particle.m_uchStartAlpha= random->RandomInt( 64, 128 ); particle.m_uchEndAlpha = 0; particle.m_uchStartSize = random->RandomInt( 2, 8 ); particle.m_uchEndSize = random->RandomInt( 24, 48 ); particle.m_flRoll = random->RandomInt( 0, 360 ); particle.m_flRollDelta = random->RandomFloat( -0.5f, 0.5f ); AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1)] ); } }
void IVision::Update() { VPROF_BUDGET("IVision::Update", "NextBotExpensive"); if (nb_blind.GetBool()) { this->m_KnownEntities.RemoveAll(); } else { this->UpdateKnownEntities(); this->m_flLastUpdate = gpGlobals->curtime; } }
//----------------------------------------------------------------------------- // Purpose: Do the headlight //----------------------------------------------------------------------------- void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, float flFov, float flFarZ, float flLinearAtten, bool castsShadows, const char* pTextureName ) { VPROF_BUDGET( __FUNCTION__, VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); m_nEntIndex = nEntIdx; m_flFov = flFov; m_flFarZ = flFarZ; m_flLinearAtten = flLinearAtten; if ( m_bCastsShadows != castsShadows ) { // requires recreation of the flashlight LightOff(); } m_bCastsShadows = castsShadows; UpdateFlashlightTexture( pTextureName ); FlashlightState_t state; if ( UpdateDefaultFlashlightState( state, vecPos, vecForward, vecRight, vecUp, castsShadows ) == false ) { return; } if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE ) { m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state ); } else { if( !r_flashlightlockposition.GetBool() ) { g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state ); } } g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true ); #ifndef NO_TOOLFRAMEWORK if ( clienttools->IsInRecordingMode() ) { KeyValues *msg = new KeyValues( "FlashlightState" ); msg->SetFloat( "time", gpGlobals->curtime ); msg->SetInt( "entindex", m_nEntIndex ); msg->SetInt( "flashlightHandle", m_FlashlightHandle ); msg->SetPtr( "flashlightState", &state ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } #endif }
static void RestoreEntityTo( CBaseEntity *pEntity, const Vector &vWantedPos ) { int nMask = pEntity->IsPlayer() ? MASK_PLAYERSOLID : MASK_NPCSOLID; int nCollisionGroup = pEntity->IsPlayer() ? COLLISION_GROUP_PLAYER_MOVEMENT : COLLISION_GROUP_NPC; // Try to move to the wanted position from our current position. trace_t tr; VPROF_BUDGET( "RestorePlayerTo", "CTFLagCompensationManager" ); UTIL_TraceEntity( pEntity, vWantedPos, vWantedPos, nMask, pEntity, nCollisionGroup, &tr ); if ( tr.startsolid || tr.allsolid ) { if ( sv_unlag_debug.GetBool() ) { CBasePlayer *pPlayer = ToBasePlayer( pEntity ); if ( pPlayer ) { DevMsg( "RestorePlayerTo() could not restore player position for client \"%s\" ( %.1f %.1f %.1f )\n", pPlayer->GetPlayerName(), vWantedPos.x, vWantedPos.y, vWantedPos.z ); } else { DevMsg( "RestoreEntityTo() could not restore entity position for %s ( %.1f %.1f %.1f )\n", pEntity->GetClassname(), vWantedPos.x, vWantedPos.y, vWantedPos.z ); } } UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), vWantedPos, nMask, pEntity, nCollisionGroup, &tr ); if ( tr.startsolid || tr.allsolid ) { // In this case, the guy got stuck back wherever we lag compensated him to. Nasty. if ( sv_unlag_debug.GetBool() ) DevMsg( " restore failed entirely\n" ); } else { // We can get to a valid place, but not all the way back to where we were. Vector vPos; VectorLerp( pEntity->GetLocalOrigin(), vWantedPos, tr.fraction * g_flFractionScale, vPos ); UTIL_SetOrigin( pEntity, vPos, true ); if ( sv_unlag_debug.GetBool() ) DevMsg( " restore got most of the way\n" ); } } else { // Cool, the player can go back to whence he came. UTIL_SetOrigin( pEntity, tr.endpos, true ); } }
virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ) { VPROF_BUDGET( "C_ServerRagdollAttached::SetupBones", VPROF_BUDGETGROUP_CLIENT_ANIMATION ); if ( !hdr ) return; float frac = RemapVal( gpGlobals->curtime, m_parentTime, m_parentTime+ATTACH_INTERP_TIME, 0, 1 ); frac = clamp( frac, 0.f, 1.f ); // interpolate offset over some time Vector offset = m_vecOffset * (1-frac); C_BaseAnimating *parent = assert_cast< C_BaseAnimating* >( GetMoveParent() ); Vector worldOrigin; worldOrigin.Init(); if ( parent ) { Assert( parent != this ); parent->SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, gpGlobals->curtime ); matrix3x4_t boneToWorld; parent->GetCachedBoneMatrix( m_boneIndexAttached, boneToWorld ); VectorTransform( m_attachmentPointBoneSpace, boneToWorld, worldOrigin ); } BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed ); if ( parent ) { int index = m_boneIndex[m_ragdollAttachedObjectIndex]; const matrix3x4_t &matrix = GetBone( index ); Vector ragOrigin; VectorTransform( m_attachmentPointRagdollSpace, matrix, ragOrigin ); offset = worldOrigin - ragOrigin; // fixes culling SetAbsOrigin( worldOrigin ); m_vecOffset = offset; } for ( int i = 0; i < hdr->numbones(); i++ ) { if ( !( hdr->boneFlags( i ) & boneMask ) ) continue; Vector pos; matrix3x4_t &matrix = GetBoneForWrite( i ); MatrixGetColumn( matrix, 3, pos ); pos += offset; MatrixSetColumn( pos, 3, matrix ); } }
//----------------------------------------------------------------------------- // Purpose: Smoke puffs //----------------------------------------------------------------------------- void FX_Smoke( const Vector &origin, const QAngle &angles, float scale, int numParticles, unsigned char *pColor, int iAlpha ) { VPROF_BUDGET( "FX_Smoke", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); Vector vecVelocity; Vector vecForward; // Smoke for ( int i = 0; i < numParticles; i++ ) { // Velocity AngleVectors( angles, &vecForward ); vecVelocity.Random( -0.5f, 0.5f ); vecVelocity += vecForward; VectorNormalize( vecVelocity ); vecVelocity *= random->RandomFloat( 16.0f, 32.0f ); vecVelocity[2] += random->RandomFloat( 4.0f, 16.0f ); // Color unsigned char particlecolor[3]; if ( !pColor ) { int color = random->RandomInt( 64, 164 ); particlecolor[0] = color; particlecolor[1] = color; particlecolor[2] = color; } else { particlecolor[0] = pColor[0]; particlecolor[1] = pColor[1]; particlecolor[2] = pColor[2]; } // Alpha int alpha = iAlpha; if ( alpha == -1 ) { alpha = random->RandomInt( 10, 25 ); } // Scale int iSize = random->RandomInt( 4, 8 ) * scale; // Roll float flRoll = random->RandomInt( 0, 360 ); float flRollDelta = random->RandomFloat( -4.0f, 4.0f ); //pParticle->m_uchEndSize = pParticle->m_uchStartSize*2; FX_Smoke( origin, vecVelocity, iSize, 1, random->RandomFloat( 0.5f, 1.0f ), particlecolor, alpha, "particle/particle_smokegrenade", flRoll, flRollDelta ); } }
void CAI_RadialLinkController::ModifyNodeLinks( bool bMakeStale ) { int nNodes = g_pBigAINet->NumNodes(); CAI_Node **ppNodes = g_pBigAINet->AccessNodes(); VPROF_BUDGET("ModifyLinks", "ModifyLinks"); const float MinDistCareSq = Square( ai_radial_max_link_dist.GetFloat() + 0.1 ); for ( int i = 0; i < nNodes; i++ ) { CAI_Node *pNode = ppNodes[i]; const Vector &nodeOrigin = pNode->GetOrigin(); if ( m_vecAtRestOrigin.DistToSqr(nodeOrigin) < MinDistCareSq ) { int nLinks = pNode->NumLinks(); for ( int j = 0; j < nLinks; j++ ) { CAI_Link *pLink = pNode->GetLinkByIndex( j ); int iLinkDest = pLink->DestNodeID( i ); if ( iLinkDest > i ) { bool bQualify = true; if( ( (pLink->m_iAcceptedMoveTypes[HULL_HUMAN]||pLink->m_iAcceptedMoveTypes[HULL_WIDE_HUMAN]) & bits_CAP_MOVE_GROUND) == 0 ) { // Micro-optimization: Ignore any connection that's not a walking connection for humans.(sjb) bQualify = false; } const Vector &originOther = ppNodes[iLinkDest]->GetOrigin(); if ( bQualify && m_vecAtRestOrigin.DistToSqr(originOther) < MinDistCareSq ) { if ( IsRayIntersectingSphere(nodeOrigin, originOther - nodeOrigin, m_vecAtRestOrigin, m_flRadius) ) { if( bMakeStale ) { pLink->m_LinkInfo |= bits_LINK_STALE_SUGGESTED; pLink->m_timeStaleExpires = FLT_MAX; } else { pLink->m_LinkInfo &= ~bits_LINK_STALE_SUGGESTED; } } } } } } } }
//================================================================================ // Update hitbox positions and visibility // This function can be very expensive, it should only be called for the active enemy. //================================================================================ void CEntityMemory::UpdateHitboxAndVisibility() { VPROF_BUDGET("CEntityMemory::UpdateHitboxAndVisibility", VPROF_BUDGETGROUP_BOTS_EXPENSIVE); // For now let's assume that we do not know Hitbox and therefore we have no vision UpdateVisibility(false); m_Hitbox.Reset(); m_VisibleHitbox.Reset(); // We obtain the positions of the Hitbox Utils::GetHitboxPositions(GetEntity(), m_Hitbox); if (!m_Hitbox.IsValid()) return; { VPROF_BUDGET("UpdateVisibility", VPROF_BUDGETGROUP_BOTS_EXPENSIVE); // Now let's check if we can see any of them if (m_pBot->GetDecision()->IsAbleToSee(m_Hitbox.head)) { m_VisibleHitbox.head = m_Hitbox.head; UpdateVisibility(true); } if (m_pBot->GetDecision()->IsAbleToSee(m_Hitbox.chest)) { m_VisibleHitbox.chest = m_Hitbox.chest; UpdateVisibility(true); } if (m_pBot->GetDecision()->IsAbleToSee(m_Hitbox.feet)) { m_VisibleHitbox.feet = m_Hitbox.feet; UpdateVisibility(true); } } // We update the ideal position GetVisibleHitboxPosition(m_vecIdealPosition, m_pBot->GetProfile()->GetFavoriteHitbox()); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CRecastMgr::Update( float dt ) { VPROF_BUDGET( "CRecastMgr::Update", "RecastNav" ); #ifndef CLIENT_DLL UpdateRebuildPartial(); #endif // CLIENT_DLL for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) ) { CRecastMesh *pMesh = m_Meshes[ i ]; pMesh->Update( dt ); } }
//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // Chopper muzzle flashes //----------------------------------------------------------------------------- void MuzzleFlash_Chopper( ClientEntityHandle_t hEntity, int attachmentIndex ) { VPROF_BUDGET( "MuzzleFlash_Chopper", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); matrix3x4_t matAttachment; // If the client hasn't seen this entity yet, bail. if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) ) return; CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex ); SimpleParticle *pParticle; Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space float flScale = random->RandomFloat( 2.5f, 4.5f ); // Flash for ( int i = 1; i < 7; i++ ) { offset = (forward * (i*2.0f*flScale)); pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset ); if ( pParticle == NULL ) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f ); pParticle->m_vecVelocity.Init(); pParticle->m_uchColor[0] = 255; pParticle->m_uchColor[1] = 255; pParticle->m_uchColor[2] = 255; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 128; pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (10-(i))/7) * flScale ); pParticle->m_uchEndSize = pParticle->m_uchStartSize; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = 0.0f; } // Grab the origin out of the transform for the attachment Vector origin; MatrixGetColumn( matAttachment, 3, &origin ); CreateMuzzleflashELight( origin, 6, 128, 256, hEntity ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPotentialFieldMgr::FrameUpdatePreEntityThink() { VPROF_BUDGET( "CPotentialFieldMgr::FrameUpdatePreEntityThink", VPROF_BUDGETGROUP_POTENTIALFIELD ); if( !m_bActive ) return; if( !NeedsUpdate() ) return; m_fNeedsUpdate = gpGlobals->curtime + 0.1f; m_pPotentialField->Reset(); m_pPotentialField->Update(); }
//----------------------------------------------------------------------------- // Purpose: serialize a protobuf into a utlbuffer //----------------------------------------------------------------------------- void CHTMLBaseProtoBufMsg::SerializeCrossProc( CUtlBuffer *pBuffer ) const { VPROF_BUDGET( "CUIProtoBufMsg::SerializeCrossProc", VPROF_BUDGETGROUP_OTHER_VGUI ); uint32 unSize = ((google::protobuf::MessageLite *)m_pMsg)->ByteSize(); // Ensure enough for type, size, and serialized data pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) * 3 + unSize ); // bugbug cboyd - drop to * 2 whenpassthrough is removed below pBuffer->PutUnsignedInt( unSize ); if ( unSize == 0 ) return; uint8 *pBody = (uint8*)pBuffer->Base()+pBuffer->TellPut(); ((google::protobuf::MessageLite *)m_pMsg)->SerializeWithCachedSizesToArray( pBody ); pBuffer->SeekPut( CUtlBuffer::SEEK_CURRENT, unSize ); }
//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void UnitBaseAirLocomotion::Move( float interval, UnitBaseMoveCommand &move_command ) { VPROF_BUDGET( "UnitBaseAirLocomotion::Move", VPROF_BUDGETGROUP_UNITS ); mv = &move_command; mv->interval = interval; mv->outwishvel.Init(); Friction(); FullAirMove(); MoveFacing(); // Sometimes an unit spawns with an invalid velocity and can't move // Validate velocity after each move CheckVelocity(); }
//----------------------------------------------------------------------------- // Purpose: Shockwave for gunship bullet impacts! // Input : &pos - // // NOTES: -Don't draw this effect when the viewer is very far away. //----------------------------------------------------------------------------- void FX_GunshipImpact( const Vector &pos, const Vector &normal, float r, float g, float b ) { VPROF_BUDGET( "FX_GunshipImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( CImpactOverlay *pOverlay = new CImpactOverlay ) { pOverlay->m_flLifetime = 0; VectorMA( pos, 1.0f, normal, pOverlay->m_vPos ); // Doesn't show up on terrain if you don't do this(sjb) pOverlay->m_nSprites = 1; pOverlay->m_vBaseColors[0].Init( r, g, b ); pOverlay->m_Sprites[0].m_flHorzSize = 0.01f; pOverlay->m_Sprites[0].m_flVertSize = 0.01f; pOverlay->Activate(); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_ParticleSystem::ClientThink( void ) { if ( m_bActive ) { const char *pszName = GetParticleSystemNameFromIndex( m_iEffectIndex ); if ( pszName && pszName[0] ) { CNewParticleEffect *pEffect = ParticleProp()->Create( pszName, PATTACH_ABSORIGIN_FOLLOW ); AssertMsg1( pEffect, "Particle system couldn't make %s", pszName ); if (pEffect) { for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) { CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); if ( pOnEntity ) { ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); } AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , "Particle system specified bogus control point parent (%d) for point %d.", m_iControlPointParents[i], i ); if (m_iControlPointParents[i] != 0) { pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); } } // NOTE: What we really want here is to compare our lifetime and that of our children and see if this delta is // already past the end of it, denoting that we're finished. In that case, just destroy us and be done. -- jdw // TODO: This can go when the SkipToTime code below goes ParticleProp()->OnParticleSystemUpdated( pEffect, 0.0f ); // Skip the effect ahead if we're restarting it float flTimeDelta = gpGlobals->curtime - m_flStartTime; if ( flTimeDelta > 0.01f ) { VPROF_BUDGET( "C_ParticleSystem::ClientThink SkipToTime", "Particle Simulation" ); pEffect->SkipToTime( flTimeDelta ); } } } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *cl - // *msg - //----------------------------------------------------------------------------- void CNetworkStringTableContainer::DirectUpdate( int tick_ack ) { VPROF_BUDGET( "CNetworkStringTableContainer::DirectUpdate", VPROF_BUDGETGROUP_OTHER_NETWORKING ); // Determine if an update is needed for ( int i = 0; i < m_Tables.Count(); i++ ) { CNetworkStringTable *table = (CNetworkStringTable*) GetTable( i ); Assert( table ); if ( !table->ChangedSinceTick( tick_ack ) ) continue; table->UpdateMirrorTable( tick_ack ); } }
//----------------------------------------------------------------------------- // Purpose: grab a previously serialized protobuf //----------------------------------------------------------------------------- bool CHTMLBaseProtoBufMsg::BDeserializeCrossProc( CUtlBuffer *pBuffer ) { VPROF_BUDGET( "CUIProtoBufMsg::BDeserialize", VPROF_BUDGETGROUP_OTHER_VGUI ); if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint32) ) return false; uint32 unSize = pBuffer->GetUnsignedInt(); if ( unSize == 0 ) return true; if ( pBuffer->GetBytesRemaining() < (int)unSize ) return false; bool bSucccess = ((google::protobuf::MessageLite *)m_pMsg)->ParseFromArray( (uint8*)pBuffer->Base()+pBuffer->TellGet(), unSize ); pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, unSize ); return bSucccess; }
//========================================================= //========================================================= bool C_GameInstructor::UpdateActiveLesson( CBaseLesson *pLesson, const CBaseLesson *pRootLesson ) { VPROF_BUDGET( "C_GameInstructor::UpdateActiveLesson", "GameInstructor" ); bool bIsOpen = pLesson->IsInstructing(); if ( !bIsOpen && !pRootLesson->IsLearned() ) { pLesson->SetStartTime(); pLesson->Start(); // Check to see if it successfully started bIsOpen = ( pLesson->IsOpenOpportunity() && pLesson->ShouldDisplay() ); if ( bIsOpen ) { // Lesson hasn't been started and hasn't been learned if ( gameinstructor_verbose.GetInt() > 0 ) { ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Started lesson " ); ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", pLesson->GetName() ); ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); } } else { pLesson->Stop(); pLesson->ResetStartTime(); } } if ( bIsOpen ) { // Update the running lesson pLesson->Update(); return true; } else { pLesson->UpdateInactive(); return false; } }