void ScratchPad_DrawLitCone( IScratchPad3D *pPad, const Vector &vBaseCenter, const Vector &vTip, const Vector &vBrightColor, const Vector &vDarkColor, const Vector &vLightDir, float baseWidth, int nSegments ) { // Make orthogonal vectors. Vector vDir = vTip - vBaseCenter; VectorNormalize( vDir ); Vector vRight, vUp; VectorVectors( vDir, vRight, vUp ); vRight *= baseWidth; vUp *= baseWidth; // Setup the top and bottom caps. CSPVertList bottomCap, tri; bottomCap.m_Verts.SetSize( nSegments ); tri.m_Verts.SetSize( 3 ); float flDot = -vLightDir.Dot( vDir ); Vector topColor, bottomColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); // Draw each quad. Vector vPrevBottom = vBaseCenter + vRight; for ( int i=0; i < nSegments; i++ ) { float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); Vector vCurBottom = vBaseCenter + vOffset; const Vector &v1 = vTip; const Vector &v2 = vPrevBottom; const Vector &v3 = vCurBottom; Vector vFaceNormal = (v2 - v1).Cross( v3 - v1 ); VectorNormalize( vFaceNormal ); // Now light it. flDot = -vLightDir.Dot( vFaceNormal ); Vector vColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); // Draw the quad. tri.m_Verts[0] = CSPVert( v1, vColor ); tri.m_Verts[1] = CSPVert( v2, vColor ); tri.m_Verts[2] = CSPVert( v3, vColor ); pPad->DrawPolygon( tri ); bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); } pPad->DrawPolygon( bottomCap ); }
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) { float t0, t1; float angle, c, s; vec3_t vr, vu, vf; angle = DEG2RAD(degrees); c = cos(angle); s = sin(angle); VectorCopy(dir, vf); VectorVectors(vf, vr, vu); t0 = vr[0] * c + vu[0] * -s; t1 = vr[0] * s + vu[0] * c; dst[0] = (t0 * vr[0] + t1 * vu[0] + vf[0] * vf[0]) * point[0] + (t0 * vr[1] + t1 * vu[1] + vf[0] * vf[1]) * point[1] + (t0 * vr[2] + t1 * vu[2] + vf[0] * vf[2]) * point[2]; t0 = vr[1] * c + vu[1] * -s; t1 = vr[1] * s + vu[1] * c; dst[1] = (t0 * vr[0] + t1 * vu[0] + vf[1] * vf[0]) * point[0] + (t0 * vr[1] + t1 * vu[1] + vf[1] * vf[1]) * point[1] + (t0 * vr[2] + t1 * vu[2] + vf[1] * vf[2]) * point[2]; t0 = vr[2] * c + vu[2] * -s; t1 = vr[2] * s + vu[2] * c; dst[2] = (t0 * vr[0] + t1 * vu[0] + vf[2] * vf[0]) * point[0] + (t0 * vr[1] + t1 * vu[1] + vf[2] * vf[1]) * point[1] + (t0 * vr[2] + t1 * vu[2] + vf[2] * vf[2]) * point[2]; }
static void SetImpactControlPoint( CNewParticleEffect *pEffect, int nPoint, const Vector &vecImpactPoint, const Vector &vecForward, C_BaseEntity *pEntity ) { Vector vecImpactY, vecImpactZ; VectorVectors( vecForward, vecImpactY, vecImpactZ ); vecImpactY *= -1.0f; pEffect->SetControlPoint( nPoint, vecImpactPoint ); pEffect->SetControlPointOrientation( nPoint, vecForward, vecImpactY, vecImpactZ ); pEffect->SetControlPointEntity( nPoint, pEntity ); }
static cell_t GetVectorVectors(IPluginContext *pContext, const cell_t *params) { cell_t *vec_addr; pContext->LocalToPhysAddr(params[1], &vec_addr); Vector vec(sp_ctof(vec_addr[0]), sp_ctof(vec_addr[1]), sp_ctof(vec_addr[2])); Vector right, up; VectorVectors(vec, right, up); cell_t *addr_right, *addr_up; pContext->LocalToPhysAddr(params[2], &addr_right); pContext->LocalToPhysAddr(params[3], &addr_up); SET_VECTOR(addr_right, right); SET_VECTOR(addr_up, up); return 1; }
//-------------------------------------------------------------------------------- // Purpose : Draw a vertical arrow at a position //-------------------------------------------------------------------------------- void NDebugOverlay::VertArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) { Vector lineDir = (endPos - startPos); VectorNormalize( lineDir ); Vector upVec; Vector sideDir; float radius = width / 2.0; VectorVectors( lineDir, sideDir, upVec ); Vector p1 = startPos - upVec * radius; Vector p2 = endPos - lineDir * width - upVec * radius; Vector p3 = endPos - lineDir * width - upVec * width; Vector p4 = endPos; Vector p5 = endPos - lineDir * width + upVec * width; Vector p6 = endPos - lineDir * width + upVec * radius; Vector p7 = startPos + upVec * radius; // Outline the arrow Line(p1, p2, r,g,b,noDepthTest,flDuration); Line(p2, p3, r,g,b,noDepthTest,flDuration); Line(p3, p4, r,g,b,noDepthTest,flDuration); Line(p4, p5, r,g,b,noDepthTest,flDuration); Line(p5, p6, r,g,b,noDepthTest,flDuration); Line(p6, p7, r,g,b,noDepthTest,flDuration); if ( a > 0 ) { // Fill us in with triangles Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); // And backfaces Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); } }
//----------------------------------------------------------------------------- // Purpose: How far away is this point? This is different for point and bar magnets // Input : &vecPoint - the point // Output : float - the dist //----------------------------------------------------------------------------- float CRagdollMagnet::DistToPoint( const Vector &vecPoint ) { if( IsBarMagnet() ) { // I'm a bar magnet, so the point's distance is really the plane constant. // A bar magnet is a cylinder who's length is AbsOrigin() to m_axis, and whose // diameter is m_radius. // first we build two planes. The TOP and BOTTOM planes. // the idea is that vecPoint must be on the right side of both // planes to be affected by this particular magnet. // TOP and BOTTOM planes can be visualized as the 'caps' of the cylinder // that describes the bar magnet, and they point towards each other. // We're making sure vecPoint is between the caps. Vector vecAxis; vecAxis = GetAxisVector(); VectorNormalize( vecAxis ); CPlane top, bottom; bottom.InitializePlane( -vecAxis, m_axis ); top.InitializePlane( vecAxis, GetAbsOrigin() ); if( top.PointInFront( vecPoint ) && bottom.PointInFront( vecPoint ) ) { // This point is between the two caps, so calculate the distance // of vecPoint from the axis of the bar magnet CPlane axis; Vector vecUp; Vector vecRight; // Horizontal and Vertical distances. float hDist, vDist; // Need to get a vector that's right-hand to m_axis VectorVectors( vecAxis, vecRight, vecUp ); //CrossProduct( vecAxis, vecUp, vecRight ); //VectorNormalize( vecRight ); //VectorNormalize( vecUp ); // Set up the plane to measure horizontal dist. axis.InitializePlane( vecRight, GetAbsOrigin() ); hDist = fabs( axis.PointDist( vecPoint ) ); axis.InitializePlane( vecUp, GetAbsOrigin() ); vDist = fabs( axis.PointDist( vecPoint ) ); return MAX( hDist, vDist ); } else { return FLT_MAX; } } else { // I'm a point magnet. Just return dist return ( GetAbsOrigin() - vecPoint ).Length(); } }
void CNPC_Hydra::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_HYDRA_DEPLOY: { m_flHeadGoalInfluence = 1.0; float dist = (EyePosition() - m_vecHeadGoal).Length(); if (dist < m_idealSegmentLength) { TaskComplete(); } AimHeadInTravelDirection( 0.2 ); } break; case TASK_HYDRA_PREP_STAB: { int i; if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } CBaseEntity *pTarget = GetTarget(); if (pTarget == NULL) { TaskFail( FAIL_NO_TARGET ); } if (pTarget->IsPlayer()) { m_vecTarget = pTarget->EyePosition( ); } else { m_vecTarget = pTarget->BodyTarget( EyePosition( ) ); } float distToTarget = (m_vecTarget - m_vecHeadGoal).Length(); float distToBase = (m_vecHeadGoal - GetAbsOrigin()).Length(); m_idealLength = distToTarget + distToBase * 0.5; if (m_idealLength > HYDRA_MAX_LENGTH) m_idealLength = HYDRA_MAX_LENGTH; if (distToTarget < 100.0) { m_vecTargetDir = (m_vecTarget - m_vecHeadGoal); VectorNormalize( m_vecTargetDir ); m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (100 - distToTarget) * 0.5; } else if (distToTarget > 200.0) { m_vecTargetDir = (m_vecTarget - m_vecHeadGoal); VectorNormalize( m_vecTargetDir ); m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (200.0 - distToTarget) * 0.5; } // face enemy m_vecTargetDir = (m_vecTarget - m_body[m_body.Count()-1].vecPos); VectorNormalize( m_vecTargetDir ); m_vecHeadDir = m_vecHeadDir * 0.6 + m_vecTargetDir * 0.4; VectorNormalize( m_vecHeadDir.GetForModify() ); // build tension towards strike time float influence = 1.0 - (m_flTaskEndTime - gpGlobals->curtime) / pTask->flTaskData; if (influence > 1) influence = 1.0; influence = influence * influence * influence; m_flHeadGoalInfluence = influence; // keep head segment straight i = m_body.Count() - 2; m_body[i].vecGoalPos = m_vecHeadGoal - m_vecHeadDir * m_body[i].flActualLength; m_body[i].flGoalInfluence = influence; // curve neck into spiral float distBackFromHead = m_body[i].flActualLength; Vector right, up; VectorVectors( m_vecHeadDir, right, up ); for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--) { distBackFromHead += m_body[i].flActualLength; float r = (distBackFromHead / 200) * 3.1415 * 2; // spiral Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 0.5 + cos( r ) * m_body[i].flActualLength * right + sin( r ) * m_body[i].flActualLength * up; // base r = (distBackFromHead / m_idealLength) * 3.1415 * 0.2; r = sin( r ); p0 = p0 * (1 - r) + r * GetAbsOrigin(); m_body[i].vecGoalPos = p0; m_body[i].flGoalInfluence = influence * (1.0 - (distBackFromHead / distToTarget)); /* if ( (pEnemy->EyePosition( ) - m_body[i].vecPos).Length() < distBackFromHead) { if ( gpGlobals->curtime - m_flLastAttackTime > 4.0) { TaskComplete(); } return; } */ } // look to see if any of the goal positions are stuck for (i = i; i < m_body.Count() - 1; i++) { if (m_body[i].bStuck) { Vector delta = DotProduct( m_body[i].vecGoalPos - m_body[i].vecPos, m_vecHeadDir) * m_vecHeadDir; m_vecHeadGoal -= delta * m_body[i].flGoalInfluence; break; } } if ( gpGlobals->curtime >= m_flTaskEndTime ) { if (distToTarget < 500) { TaskComplete( ); return; } else { TaskFail( "target is too far away" ); return; } } } return; case TASK_HYDRA_STAB: { int i; if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } if (m_flTaskEndTime <= gpGlobals->curtime) { TaskComplete( ); return; } m_flHeadGoalInfluence = 1.0; // face enemy //m_vecHeadDir = (pEnemy->EyePosition( ) - m_body[m_body.Count()-1].vecPos); //VectorNormalize( m_vecHeadDir.GetForModify() ); // keep head segment straight i = m_body.Count() - 2; m_body[i].vecGoalPos = m_vecHeadGoal + m_vecHeadDir * m_body[i].flActualLength; m_body[i].flGoalInfluence = 1.0; Vector vecToTarget = (m_vecTarget - EyePosition( )); // check to see if we went past target if (DotProduct( vecToTarget, m_vecHeadDir ) < 0.0) { TaskComplete( ); return; } float distToTarget = vecToTarget.Length(); float distToBase = (EyePosition( ) - GetAbsOrigin()).Length(); m_idealLength = distToTarget + distToBase; /* if (distToTarget < 20) { m_vecHeadGoal = m_vecTarget; SetLastAttackTime( gpGlobals->curtime ); TaskComplete(); return; } else */ { // hit enemy m_vecHeadGoal = m_vecTarget + m_vecHeadDir * 300; } if (m_idealLength > HYDRA_MAX_LENGTH) m_idealLength = HYDRA_MAX_LENGTH; // curve neck into spiral float distBackFromHead = m_body[i].flActualLength; Vector right, up; VectorVectors( m_vecHeadDir, right, up ); #if 1 for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--) { Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 1.0; m_body[i].vecGoalPos = p0; if ((m_vecTarget - m_body[i].vecPos).Length() > distToTarget + distBackFromHead) { m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget); } else { m_body[i].vecGoalPos = EyePosition( ) - m_vecHeadDir * distBackFromHead; m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget); } distBackFromHead += m_body[i].flActualLength; } #endif } return; case TASK_HYDRA_PULLBACK: { if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } CBaseEntity *pEnemy = (CBaseEntity *)UTIL_GetLocalPlayer(); if (GetEnemy() != NULL) { pEnemy = GetEnemy(); } AimHeadInTravelDirection( 0.2 ); // float dist = (EyePosition() - m_vecHeadGoal).Length(); if (m_flCurrentLength < m_idealLength + m_idealSegmentLength) { TaskComplete(); } } break; default: BaseClass::RunTask( pTask ); break; } }
//========================================================= // Disparo //========================================================= void CWeaponGaussGun::Fire() { CBasePlayer *pOwner = ToBasePlayer(GetOwner()); // ¿El jugador no ha sido creado? if ( !pOwner ) return; m_bCharging = false; if ( m_hViewModel == NULL ) { CBaseViewModel *vm = pOwner->GetViewModel(); if ( vm ) m_hViewModel.Set(vm); } Vector startPos = pOwner->Weapon_ShootPosition(); Vector aimDir = pOwner->GetAutoaimVector(AUTOAIM_5DEGREES); Vector vecUp, vecRight; VectorVectors(aimDir, vecRight, vecUp); float x, y, z; //Gassian spread do { x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); z = x*x+y*y; } while (z > 1); aimDir = aimDir + x * GetBulletSpread().x * vecRight + y * GetBulletSpread().y * vecUp; Vector endPos = startPos + (aimDir * MAX_TRACE_LENGTH); // Shoot a shot straight out trace_t tr; UTIL_TraceLine(startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr); #ifndef CLIENT_DLL ClearMultiDamage(); CBaseEntity *pHit = tr.m_pEnt; CTakeDamageInfo dmgInfo(this, pOwner, sk_plr_dmg_gauss.GetFloat(), DMG_SHOCK | DMG_DISSOLVE); if ( pHit != NULL ) { CalculateBulletDamageForce(&dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos); pHit->DispatchTraceAttack(dmgInfo, aimDir, &tr); } if ( tr.DidHitWorld() ) { float hitAngle = -DotProduct( tr.plane.normal, aimDir ); if ( hitAngle < 0.5f ) { Vector vReflection; vReflection = 2.0 * tr.plane.normal * hitAngle + aimDir; startPos = tr.endpos; endPos = startPos + (vReflection * MAX_TRACE_LENGTH); // Draw beam to reflection point DrawBeam(tr.startpos, tr.endpos, 15, true); CPVSFilter filter(tr.endpos); te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0); UTIL_ImpactTrace(&tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss"); //Find new reflection end position UTIL_TraceLine(startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr); if ( tr.m_pEnt != NULL ) { dmgInfo.SetDamageForce(GetAmmoDef()->DamageForce(m_iPrimaryAmmoType) * vReflection); dmgInfo.SetDamagePosition(tr.endpos); tr.m_pEnt->DispatchTraceAttack(dmgInfo, vReflection, &tr); } // Connect reflection point to end DrawBeam(tr.startpos, tr.endpos, 10); } else DrawBeam(tr.startpos, tr.endpos, 15, true); } else DrawBeam(tr.startpos, tr.endpos, 15, true); ApplyMultiDamage(); #endif UTIL_ImpactTrace(&tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss"); CPVSFilter filter(tr.endpos); te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0); m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f; AddViewKick(); // Register a muzzleflash for the AI #ifndef CLIENT_DLL pOwner->SetMuzzleFlashTime(gpGlobals->curtime + 0.5); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_WaterExplosionEffect::CreateCore( void ) { if ( m_fFlags & TE_EXPLFLAG_NOFIREBALL ) return; // Get our lighting information for the water surface Vector color; float luminosity; FX_GetSplashLighting( m_vecWaterSurface + Vector( 0, 0, 8 ), &color, &luminosity ); float lifetime = random->RandomFloat( 0.8f, 1.0f ); // Ground splash FX_AddQuad( m_vecWaterSurface + Vector(0,0,2), Vector(0,0,1), 64, 64 * 4.0f, 0.85f, luminosity, 0.0f, 0.25f, random->RandomInt( 0, 360 ), random->RandomFloat( -4, 4 ), color, 2.0f, "effects/splashwake1", (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); Vector vRight, vUp; VectorVectors( Vector(0,0,1) , vRight, vUp ); Vector start, end; float radius = 50.0f; unsigned int flags; // Base vertical shaft FXLineData_t lineData; start = m_vecWaterSurface; end = start + ( Vector( 0, 0, 1 ) * random->RandomFloat( radius, radius*1.5f ) ); if ( random->RandomInt( 0, 1 ) ) { flags |= FXSTATICLINE_FLIP_HORIZONTAL; } else { flags = 0; } lineData.m_flDieTime = lifetime * 0.5f; lineData.m_flStartAlpha= luminosity; lineData.m_flEndAlpha = 0.0f; lineData.m_flStartScale = radius*0.5f; lineData.m_flEndScale = radius*2; lineData.m_pMaterial = materials->FindMaterial( "effects/splash3", 0, 0 ); lineData.m_vecStart = start; lineData.m_vecStartVelocity = vec3_origin; lineData.m_vecEnd = end; lineData.m_vecEndVelocity = Vector(0,0,random->RandomFloat( 650, 750 )); FX_AddLine( lineData ); // Inner filler shaft start = m_vecWaterSurface; end = start + ( Vector(0,0,1) * random->RandomFloat( 32, 64 ) ); if ( random->RandomInt( 0, 1 ) ) { flags |= FXSTATICLINE_FLIP_HORIZONTAL; } else { flags = 0; } lineData.m_flDieTime = lifetime * 0.5f; lineData.m_flStartAlpha= luminosity; lineData.m_flEndAlpha = 0.0f; lineData.m_flStartScale = radius; lineData.m_flEndScale = radius*2; lineData.m_pMaterial = materials->FindMaterial( "effects/splash3", 0, 0 ); lineData.m_vecStart = start; lineData.m_vecStartVelocity = vec3_origin; lineData.m_vecEnd = end; lineData.m_vecEndVelocity = Vector(0,0,1) * random->RandomFloat( 64, 128 ); FX_AddLine( lineData ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_BaseExplosionEffect::CreateCore( void ) { if ( m_fFlags & TE_EXPLFLAG_NOFIREBALL ) return; Vector offset; int i; //Spread constricts as force rises float force = m_flForce; //Cap our force if ( force < EXPLOSION_FORCE_MIN ) force = EXPLOSION_FORCE_MIN; if ( force > EXPLOSION_FORCE_MAX ) force = EXPLOSION_FORCE_MAX; float spread = 1.0f - (0.15f*force); SimpleParticle *pParticle; CSmartPtr<CExplosionParticle> pSimple = CExplosionParticle::Create( "exp_smoke" ); pSimple->SetSortOrigin( m_vecOrigin ); pSimple->SetNearClip( 64, 128 ); pSimple->GetBinding().SetBBox( m_vecOrigin - Vector( 128, 128, 128 ), m_vecOrigin + Vector( 128, 128, 128 ) ); if ( m_Material_Smoke == NULL ) { m_Material_Smoke = g_Mat_DustPuff[1]; } //FIXME: Better sampling area offset = m_vecOrigin + ( m_vecDirection * 32.0f ); //Find area ambient light color and use it to tint smoke Vector worldLight = WorldGetLightForPoint( offset, true ); Vector tint; float luminosity; if ( worldLight == vec3_origin ) { tint = vec3_origin; luminosity = 0.0f; } else { UTIL_GetNormalizedColorTintAndLuminosity( worldLight, &tint, &luminosity ); } // We only take a portion of the tint tint = (tint * 0.25f)+(Vector(0.75f,0.75f,0.75f)); // Rescale to a character range luminosity *= 255; if ( (m_fFlags & TE_EXPLFLAG_NOFIREBALLSMOKE) == 0 ) { // // Smoke - basic internal filler // for ( i = 0; i < 4; i++ ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, m_vecOrigin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; #ifdef INVASION_CLIENT_DLL pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); #endif #ifdef _XBOX pParticle->m_flDieTime = 1.0f; #else pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f ); #endif pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( m_vecDirection * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 1, 750 ) * force; //Scale the force down as we fall away from our main direction ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread, &fForce ); pParticle->m_vecVelocity *= fForce; #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif int nColor = random->RandomInt( luminosity*0.5f, luminosity ); pParticle->m_uchColor[0] = ( worldLight[0] * nColor ); pParticle->m_uchColor[1] = ( worldLight[1] * nColor ); pParticle->m_uchColor[2] = ( worldLight[2] * nColor ); pParticle->m_uchStartSize = 72; pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); } } // // Inner core // #ifndef _XBOX for ( i = 0; i < 8; i++ ) { offset.Random( -16.0f, 16.0f ); offset += m_vecOrigin; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; #ifdef INVASION_CLIENT_DLL pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); #else pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); #endif pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( m_vecDirection * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 1, 2000 ) * force; //Scale the force down as we fall away from our main direction ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread, &fForce ); pParticle->m_vecVelocity *= fForce; #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif int nColor = random->RandomInt( luminosity*0.5f, luminosity ); pParticle->m_uchColor[0] = ( worldLight[0] * nColor ); pParticle->m_uchColor[1] = ( worldLight[1] * nColor ); pParticle->m_uchColor[2] = ( worldLight[2] * nColor ); pParticle->m_uchStartSize = random->RandomInt( 32, 64 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2; pParticle->m_uchStartAlpha = random->RandomFloat( 128, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); } } #endif // !_XBOX // // Ground ring // Vector vRight, vUp; VectorVectors( m_vecDirection, vRight, vUp ); Vector forward; #ifndef INVASION_CLIENT_DLL #ifndef _XBOX int numRingSprites = 32; #else int numRingSprites = 8; #endif float flIncr = (2*M_PI) / (float) numRingSprites; // Radians float flYaw = 0.0f; for ( i = 0; i < numRingSprites; i++ ) { flYaw += flIncr; SinCos( flYaw, &forward.y, &forward.x ); forward.z = 0.0f; offset = ( RandomVector( -4.0f, 4.0f ) + m_vecOrigin ) + ( forward * random->RandomFloat( 8.0f, 16.0f ) ); pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.5f ); pParticle->m_vecVelocity = forward; float fForce = random->RandomFloat( 500, 2000 ) * force; //Scale the force down as we fall away from our main direction ScaleForceByDeviation( pParticle->m_vecVelocity, pParticle->m_vecVelocity, spread, &fForce ); pParticle->m_vecVelocity *= fForce; #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif int nColor = random->RandomInt( luminosity*0.5f, luminosity ); pParticle->m_uchColor[0] = ( worldLight[0] * nColor ); pParticle->m_uchColor[1] = ( worldLight[1] * nColor ); pParticle->m_uchColor[2] = ( worldLight[2] * nColor ); pParticle->m_uchStartSize = random->RandomInt( 16, 32 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomFloat( 16, 32 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); } } #endif } #ifndef _XBOX // // Embers // if ( m_Material_Embers[0] == NULL ) { m_Material_Embers[0] = pSimple->GetPMaterial( "effects/fire_embers1" ); } if ( m_Material_Embers[1] == NULL ) { m_Material_Embers[1] = pSimple->GetPMaterial( "effects/fire_embers2" ); } for ( i = 0; i < 16; i++ ) { offset.Random( -32.0f, 32.0f ); offset += m_vecOrigin; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Embers[random->RandomInt(0,1)], offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f ); pParticle->m_vecVelocity.Random( -spread*2, spread*2 ); pParticle->m_vecVelocity += m_vecDirection; VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 1.0f, 400.0f ); //Scale the force down as we fall away from our main direction float vDev = ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread ); pParticle->m_vecVelocity *= fForce * ( 16.0f * (vDev*vDev*0.5f) ); #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif int nColor = random->RandomInt( 192, 255 ); pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = nColor; pParticle->m_uchStartSize = random->RandomInt( 8, 16 ) * vDev; pParticle->m_uchStartSize = clamp( pParticle->m_uchStartSize, 4, 32 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); } } #endif // !_XBOX // // Fireballs // if ( m_Material_FireCloud == NULL ) { m_Material_FireCloud = pSimple->GetPMaterial( "effects/fire_cloud2" ); } #ifndef _XBOX int numFireballs = 32; #else int numFireballs = 16; #endif for ( i = 0; i < numFireballs; i++ ) { offset.Random( -48.0f, 48.0f ); offset += m_vecOrigin; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_FireCloud, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.2f, 0.4f ); pParticle->m_vecVelocity.Random( -spread*0.75f, spread*0.75f ); pParticle->m_vecVelocity += m_vecDirection; VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 400.0f, 800.0f ); //Scale the force down as we fall away from our main direction float vDev = ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread ); pParticle->m_vecVelocity *= fForce * ( 16.0f * (vDev*vDev*0.5f) ); #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif int nColor = random->RandomInt( 128, 255 ); pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = nColor; pParticle->m_uchStartSize = random->RandomInt( 32, 85 ) * vDev; pParticle->m_uchStartSize = clamp( pParticle->m_uchStartSize, 32, 85 ); pParticle->m_uchEndSize = (int)((float)pParticle->m_uchStartSize * 1.5f); pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : &data - //----------------------------------------------------------------------------- void AR2ExplosionCallback( const CEffectData &data ) { float lifetime = random->RandomFloat( 0.4f, 0.75f ); // Ground splash FX_AddQuad( data.m_vOrigin, data.m_vNormal, data.m_flRadius, data.m_flRadius * 4.0f, 0.85f, 1.0f, 0.0f, 0.25f, random->RandomInt( 0, 360 ), random->RandomFloat( -4, 4 ), Vector( 1.0f, 1.0f, 1.0f ), lifetime, "effects/combinemuzzle1", (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); Vector vRight, vUp; VectorVectors( data.m_vNormal, vRight, vUp ); Vector start, end; float radius = data.m_flRadius * 0.15f; // Base vertical shaft FXLineData_t lineData; start = data.m_vOrigin; end = start + ( data.m_vNormal * random->RandomFloat( radius*2.0f, radius*4.0f ) ); lineData.m_flDieTime = lifetime; lineData.m_flStartAlpha= 1.0f; lineData.m_flEndAlpha = 0.0f; lineData.m_flStartScale = radius*4; lineData.m_flEndScale = radius*5; lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 ); lineData.m_vecStart = start; lineData.m_vecStartVelocity = vec3_origin; lineData.m_vecEnd = end; lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 200, 350 ); FX_AddLine( lineData ); // Inner filler shaft start = data.m_vOrigin; end = start + ( data.m_vNormal * random->RandomFloat( 16, radius*0.25f ) ); lineData.m_flDieTime = lifetime - 0.1f; lineData.m_flStartAlpha= 1.0f; lineData.m_flEndAlpha = 0.0f; lineData.m_flStartScale = radius*2; lineData.m_flEndScale = radius*4; lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 ); lineData.m_vecStart = start; lineData.m_vecStartVelocity = vec3_origin; lineData.m_vecEnd = end; lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 64, 128 ); FX_AddLine( lineData ); }
void CFXCharSprite::Draw( ) { float scale = m_FXData.m_flStartScale; float alpha = m_FXData.m_flStartAlpha; //Bind the material CMatRenderContextPtr pRenderContext( materials ); IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector pos; Vector vRight, vUp; float color[4]; color[0] = m_FXData.m_Color[0]; color[1] = m_FXData.m_Color[1]; color[2] = m_FXData.m_Color[2]; color[3] = alpha; VectorVectors( m_FXData.m_vecNormal, vRight, vUp ); Vector rRight, rUp; rRight = ( vRight * cos( DEG2RAD( m_FXData.m_flYaw ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw ) ) ); rUp = ( vRight * cos( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) ); vRight = rRight * ( scale * 0.5f ); vUp = rUp * ( scale * 0.5f ); pos = m_FXData.m_vecOrigin + vRight - vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin - vRight - vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin - vRight + vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin + vRight + vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void ScratchPad_DrawLitCylinder( IScratchPad3D *pPad, const Vector &v1, const Vector &v2, const Vector &vBrightColor, const Vector &vDarkColor, const Vector &vLightDir, float width, int nSegments ) { // Make orthogonal vectors. Vector vDir = v2 - v1; VectorNormalize( vDir ); Vector vRight, vUp; VectorVectors( vDir, vRight, vUp ); vRight *= width; vUp *= width; // Setup the top and bottom caps. CSPVertList topCap, bottomCap, quad; topCap.m_Verts.SetSize( nSegments ); bottomCap.m_Verts.SetSize( nSegments ); quad.m_Verts.SetSize( 4 ); float flDot = -vLightDir.Dot( vDir ); Vector topColor, bottomColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), topColor ); VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); // Draw each quad. Vector vPrevTop = v1 + vRight; Vector vPrevBottom = v2 + vRight; for ( int i=0; i < nSegments; i++ ) { float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); Vector vCurTop = v1 + vOffset; Vector vCurBottom = v2 + vOffset; // Now light it. VectorNormalize( vOffset ); flDot = -vLightDir.Dot( vOffset ); Vector vColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); // Draw the quad. quad.m_Verts[0] = CSPVert( vPrevTop, vColor ); quad.m_Verts[1] = CSPVert( vPrevBottom, vColor ); quad.m_Verts[2] = CSPVert( vCurBottom, vColor ); quad.m_Verts[3] = CSPVert( vCurTop, vColor ); pPad->DrawPolygon( quad ); topCap.m_Verts[i] = CSPVert( vCurTop, topColor ); bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); } pPad->DrawPolygon( topCap ); pPad->DrawPolygon( bottomCap ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponGauss::Fire( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( pOwner == NULL ) return; m_bCharging = false; Vector startPos= pOwner->Weapon_ShootPosition(); Vector aimDir = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES ); Vector vecUp, vecRight; VectorVectors( aimDir, vecRight, vecUp ); float x, y, z; //Gassian spread do { x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); z = x*x+y*y; } while (z > 1); Vector endPos = startPos + ( aimDir * MAX_TRACE_LENGTH ); //Shoot a shot straight out trace_t tr; UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr ); #ifndef CLIENT_DLL ClearMultiDamage(); #endif CBaseEntity *pHit = tr.m_pEnt; #ifndef CLIENT_DLL CTakeDamageInfo dmgInfo( this, pOwner, sk_dmg_gauss.GetFloat(), DMG_SHOCK | DMG_BULLET ); #endif if ( pHit != NULL ) { #ifndef CLIENT_DLL CalculateBulletDamageForce( &dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos, 7.0f * 5.0f ); pHit->DispatchTraceAttack( dmgInfo, aimDir, &tr ); #endif } if ( tr.DidHitWorld() ) { float hitAngle = -DotProduct( tr.plane.normal, aimDir ); if ( hitAngle < 0.5f ) { Vector vReflection; vReflection = 2.0 * tr.plane.normal * hitAngle + aimDir; startPos = tr.endpos; endPos = startPos + ( vReflection * MAX_TRACE_LENGTH ); //Draw beam to reflection point DrawBeam( tr.startpos, tr.endpos, 1.6, true ); CPVSFilter filter( tr.endpos ); te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 ); UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" ); //Find new reflection end position UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr ); if ( tr.m_pEnt != NULL ) { #ifndef CLIENT_DLL dmgInfo.SetDamageForce( GetAmmoDef()->DamageForce(m_iPrimaryAmmoType) * vReflection ); dmgInfo.SetDamagePosition( tr.endpos ); tr.m_pEnt->DispatchTraceAttack( dmgInfo, vReflection, &tr ); #endif } //Connect reflection point to end DrawBeam( tr.startpos, tr.endpos, 0.4 ); } else { DrawBeam( tr.startpos, tr.endpos, 1.6, true ); } } else { DrawBeam( tr.startpos, tr.endpos, 1.6, true ); } #ifndef CLIENT_DLL ApplyMultiDamage(); #endif UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" ); CPVSFilter filter( tr.endpos ); te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 ); m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f; AddViewKick(); return; }
//----------------------------------------------------------------------------- // Purpose: // Input : frametime - //----------------------------------------------------------------------------- void CFXQuad::Draw( double frametime ) { VPROF_BUDGET( "FX_Quad::Draw", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); // Update the effect Update( frametime ); float scaleTimePerc, alphaTimePerc; //Determine the scale if ( m_FXData.m_uiFlags & FXQUAD_BIAS_SCALE ) { scaleTimePerc = Bias( ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ), m_FXData.m_flScaleBias ); } else { scaleTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ); } float scale = m_FXData.m_flStartScale + ( ( m_FXData.m_flEndScale - m_FXData.m_flStartScale ) * scaleTimePerc ); //Determine the alpha if ( m_FXData.m_uiFlags & FXQUAD_BIAS_ALPHA ) { alphaTimePerc = Bias( ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ), m_FXData.m_flAlphaBias ); } else { alphaTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ); } float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * alphaTimePerc ); alpha = clamp( alpha, 0.0f, 1.0f ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); //Update our roll m_FXData.m_flYaw = anglemod( m_FXData.m_flYaw + ( m_FXData.m_flDeltaYaw * frametime ) ); Vector pos; Vector vRight, vUp; float color[4]; color[0] = m_FXData.m_Color[0]; color[1] = m_FXData.m_Color[1]; color[2] = m_FXData.m_Color[2]; if ( m_FXData.m_uiFlags & FXQUAD_COLOR_FADE ) { color[0] *= alpha; color[1] *= alpha; color[2] *= alpha; } color[3] = alpha; VectorVectors( m_FXData.m_vecNormal, vRight, vUp ); Vector rRight, rUp; rRight = ( vRight * cos( DEG2RAD( m_FXData.m_flYaw ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw ) ) ); rUp = ( vRight * cos( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) ); vRight = rRight * ( scale * 0.5f ); vUp = rUp * ( scale * 0.5f ); pos = m_FXData.m_vecOrigin + vRight - vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin - vRight - vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin - vRight + vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); pos = m_FXData.m_vecOrigin + vRight + vUp; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4fv( color ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }