void CGibFX::CreateLingeringSmoke(int nIndex) { CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr(); if (!psfxMgr) return; CGameSettings* pSettings = g_pInterfaceMgr->GetSettings(); if (!pSettings) return; uint8 nDetailLevel = pSettings->SpecialFXSetting(); if (nDetailLevel == RS_LOW) return; SMCREATESTRUCT sm; char* pTexture = "Sprites\\SmokeTest.spr"; VEC_SET(sm.vColor1, 100.0f, 100.0f, 100.0f); VEC_SET(sm.vColor2, 125.0f, 125.0f, 125.0f); VEC_SET(sm.vMinDriftVel, -10.0f, 25.0f, -10.0f); VEC_SET(sm.vMaxDriftVel, 10.0f, 50.0f, 10.0f); LTFLOAT fVolumeRadius = 10.0f; LTFLOAT fLifeTime = GetRandom(m_fLifeTime * 0.75f, m_fLifeTime); LTFLOAT fRadius = 1500; LTFLOAT fParticleCreateDelta = 0.1f; LTFLOAT fMinParticleLife = 1.0f; LTFLOAT fMaxParticleLife = 5.0f; uint8 nNumParticles = 3; LTBOOL bIgnoreWind = LTFALSE; if (IsLiquid(m_eCode)) { GetLiquidColorRange(m_eCode, &sm.vColor1, &sm.vColor2); pTexture = DEFAULT_BUBBLE_TEXTURE; fRadius = 750.0f; bIgnoreWind = LTTRUE; fMinParticleLife = 1.0f; fMaxParticleLife = 1.5f; } sm.vPos = m_Emitters[nIndex].m_vPos; sm.hServerObj = m_hGib[nIndex]; sm.fVolumeRadius = fVolumeRadius; sm.fLifeTime = fLifeTime; sm.fRadius = fRadius; sm.fParticleCreateDelta = fParticleCreateDelta; sm.fMinParticleLife = fMinParticleLife; sm.fMaxParticleLife = fMaxParticleLife; sm.nNumParticles = nNumParticles; sm.bIgnoreWind = bIgnoreWind; sm.hstrTexture = m_pClientDE->CreateString(pTexture); psfxMgr->CreateSFX(SFX_SMOKE_ID, &sm); m_pClientDE->FreeString(sm.hstrTexture); }
void CWeaponFX::CreateMuzzleFX() { CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr(); if (!psfxMgr) return; char* pTexture = "SFX\\Impact\\Spr\\Smoke.spr"; if (IsLiquid(m_eFirePosCode)) { pTexture = DEFAULT_BUBBLE_TEXTURE; } PARTICLESHOWERCREATESTRUCT sp; sp.vPos = m_vFirePos; sp.vDir = m_vSurfaceNormal * 10.0f; sp.pTexture = pTexture; sp.nParticles = 1; sp.fRadius = 400.0f; sp.fDuration = 1.0f; sp.fEmissionRadius = 0.05f; sp.fRadius = 800.0f; sp.fGravity = 0.0f; sp.vColor1.Init(100.0f, 100.0f, 100.0f); sp.vColor2.Init(125.0f, 125.0f, 125.0f); if (IsLiquid(m_eFirePosCode)) { GetLiquidColorRange(m_eFirePosCode, &sp.vColor1, &sp.vColor2); sp.fRadius = 600.0f; sp.fGravity = 50.0f; } psfxMgr->CreateSFX(SFX_PARTICLESHOWER_ID, &sp); }
LTBOOL CBulletTrailFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); if (m_bFirstUpdate) { // See if we can figure out what color bubbles to make, based on the // container we start in... HLOCALOBJ objList[1]; uint32 dwNum = m_pClientDE->GetPointContainers(&m_vStartPos, objList, 1); if (dwNum > 0 && objList[0]) { uint32 dwUserFlags; m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags); if (dwUserFlags & USRFLG_VISIBLE) { uint16 dwCode; if (m_pClientDE->GetContainerCode(objList[0], &dwCode)) { GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2); } } } // Move the particle system to the correct position... m_pClientDE->SetObjectPos(m_hObject, &m_vStartPos); m_bFirstUpdate = LTFALSE; m_fStartTime = fTime; m_fLastTime = fTime; VEC_INIT(m_vLastPos); // Find the end position... ClientIntersectQuery iQuery; ClientIntersectInfo iInfo; LTVector vTemp, vEndPoint; VEC_MULSCALAR(vTemp, m_vDir, MAX_TRAIL_LENGTH); VEC_ADD(vEndPoint, m_vStartPos, vTemp); VEC_COPY(iQuery.m_From, m_vStartPos); VEC_COPY(iQuery.m_To, vEndPoint); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vEndPoint, iInfo.m_Point, m_vStartPos); m_fDistance = VEC_MAG(vEndPoint); } if (m_fDistance <= 0.0f || m_fFadeTime <= 0.0f) return LTFALSE; // Calculate the trail velocity... m_fTrailVel = m_fDistance / m_fFadeTime; VEC_MULSCALAR(m_vDir, m_vDir, m_fTrailVel); } // Check to see if we should just wait for last bubble to go away... if (fTime > m_fStartTime + m_fFadeTime) { if (fTime > m_fLastTime + m_fLifeTime) { return LTFALSE; } LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime; // m_pClientDE->SetParticleSystemColorScale(m_hObject, fScale); LTFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); return LTTRUE; } // Create the necessary particles... LTFLOAT fTimeOffset = g_pGameClientShell->GetFrameTime(); // Calculate distance traveled this frame... LTFLOAT fDist = m_fTrailVel * fTimeOffset; if (fDist > m_fDistance) fDist = m_fDistance; m_fDistTraveled += fDist; if (m_fDistTraveled > m_fDistance) { fDist = m_fDistance - (m_fDistTraveled - fDist); if (fDist <= 0.0f) return LTTRUE; } // Calculate number of particles to create... LTFLOAT fNumParticles = fDist * m_fNumParticles / m_fDistance; // Calculate starting bubble position... LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor; VEC_MULSCALAR(vTemp, m_vDir, fTimeOffset); VEC_ADD(vCurPos, m_vLastPos, vTemp); // What is the range of colors? LTFLOAT fRange = m_vColor2.x - m_vColor1.x; // Fill the distance between the last projectile position, and it's // current position with bubbles... VEC_SUB(vTemp, vCurPos, m_vLastPos); VEC_MULSCALAR(vDelta, vTemp, 1.0f/fNumParticles); VEC_COPY(vPos, m_vLastPos); LTFLOAT fLifeTime = 100.0f; LTFLOAT fOffset = 0.0f; LTVector vDriftOffset; VEC_SET(vDriftOffset, 0.0f, 0.0f, 0.0f); int nNumParticles = GetNumParticles((int)fNumParticles); for (int i=0; i < nNumParticles; i++) { // Build the individual bubbless... for (int j=0; j < 1; j++) { VEC_COPY(vTemp, vPos); VEC_SET(vDriftVel, 0.0f, GetRandom(5.0f, 6.0f), 0.0f); vTemp.x += GetRandom(-fOffset, fOffset); vTemp.y += GetRandom(-fOffset, fOffset); vTemp.z += GetRandom(-fOffset, fOffset); GetRandomColorInRange(vColor); m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fLifeTime); } VEC_ADD(vPos, vPos, vDelta); } VEC_COPY(m_vLastPos, vCurPos); m_fLastTime = fTime; return LTTRUE; }
LTBOOL CParticleTrailSegmentFX::CreateObject(ILTClient *pClientDE) { if (!pClientDE || !m_hServerObject) return LTFALSE; if (m_nType & PT_SMOKE_LONG) { m_pTextureName = "SFX\\Smoke\\Spr\\WhiteTrailLong.spr"; m_basecs.bAdjustParticleScale = LTTRUE; m_basecs.fStartParticleScale = g_cvarSmokeTrailStartScale.GetFloat(); m_basecs.fEndParticleScale = g_cvarSmokeTrailLWEndScale.GetFloat(); m_basecs.bAdjustParticleAlpha = LTTRUE; m_basecs.fStartParticleAlpha = g_cvarSmokeTrailStartAlpha.GetFloat(); m_basecs.fEndParticleAlpha = g_cvarSmokeTrailEndAlpha.GetFloat(); } else if (m_nType & PT_SMOKE) { m_pTextureName = "SFX\\Smoke\\Spr\\WhiteTrailShort.spr"; m_basecs.bAdjustParticleScale = LTTRUE; m_basecs.fStartParticleScale = g_cvarSmokeTrailStartScale.GetFloat(); m_basecs.fEndParticleScale = g_cvarSmokeTrailSWEndScale.GetFloat(); m_basecs.bAdjustParticleAlpha = LTTRUE; m_basecs.fStartParticleAlpha = g_cvarSmokeTrailStartAlpha.GetFloat(); m_basecs.fEndParticleAlpha = g_cvarSmokeTrailEndAlpha.GetFloat(); } else if (m_nType & PT_SMOKE_BLACK) { m_pTextureName = "SFX\\Smoke\\Spr\\BlackTrailShort.spr"; m_basecs.bAdjustParticleScale = LTTRUE; m_basecs.fStartParticleScale = g_cvarSmokeTrailStartScale.GetFloat(); m_basecs.fEndParticleScale = g_cvarSmokeTrailSBEndScale.GetFloat(); m_basecs.bAdjustParticleAlpha = LTTRUE; m_basecs.fStartParticleAlpha = g_cvarSmokeTrailStartAlpha.GetFloat(); m_basecs.fEndParticleAlpha = g_cvarSmokeTrailEndAlpha.GetFloat(); } else if ((m_nType & PT_GIBSMOKE)) { m_pTextureName = "SFX\\Impact\\Spr\\Smoke.spr"; m_basecs.bAdjustParticleScale = LTTRUE; m_basecs.fStartParticleScale = g_cvarSmokeTrailStartScale.GetFloat(); m_basecs.fEndParticleScale = g_cvarSmokeTrailSWEndScale.GetFloat(); m_basecs.bAdjustParticleAlpha = LTTRUE; m_basecs.fStartParticleAlpha = g_cvarSmokeTrailStartAlpha.GetFloat(); m_basecs.fEndParticleAlpha = g_cvarSmokeTrailEndAlpha.GetFloat(); } else if (m_nType & PT_BLOOD) { if (GetRandom(0, 1) == 0) { m_pTextureName = "SFX\\Particle\\Blood_1.dtx"; } else { m_pTextureName = "SFX\\Particle\\Blood_2.dtx"; } } // Determine if we are in a liquid... LTVector vPos; pClientDE->GetObjectPos(m_hServerObject, &vPos); HLOCALOBJ objList[1]; uint32 dwNum = pClientDE->GetPointContainers(&vPos, objList, 1); if (dwNum > 0 && objList[0]) { uint32 dwUserFlags; pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags); if (dwUserFlags & USRFLG_VISIBLE) { uint16 dwCode; if (pClientDE->GetContainerCode(objList[0], &dwCode)) { if (IsLiquid((ContainerCode)dwCode)) { // Don't create blood under water... if (m_nType & PT_BLOOD) { m_bWantRemove = LTTRUE; m_fLifeTime = 0.0f; m_fFadeTime = 0.0f; return LTFALSE; } m_fRadius = 500.0f; m_fGravity = 5.0f; m_nNumPerPuff *= 3; m_bIgnoreWind = LTTRUE; m_pTextureName = DEFAULT_BUBBLE_TEXTURE; GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2); } } } } return CBaseParticleSystemFX::CreateObject(pClientDE); }