LTBOOL CPickupItemFX::Update() { if (!m_pClientDE || m_bWantRemove || !m_hServerObject) return LTFALSE; LTFLOAT fDeltaTime = g_pGameClientShell->GetFrameTime(); if (m_bRotate) { LTRotation rRot; g_pLTClient->GetObjectRotation(m_hServerObject, &rRot); rRot.Rotate(rRot.Up(), PICKUPITEM_ROTVEL * fDeltaTime); g_pLTClient->SetObjectRotation(m_hServerObject, &rRot); } if (m_bBounce) { } // If we have a ClientFX that is playing hide or show it based on the serverobject... if( m_linkClientFX.IsValid() ) { uint32 dwFlags; g_pCommonLT->GetObjectFlags( m_hServerObject, OFT_Flags, dwFlags ); if( dwFlags & FLAG_VISIBLE ) { m_linkClientFX.GetInstance()->Show(); } else { m_linkClientFX.GetInstance()->Hide(); } } return LTTRUE; }
LTBOOL CShellCasingFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; if (g_pGameClientShell->IsServerPaused()) { return LTTRUE; } m_fElapsedTime += g_pGameClientShell->GetFrameTime(); m_fDieTime -= g_pGameClientShell->GetFrameTime(); if (m_fDieTime <= 0.0f) return LTFALSE; // Update object scale if necessary... LTVector vScale; m_pClientDE->GetObjectScale(m_hObject, &vScale); if (vScale != m_vFinalScale) { if (m_fElapsedTime <= g_vtShellScaleTime.GetFloat()) { LTVector vScaleRange = (m_vFinalScale - m_vInitialScale); vScale = m_vInitialScale + (vScaleRange * (m_fElapsedTime/g_vtShellScaleTime.GetFloat())); if (vScale > m_vFinalScale) { vScale = m_vFinalScale; } m_pClientDE->SetObjectScale(m_hObject, &vScale); } else { m_pClientDE->SetObjectScale(m_hObject, &m_vFinalScale); } } if (m_bResting) return LTTRUE; LTRotation rRot; g_pLTClient->GetObjectRotation(m_hObject, &rRot); // If velocity slows enough, and we're on the ground, just stop bouncing and just wait to expire. if (m_movingObj.m_dwPhysicsFlags & MO_RESTING) { m_bResting = LTTRUE; // Stop the spinning... rRot.Rotate(rRot.Up(), m_fYaw); g_pLTClient->SetObjectRotation(m_hObject, &rRot); // Shell is at rest, we can add a check here to see if we really want // to keep it around depending on detail settings... //HLOCALOBJ hObjs[1]; //uint32 nNumFound, nBogus; //m_pClientDE->FindObjectsInSphere(&m_movingObj.m_vPos, 64.0f, hObjs, 1, &nBogus, &nNumFound); // Remove thyself... //if (nNumFound > 15) return LTFALSE; } else { if (m_fPitchVel != 0 || m_fYawVel != 0) { LTFLOAT fDeltaTime = g_pGameClientShell->GetFrameTime(); m_fPitch += m_fPitchVel * fDeltaTime; m_fYaw += m_fYawVel * fDeltaTime; rRot.Rotate(rRot.Up(), m_fYaw); rRot.Rotate(rRot.Right(), m_fPitch); g_pLTClient->SetObjectRotation(m_hObject, &rRot); } } LTVector vNewPos; if (UpdateMovingObject(LTNULL, &m_movingObj, vNewPos)) { ClientIntersectInfo info; LTBOOL bBouncedOnGround = LTFALSE; if (BounceMovingObject(LTNULL, &m_movingObj, vNewPos, &info, INTERSECT_HPOLY, true, bBouncedOnGround)) { // If we hit the sky/invisible surface we're done... SurfaceType eType = GetSurfaceType(info); if (eType == ST_SKY || eType == ST_INVISIBLE) { return LTFALSE; } if (m_nBounceCount >= MAX_BOUNCE_COUNT) { if (!(m_movingObj.m_dwPhysicsFlags & MO_LIQUID)) { SURFACE* pSurf = g_pSurfaceMgr->GetSurface(eType); if (pSurf) { // Play appropriate sound... if (pSurf->szShellImpactSnds[0]) { g_pClientSoundMgr->PlaySoundFromPos(vNewPos, pSurf->szShellImpactSnds[0], pSurf->fShellSndRadius, SOUNDPRIORITY_MISC_LOW); } } } } // Adjust the bouncing.. m_fPitchVel *= 0.75f; m_fYawVel *= -0.75f; m_nBounceCount--; if (m_nBounceCount <= 0) { m_movingObj.m_dwPhysicsFlags |= MO_RESTING; } } m_movingObj.m_vPos = vNewPos; if (g_pCommonLT->GetPointStatus(&vNewPos) == LT_OUTSIDE) { return LTFALSE; } g_pLTClient->SetObjectPos(m_hObject, &vNewPos); } return LTTRUE; }
LTBOOL CParticleSystemFX::Update() { if (!m_hObject || !m_pClientDE || m_bWantRemove) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); // Hide/show the particle system if necessary... if (m_hServerObject) { uint32 dwUserFlags; g_pCommonLT->GetObjectFlags(m_hServerObject, OFT_User, dwUserFlags); if (!(dwUserFlags & USRFLG_VISIBLE)) { uint32 dwFlags; g_pCommonLT->GetObjectFlags(m_hObject, OFT_Flags, dwFlags); // Once last puff as disappeared, hide the system (no new puffs // will be added...) if (dwFlags & FLAG_VISIBLE) { if (fTime > m_fLastTime + m_cs.fParticleLifetime) { g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, 0, FLAG_VISIBLE); } } else { m_fLastTime = fTime; } return LTTRUE; } else { g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE); } } // Debugging aid... if (s_cvarTweak.GetFloat() > 0) { TweakSystem(); } if (m_bFirstUpdate) { m_fLastTime = fTime; m_bFirstUpdate = LTFALSE; } // Make sure it is time to update... if (fTime < m_fLastTime + m_fNextUpdate) { return LTTRUE; } // Ok, how many to add this frame....(make sure time delta is no more than // 15 frames/sec... float fTimeDelta = fTime - m_fLastTime; fTimeDelta = fTimeDelta > 0.0666f ? 0.0666f : fTimeDelta; int nToAdd = (int) floor(m_cs.fParticlesPerSecond * fTimeDelta); nToAdd = LTMIN(nToAdd, (int)(MAX_PARTICLES_PER_SECOND * fTimeDelta)); nToAdd = GetNumParticles(nToAdd); m_pClientDE->AddParticles(m_hObject, nToAdd, &m_vMinOffset, &m_vMaxOffset, // Position offset &(m_cs.vMinVel), &(m_cs.vMaxVel), // Velocity &(m_cs.vColor1), &(m_cs.vColor2), // Color m_cs.fParticleLifetime, m_cs.fParticleLifetime); // Determine when next update should occur... if (m_cs.fBurstWait > 0.001f) { m_fNextUpdate = m_cs.fBurstWait * GetRandom(m_cs.fBurstWaitMin, m_cs.fBurstWaitMax); } else { m_fNextUpdate = 0.001f; } // Rotate the particle system... if (m_cs.fRotationVelocity != 0.0f) { LTRotation rRot; g_pLTClient->GetObjectRotation(m_hObject, &rRot); rRot.Rotate(rRot.Up(), g_pGameClientShell->GetFrameTime() * m_cs.fRotationVelocity); g_pLTClient->SetObjectRotation(m_hObject, &rRot); } m_fLastTime = fTime; return LTTRUE; }
bool CFallingStuffFX::Update(float tmFrameTime) { // Base class update first m_vLastPos = m_vPos; if (!CBaseFX::Update(tmFrameTime)) return false; //increment our emission time by the elapsed frame time m_tmElapsedEmission += tmFrameTime; if (!IsShuttingDown() && !IsSuspended() && (m_tmElapsedEmission > GetProps()->m_tmFallingStuffFXEmission)) { ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(m_scale, m_scale, m_scale); LTVector vInterp; LTVector vInterpCur = m_vPos; // Calculate interpolant for particle system if (GetProps()->m_nFallingStuffFXEmission) { vInterp = m_vPos - m_vLastPos; vInterp /= (float)GetProps()->m_nFallingStuffFXEmission; } for (uint32 i = 0; i < GetProps()->m_nFallingStuffFXEmission; i ++) { ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATABLESPRITE; // Compute the initial position float xRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); float zRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); ocs.m_Pos = m_vPos + (m_vRight * xRand) + (m_vUp * zRand); ocs.m_Scale = vScale; strcpy(ocs.m_Filename, GetProps()->m_sSpriteName); // Move the start point vInterpCur += vInterp; HLOCALOBJ hNewSprite = m_pLTClient->CreateObject(&ocs); if (hNewSprite) { // Create a new sprite FALLING_THING *pNewSprite = debug_new( FALLING_THING ); if (GetProps()->m_nImpactCreate) { if (g_dwSplash > (uint32)GetProps()->m_nImpactCreate) { pNewSprite->m_bSplash = true; g_dwSplash = 0; } else { pNewSprite->m_bSplash = false; } } else { pNewSprite->m_bSplash = false; } g_dwSplash ++; if (pNewSprite) { LTVector v; // Compute the initial velocity v = m_vPlaneDir * GetProps()->m_fVel; pNewSprite->m_hObject = hNewSprite; pNewSprite->m_vVel = v; pNewSprite->m_tmElapsed = 0.0f; pNewSprite->m_vPos = ocs.m_Pos; pNewSprite->m_vLastPos = ocs.m_Pos; m_collSprites.AddTail(pNewSprite); } } } m_tmElapsedEmission = 0.0f; // And store the last position m_vLastPos = m_vPos; } LTMatrix mSpin; if (GetProps()->m_bUseSpin) { // Setup rotation LTMatrix vRight; LTMatrix vUp; LTMatrix vForward; LTMatrix vTmp; Mat_SetupRot(&vRight, &m_vRight, m_xRot); Mat_SetupRot(&vUp, &m_vUp, m_yRot); Mat_SetupRot(&vForward, &m_vPlaneDir, m_zRot); MatMul(&vTmp, &vRight, &vUp); MatMul(&mSpin, &vTmp, &vForward); m_xRot += GetProps()->m_vRotAdd.x * tmFrameTime; m_yRot += GetProps()->m_vRotAdd.y * tmFrameTime; m_zRot += GetProps()->m_vRotAdd.z * tmFrameTime; } // Get the camera rotation LTRotation orient; m_pLTClient->GetObjectRotation(m_hCamera, &orient); LTRotation dRot(orient); LTVector vF = orient.Forward(); float rot = (float)atan2(vF.x, vF.z); // Update the sprites.... CLinkListNode<FALLING_THING *> *pNode = m_collSprites.GetHead(); CLinkListNode<FALLING_THING *> *pDelNode; while (pNode) { pDelNode = NULL; FALLING_THING *pSprite = pNode->m_Data; //adjust our elapsed time pSprite->m_tmElapsed += tmFrameTime; // Check for expiration if (pSprite->m_tmElapsed > GetProps()->m_tmSpriteLifespan) { // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); pDelNode = pNode; } else { // Update !! pSprite->m_vLastPos = pSprite->m_vPos; pSprite->m_vPos += (pSprite->m_vVel * tmFrameTime); // Rotate if neccessary TVector3<float> vPos = pSprite->m_vPos; if (GetProps()->m_bUseSpin) { MatVMul_InPlace(&mSpin, &vPos); } // Add in wind vPos += (GetProps()->m_vWind * GetProps()->m_fWindAmount) * tmFrameTime; // Setup the new sprite position LTVector vPos2 = vPos; m_pLTClient->SetObjectPos(pSprite->m_hObject, &vPos2); // Setup the colour float r, g, b, a; m_pLTClient->GetObjectColor(pSprite->m_hObject, &r, &g, &b, &a); CalcColour(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &r, &g, &b, &a); m_pLTClient->SetObjectColor(pSprite->m_hObject, r, g, b, a); // Setup the scale float scale = 0.1f; CalcScale(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &scale); LTVector vScale; vScale.Init(scale, scale * GetProps()->m_fStretchMul, scale); m_pLTClient->SetObjectScale(pSprite->m_hObject, &vScale); // Setup the rotation dRot = LTRotation(0, 0, 0, 1); LTRotation orient(dRot); orient.Rotate( orient.Up(), rot ); m_pLTClient->SetObjectRotation(pSprite->m_hObject, &orient); // Check to see if we need to start a splash sprite if (pSprite->m_bSplash) { ClientIntersectQuery ciq; ClientIntersectInfo cii; ciq.m_From = pSprite->m_vLastPos; ciq.m_To = pSprite->m_vPos; if ((GetProps()->m_sImpactSpriteName[0]) && (m_pLTClient->IntersectSegment(&ciq, &cii))) { // Create a splash sprite SPLASH *pSplash = debug_new( SPLASH ); ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(0.0f, 0.0f, 0.0f); ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_ROTATABLESPRITE | FLAG_NOLIGHT; ocs.m_Pos = cii.m_Point + (cii.m_Plane.m_Normal * 2.0f); ocs.m_Scale = vScale; LTRotation dOrient( cii.m_Plane.m_Normal, LTVector(0.0f, 1.0f, 0.0f) ); strcpy(ocs.m_Filename, GetProps()->m_sImpactSpriteName); pSplash->m_hObject = m_pLTClient->CreateObject(&ocs); pSplash->m_scale = 0.0f; LTRotation orient(dRot); m_pLTClient->SetObjectRotation(pSplash->m_hObject, &orient); pSplash->m_tmElapsed = 0.0f; m_collSplashes.AddTail(pSplash); // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); // Delete the sprite pDelNode = pNode; } } } pNode = pNode->m_pNext; if (pDelNode) m_collSprites.Remove(pDelNode); } // Update our splashes CLinkListNode<SPLASH *> *pSplashNode = m_collSplashes.GetHead(); while (pSplashNode) { CLinkListNode<SPLASH *> *pDelNode = NULL; SPLASH *pSplash = pSplashNode->m_Data; //update the elapsed time on the splash pSplash->m_tmElapsed += tmFrameTime; // Calculate the new scale float scale = GetProps()->m_fImpactScale1 + ((GetProps()->m_fImpactScale2 - GetProps()->m_fImpactScale1) * (pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan)); LTVector vScale(scale, scale, scale); m_pLTClient->SetObjectScale(pSplash->m_hObject, &vScale); float r, g, b, a; m_pLTClient->GetObjectColor(pSplash->m_hObject, &r, &g, &b, &a); a = (float)(int)(pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan); if (a < 0.0f) a = 0.0f; if (a > 1.0f) a = 1.0f; m_pLTClient->SetObjectColor(pSplash->m_hObject, r, g, b, a); if (pSplash->m_tmElapsed > GetProps()->m_tmImpactLifespan) { m_pLTClient->RemoveObject(pSplash->m_hObject); pDelNode = pSplashNode; } pSplashNode = pSplashNode->m_pNext; if (pDelNode) m_collSplashes.Remove(pDelNode); } // Success !! return true; }
void SecurityCamera::UpdateRotation() { LTFLOAT fTimeDelta = g_pLTServer->GetFrameTime(); if ( m_eState == eStateDetected || m_eState == eStateDestroyed || m_eState == eStateFocusing) { return; } if ( m_eState == eStateTurningTo1 || m_eState == eStateTurningTo2 ) { LTFLOAT fYaw = g_pLTServer->GetFrameTime()*m_fYawSpeed; if ( m_eState == eStateTurningTo1 ) { fYaw = -fYaw; m_fYaw += fYaw; if ( m_fYaw < m_fYaw1 ) { if ( m_fYaw1PauseTime ) { SetState(eStatePausingAt1); } else { SetState(eStateTurningTo2); } } } else { m_fYaw += fYaw; if ( m_fYaw > m_fYaw2 ) { if ( m_fYaw2PauseTime ) { SetState(eStatePausingAt2); } else { SetState(eStateTurningTo1); } } } LTRotation rRot; g_pLTServer->GetObjectRotation(m_hObject, &rRot); rRot.Rotate(rRot.Up(), fYaw); g_pLTServer->SetObjectRotation(m_hObject, &rRot); } if ( m_eState == eStatePausingAt1 ) { m_fYawPauseTimer += fTimeDelta; if ( m_fYawPauseTimer > m_fYaw1PauseTime ) { m_fYawPauseTimer = 0.0f; SetState(eStateTurningTo2); } } if ( m_eState == eStatePausingAt2 ) { m_fYawPauseTimer += fTimeDelta; if ( m_fYawPauseTimer > m_fYaw2PauseTime ) { m_fYawPauseTimer = 0.0f; SetState(eStateTurningTo1); } } }
LTBOOL CParticleExplosionFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; if (!CBaseParticleSystemFX::Update()) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); if (m_bFirstUpdate) { m_bFirstUpdate = LTFALSE; m_fStartTime = fTime; m_fLastTime = fTime; } // Check to see if we should start fading the system... if (fTime > m_fStartTime + m_fFadeTime) { LTFLOAT fEndTime = m_fStartTime + m_fLifeTime; if (fTime > fEndTime) { return LTFALSE; } LTFLOAT fScale = (fEndTime - fTime) / (m_fLifeTime - m_fFadeTime); LTFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); } // See if it is time to create a new Particle puff... if (fTime >= m_fLastTime + m_fOffsetTime) { // Loop over our list of Emitters, creating new particles... for (int i=0; i < m_nNumEmitters; i++) { if (m_ActiveEmitters[i]) { AddParticles(&m_Emitters[i]); } } m_fLastTime = fTime; } // Loop over our list of Emitters, updating the position of each for (int i=0; i < m_nNumEmitters; i++) { if (m_ActiveEmitters[i]) { LTBOOL bBounced = LTFALSE; if (bBounced = UpdateEmitter(&m_Emitters[i])) { if (!(m_Emitters[i].m_dwPhysicsFlags & MO_LIQUID) && (m_hDebris[i])) { /* char* pSound = GetDebrisBounceSound(DBT_STONE_BIG); // Play appropriate sound... g_pClientSoundMgr->PlaySoundFromPos(m_Emitters[i].m_Pos, pSound, 300.0f, SOUNDPRIORITY_MISC_LOW); */ } m_BounceCount[i]--; if (m_BounceCount[i] <= 0) { m_Emitters[i].m_dwPhysicsFlags |= MO_RESTING; } } if (m_Emitters[i].m_dwPhysicsFlags & MO_RESTING) { m_ActiveEmitters[i] = LTFALSE; if (m_hDebris[i]) { m_pClientDE->RemoveObject(m_hDebris[i]); m_hDebris[i] = LTNULL; } } else if (m_hDebris[i]) { g_pLTClient->SetObjectPos(m_hDebris[i], &(m_Emitters[i].m_vPos)); if (m_bRotateDebris) { if (bBounced) { // Adjust due to the bounce... m_fPitchVel = GetRandom(-MATH_CIRCLE, MATH_CIRCLE); m_fYawVel = GetRandom(-MATH_CIRCLE, MATH_CIRCLE); } if (m_fPitchVel != 0 || m_fYawVel != 0) { LTFLOAT fDeltaTime = g_pGameClientShell->GetFrameTime(); m_fPitch += m_fPitchVel * fDeltaTime; m_fYaw += m_fYawVel * fDeltaTime; LTRotation rRot; rRot.Rotate(rRot.Up(), m_fYaw); rRot.Rotate(rRot.Right(), m_fPitch); g_pLTClient->SetObjectRotation(m_hDebris[i], &rRot); } } } } } return LTTRUE; }