示例#1
0
LTBOOL ScaleSprite::Update()
{
	if (m_bStartOn)
	{
		g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, USRFLG_VISIBLE, USRFLG_VISIBLE);

		g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE);
	}

	SetNextUpdate(UPDATE_NEVER);
 
	// BUG - This isn't quite right.  Sometimes this works (flipping the sprite)
	// other times the sprite shouldn't be flipped...Not sure what the bug is.
	// For some reason the sprites are sometimes backwards...Get the rotation
	// so we can flip it...

    LTRotation rRot;
    LTVector vPos, vDir, vU, vR, vF;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);
	g_pLTServer->GetObjectRotation(m_hObject, &rRot);
	vU = rRot.Up();
	vR = rRot.Right();
	vF = rRot.Forward();

	if (m_bFlushWithWorld)
	{
		// Align the sprite to the surface directly behind the sprite
		// (i.e., opposite the forward vector)...

		VEC_NORM(vF);
		VEC_MULSCALAR(vDir, vF, -1.0f);


		// Determine where on the surface to place the sprite...

		IntersectInfo iInfo;
		IntersectQuery qInfo;

		VEC_COPY(qInfo.m_From, vPos);
		VEC_COPY(qInfo.m_Direction, vDir);
		qInfo.m_Flags	 = IGNORE_NONSOLID | INTERSECT_OBJECTS | INTERSECT_HPOLY;
        qInfo.m_FilterFn = LTNULL;

        if (g_pLTServer->CastRay(&qInfo, &iInfo))
		{
            LTVector vTemp;
			VEC_COPY(vPos, iInfo.m_Point);
			VEC_COPY(vDir, iInfo.m_Plane.m_Normal);

			// Place the sprite just above the surface...

			VEC_MULSCALAR(vTemp, vDir, 1.0f);
			VEC_ADD(vPos, vPos, vTemp);

			g_pLTServer->SetObjectPos(m_hObject, &vPos);
		}
	}

    return LTTRUE;
}
示例#2
0
bool CFallingStuffFX::Init(ILTClient *pClientDE, FX_BASEDATA *pBaseData, const CBaseFXProps *pProps)
{
    // Perform base class initialisation

    if (!CBaseFX::Init(pClientDE, pBaseData, pProps))
        return false;

    // Store the first position as the last position

    m_vLastPos = pBaseData->m_vPos;

    // If we have a parent object, get it and apply it's rotation
    // to the plane direction
    m_vPlaneDir = GetProps()->m_vPlaneDir;
    if (m_hParent)
    {
        LTRotation orient;
        m_pLTClient->GetObjectRotation(m_hParent, &orient);

        LTMatrix mRot;
        Mat_SetBasisVectors(&mRot, &orient.Right(), &orient.Up(), &orient.Forward());

        LTVector vTmp = m_vPlaneDir;

        MatVMul(&m_vPlaneDir, &mRot, &vTmp);
    }

    LTVector vUp;
    vUp.x = 0.0f;
    vUp.y = 1.0f;
    vUp.z = 0.0f;

    LTVector vTest = m_vPlaneDir;
    vTest.x = (float)fabs(vTest.x);
    vTest.y = (float)fabs(vTest.y);
    vTest.z = (float)fabs(vTest.z);

    if (vTest == vUp)
    {
        // Gotsta use another axis

        vUp.x = -1.0f;
        vUp.y = 0.0f;
        vUp.z = 0.0f;
    }

    m_vRight = m_vPlaneDir.Cross(vUp);
    m_vUp = m_vPlaneDir.Cross(m_vRight);


    // Create the base object

    CreateDummyObject();

    // Success !!

    return true;
}
示例#3
0
LTBOOL CLaserTriggerFX::CalcBeamCoords()
{
    if (!m_hServerObject) return LTFALSE;

	// The beam is relative to the server object's dims...

    LTVector vPos;
	g_pLTClient->GetObjectPos(m_hServerObject, &vPos);

    LTRotation rRot;
	g_pLTClient->GetObjectRotation(m_hServerObject, &rRot);

    LTVector vU, vR, vF;
	vU = rRot.Up();
	vR = rRot.Right();
	vF = rRot.Forward();


	// Okay, the beam is always along the object's longest dim...

    LTVector vDir = vF;
    LTFLOAT fLongestDim = m_cs.vDims.z; // Assume forward first...

	m_pls.fMaxWidth = (m_cs.vDims.x + m_cs.vDims.y); // Assume x/y are same...

	if (m_cs.vDims.y > fLongestDim)
	{
		vDir = vU;
		fLongestDim =  m_cs.vDims.y;
		m_pls.fMaxWidth = (m_cs.vDims.x + m_cs.vDims.z);
	}
	if (m_cs.vDims.x > fLongestDim)
	{
		vDir = vR;
		fLongestDim =  m_cs.vDims.x;
		m_pls.fMaxWidth = (m_cs.vDims.y + m_cs.vDims.z);
	}

	m_pls.vStartPos = vPos + (vDir * fLongestDim);
	m_pls.vEndPos	= vPos - (vDir * fLongestDim);

    return LTTRUE;
}
示例#4
0
bool ConstraintWheel::SetupBodySpaceData(const LTRigidTransform& tInvBody1, const LTRigidTransform& tInvBody2)
{
	//get the position of our object which will serve as the constraint point
	LTVector vConstraintPos;
	if(g_pLTServer->GetObjectPos(m_hObject, &vConstraintPos) != LT_OK)
		return false;

	LTRotation rConstraintOr;
	if(g_pLTServer->GetObjectRotation(m_hObject, &rConstraintOr) != LT_OK)
		return false;

	m_vPivotPt1 = tInvBody1 * vConstraintPos;
	m_vPivotPt2 = tInvBody2 * vConstraintPos;

	m_vRotation1 = tInvBody1.m_rRot.RotateVector(rConstraintOr.Forward());
	m_vRotation2 = tInvBody2.m_rRot.RotateVector(rConstraintOr.Forward());

	m_vSuspension2 = tInvBody2.m_rRot.RotateVector(rConstraintOr.Up());

	return true;
}
示例#5
0
void CFlashLight3rdPerson::GetLightPositions(LTVector& vStartPos, LTVector& vEndPos, LTVector& vUOffset, LTVector& vROffset)
{
	if ( !m_hObj ) return;

	HMODELSOCKET hSocket;
	if ( LT_OK == g_pModelLT->GetSocket(m_hObj, "LeftHand", hSocket) )
	{
		LTransform tf;

		if ( LT_OK == g_pModelLT->GetSocketTransform(m_hObj, hSocket, tf, LTTRUE) )
		{
			LTVector vPos = tf.m_Pos;
			LTRotation rRot = tf.m_Rot;

			LTVector vRight, vUp, vForward;
			vRight = rRot.Right();
			vUp = rRot.Up();
			vForward = rRot.Forward();

			//vStartPos = vPos - vUp*4.0f + vForward*8.0f;
			//vEndPos = vPos + vForward*200.0f;
			//vUOffset = vUp;
			//vROffset = vRight;

			vStartPos = vPos;
			vEndPos = vPos + (vForward * g_cvarFLLightOffsetForward.GetFloat());

  			vROffset = (vRight * g_cvarFLLightOffsetRight.GetFloat());
  			vUOffset = (vUp * g_cvarFLLightOffsetUp.GetFloat());

			// Update the Start/End position to addjust for any offset...

			vEndPos += vROffset;
			vEndPos += vUOffset;

			vStartPos += vROffset;
			vStartPos += vUOffset;
		}
	}
}
示例#6
0
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;
}
示例#7
0
void CFlashLightPlayer::GetLightPositions(LTVector& vStartPos, LTVector& vEndPos, LTVector& vUOffset, LTVector& vROffset)
{
	vStartPos.Init();
	vEndPos.Init();
	vUOffset.Init();
	vROffset.Init();

	CMoveMgr* pMoveMgr = g_pPlayerMgr->GetMoveMgr();
	if (!pMoveMgr) return;

	LTRotation rRot;

	if (pMoveMgr->GetVehicleMgr()->IsVehiclePhysics())
	{
		if (g_pPlayerMgr->IsFirstPerson())
		{
			pMoveMgr->GetVehicleMgr()->GetVehicleLightPosRot(vStartPos, rRot);
		}
		else // 3rd person vehicle
		{
			// Get light pos on 3rd-person vehicle...

			HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject();
			if (hPlayerObj)
			{
				g_pLTClient->GetObjectRotation(hPlayerObj, &rRot);
				g_pLTClient->GetObjectPos(hPlayerObj, &vStartPos);
			}
		}
	}
	else if (g_pPlayerMgr->IsFirstPerson())
	{
		HOBJECT hCamera = g_pPlayerMgr->GetCamera();
		if (!hCamera) return;

		g_pLTClient->GetObjectRotation(hCamera, &rRot);
		g_pLTClient->GetObjectPos(hCamera, &vStartPos);
	}
	else // 3rd person
	{
		// Get light pos from 3rd-person model...

		HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject();
		if (hPlayerObj)
		{
			// g_pLTClient->GetObjectRotation(hPlayerObj, &rRot);
			// g_pLTClient->GetObjectPos(hPlayerObj, &vStartPos);

			HMODELSOCKET hSocket;
			if ( LT_OK == g_pModelLT->GetSocket(hPlayerObj, "LeftHand", hSocket) )
			{
				LTransform tf;

				if ( LT_OK == g_pModelLT->GetSocketTransform(hPlayerObj, hSocket, tf, LTTRUE) )
				{
					vStartPos = tf.m_Pos;
					rRot = tf.m_Rot;
				}
			}
		}
	}

	vEndPos = vStartPos + (rRot.Forward() * g_cvarFLLightOffsetForward.GetFloat());

  	if (g_pPlayerMgr->IsFirstPerson())
  	{
  		vROffset = (rRot.Right() * g_cvarFLLightOffsetRight.GetFloat());
  		vUOffset = (rRot.Up() * g_cvarFLLightOffsetUp.GetFloat());

		// Update the Start/End position to addjust for any offset...

		vEndPos += vROffset;
		vEndPos += vUOffset;

		vStartPos += vROffset;
		vStartPos += vUOffset;
  	}
}
示例#8
0
void DebugLineSystem::AddOrientation( const LTVector& vCenter, const LTRotation& rRot, float fLength, uint8 nAlpha)
{
	AddArrow(vCenter, vCenter + rRot.Right() * fLength, Color::Red, nAlpha);
	AddArrow(vCenter, vCenter + rRot.Up() * fLength, Color::Green, nAlpha);
	AddArrow(vCenter, vCenter + rRot.Forward() * fLength, Color::Blue, nAlpha);
}
示例#9
0
//function that handles the custom rendering
void CParticleSystemGroup::RenderParticleSystem(ILTCustomRenderCallback* pInterface, const LTRigidTransform& tCamera)
{
	//track our performance
	CTimedSystemBlock TimingBlock(g_tsClientFXParticles);

	//setup our vertex declaration
	if(pInterface->SetVertexDeclaration(g_ClientFXVertexDecl.GetTexTangentSpaceDecl()) != LT_OK)
		return;

	//bind a quad index stream
	if(pInterface->BindQuadIndexStream() != LT_OK)
		return;

	//set the fact that we were visible
	*m_pVisibleFlag = true;

	//now determine the largest number of particles that we can render at any time
	uint32 nMaxParticlesPerBatch = QUAD_RENDER_INDEX_STREAM_SIZE / 6;
	nMaxParticlesPerBatch = LTMIN(nMaxParticlesPerBatch, DYNAMIC_RENDER_VERTEX_STREAM_SIZE / (sizeof(STexTangentSpaceVert) * 4));

	//determine the screen orientation
	LTRotation rCamera = tCamera.m_rRot;

	if (m_pProps->m_bObjectSpace)
	{
		LTRotation rObjectRotation;
		g_pLTClient->GetObjectRotation(m_hCustomRender, &rObjectRotation);
		rCamera = rObjectRotation.Conjugate() * rCamera;
	}

	LTVector vUp = rCamera.Up();
	LTVector vRight = rCamera.Right();

	//create some vectors to offset to each corner (avoids adding for displacement in the inner loop)
	//Each one can just be scaled by the size of the particle to get the final offset
	static const float kfHalfRoot2 = 0.5f * MATH_SQRT2;

	//premultiplied versions of up and right scaled by half the square root of two
	LTVector vUpHalfRoot2 = vUp * kfHalfRoot2;
	LTVector vRightHalfRoot2 = vRight * kfHalfRoot2;

	//precalculate the diagonals for non-rotating particles since these are constant
	LTVector vDiagonals[4];
	vDiagonals[0] =  vUpHalfRoot2 - vRightHalfRoot2; 
	vDiagonals[1] =  vUpHalfRoot2 + vRightHalfRoot2; 
	vDiagonals[2] = -vUpHalfRoot2 + vRightHalfRoot2; 
	vDiagonals[3] = -vUpHalfRoot2 - vRightHalfRoot2; 

	uint32 nNumParticlesLeft = m_Particles.GetNumParticles();

	//precalculate some data for the basis space of the particles
	LTVector	vNormal		= -rCamera.Forward();
	LTVector	vTangent	= vRight;
	LTVector	vBinormal	= -vUp;

	//the U scale for particle images
	float		fUImageWidth = 1.0f / (float)m_pProps->m_nNumImages;

	//variables used within the inner loop
	float		fSize;
	uint32		nColor;

	//now run through all the particles and render
	CParticleIterator itParticles = m_Particles.GetIterator();
	while(nNumParticlesLeft > 0)
	{
		//determine our batch size
		uint32 nBatchSize = LTMIN(nNumParticlesLeft, nMaxParticlesPerBatch);

		//lock down our buffer for rendering
		SDynamicVertexBufferLockRequest LockRequest;
		if(pInterface->LockDynamicVertexBuffer(nBatchSize * 4, LockRequest) != LT_OK)
			return;

		//fill in a batch of particles
		STexTangentSpaceVert* pCurrOut = (STexTangentSpaceVert*)LockRequest.m_pData;

		if(m_pProps->m_bRotate)
		{
			//we need to render the particles rotated
			for(uint32 nBatchParticle = 0; nBatchParticle < nBatchSize; nBatchParticle++)
			{
				//sanity check
				LTASSERT(!itParticles.IsDone(), "Error: Particle count and iterator mismatch");

				//get the particle from the iterator
				SParticle* pParticle = (SParticle*)itParticles.GetParticle();

				GetParticleSizeAndColor(pParticle, nColor, fSize);

				//determine the sin and cosine of this particle angle
				float fAngle = pParticle->m_fAngle;
				float fSinAngle = LTSin(fAngle);
				float fCosAngle = LTCos(fAngle);

				LTVector vRotRight = (vRightHalfRoot2 * fCosAngle + vUpHalfRoot2 * fSinAngle) * fSize;
				LTVector vRotUp    = vNormal.Cross(vRotRight);

				LTVector vRotTangent  = vTangent * fCosAngle + vBinormal * fSinAngle;
				LTVector vRotBinormal = vTangent * fSinAngle + vBinormal * fCosAngle;

				SetupParticle(	pCurrOut, 
					pParticle->m_Pos + vRotUp - vRotRight,
					pParticle->m_Pos + vRotUp + vRotRight,
					pParticle->m_Pos - vRotUp + vRotRight,
					pParticle->m_Pos - vRotUp - vRotRight,
					nColor, vNormal, vRotTangent, vRotBinormal, 
					pParticle->m_nUserData & PARTICLE_IMAGE_MASK, fUImageWidth);

				//move onto the next set of particles
				pCurrOut += 4;

				//move onto the next particle for processing
				itParticles.Next();
			}
		}
		else if (m_pProps->m_bStreak)
		{
			//the particles are non-rotated but streaked along their velocity
			for(uint32 nBatchParticle = 0; nBatchParticle < nBatchSize; nBatchParticle++)
			{
				//sanity check
				LTASSERT(!itParticles.IsDone(), "Error: Particle count and iterator mismatch");

				//get the particle from the iterator
				SParticle* pParticle = (SParticle*)itParticles.GetParticle();

				GetParticleSizeAndColor(pParticle, nColor, fSize);

				//in order to render the streak, we determine a line that passes through
				//the particle and runs in the direction of the velocity of the particle

				//we need to project the velocity onto the screen
				LTVector2 vScreen;
				vScreen.x = -(pParticle->m_Velocity.Dot(vRight));
				vScreen.y = -(pParticle->m_Velocity.Dot(vUp));

				//we know that the up and right vectors are normalized, so we can save some work by
				//just doing a 2d normalization
				float fMag = vScreen.Mag();
				if(fMag == 0.0f)
					vScreen.Init(fSize, 0.0f);
				else
					vScreen *= fSize / fMag;

				//determine our actual screen space velocity
				LTVector vScreenRight = vUp * vScreen.y + vRight * vScreen.x;
				LTVector vScreenUp = vUp * -vScreen.x + vRight * vScreen.y;

				//and now compute the endpoint of the streak
				LTVector vEndPos = pParticle->m_Pos - pParticle->m_Velocity * m_pProps->m_fStreakScale;

				SetupParticle(	pCurrOut, 
					pParticle->m_Pos	- vScreenRight - vScreenUp,
					vEndPos				+ vScreenRight - vScreenUp,
					vEndPos				+ vScreenRight + vScreenUp,
					pParticle->m_Pos	- vScreenRight + vScreenUp,
					nColor, vNormal, vScreenRight, vScreenUp, 
					pParticle->m_nUserData & PARTICLE_IMAGE_MASK, fUImageWidth);

				//move onto the next set of particles
				pCurrOut += 4;

				//move onto the next particle for processing
				itParticles.Next();
			}
		}
		else
		{
			//the particles are non-rotated
			for(uint32 nBatchParticle = 0; nBatchParticle < nBatchSize; nBatchParticle++)
			{
				//sanity check
				LTASSERT(!itParticles.IsDone(), "Error: Particle count and iterator mismatch");

				//get the particle from the iterator
				SParticle* pParticle = (SParticle*)itParticles.GetParticle();

				GetParticleSizeAndColor(pParticle, nColor, fSize);

				SetupParticle(	pCurrOut, 
					pParticle->m_Pos + vDiagonals[0] * fSize,
					pParticle->m_Pos + vDiagonals[1] * fSize,
					pParticle->m_Pos + vDiagonals[2] * fSize,
					pParticle->m_Pos + vDiagonals[3] * fSize,
					nColor, vNormal, vTangent, vBinormal, 
					pParticle->m_nUserData & PARTICLE_IMAGE_MASK, fUImageWidth);

				//move onto the next set of particles
				pCurrOut += 4;

				//move onto the next particle for processing
				itParticles.Next();
			}
		}

		//unlock and render the batch
		pInterface->UnlockAndBindDynamicVertexBuffer(LockRequest);
		pInterface->RenderIndexed(	eCustomRenderPrimType_TriangleList, 
			0, nBatchSize * 6, LockRequest.m_nStartIndex, 
			0, nBatchSize * 4);

		nNumParticlesLeft -= nBatchSize;
	}
}
示例#10
0
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;
}
示例#11
0
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);
		}
	}
}
示例#12
0
bool CPolyTubeFX::Update(float tmFrameTime)
{
	// Base class update first
	if (!CBaseFX::Update(tmFrameTime)) 
		return false;

	if ((!m_hTexture) && (!m_bLoadFailed))
	{
		m_pLTClient->GetTexInterface()->CreateTextureFromName(m_hTexture, GetProps()->m_sPath);

		if (m_hTexture)
		{
			// Retrieve texture dims
			uint32 nHeight;
			m_pLTClient->GetTexInterface()->GetTextureDims(m_hTexture, m_dwWidth, nHeight);
		}
		else
		{
			m_bLoadFailed = true;
		}
	}

	if ((m_collPathPts.GetSize() < 2) && IsShuttingDown())
	{
		m_collPathPts.RemoveAll();
		return true;
	}
	
	float tmAddPtInterval = GetProps()->m_tmAddPtInterval * 2.0f;

	LTRotation rRot;
	m_pLTClient->GetObjectRotation( m_hObject, &rRot );

	//increase the emission time elapse
	m_tmElapsedEmission += tmFrameTime;

	if (!IsShuttingDown() && 
	    (m_collPathPts.GetSize() < GetProps()->m_nMaxTrailLength) && 
		((m_tmElapsedEmission > GetProps()->m_tmAddPtInterval) || (m_collPathPts.GetSize() == 1)))
	{
		LTVector vNew = m_vPos;
		
		// Only add the new point if it's not the same as the last one....

		// Add a new trail section

		PT_TRAIL_SECTION ts;
		ts.m_vPos		= vNew;
		ts.m_tmElapsed	= 0.0f;

		switch( GetProps()->m_eAllignment )
		{
			case ePTA_Up:
				ts.m_vBisector = rRot.Up();
			break;

			case ePTA_Right:
				ts.m_vBisector = rRot.Right();
			break;

			case ePTA_Forward:
				ts.m_vBisector = rRot.Forward();
			break;

			case ePTA_Camera:
			default:
				ts.m_vBisector.Init();
			break;
		}
		
		
		// Compute u coordinate

		if (m_collPathPts.GetSize())
		{
			LTVector vPrev = m_collPathPts.GetTail()->m_Data.m_vPos;
			float fUPrev = m_collPathPts.GetTail()->m_Data.m_uVal;
			
			float fWidth = (float)m_dwWidth;
			float fScalar = fWidth / GetProps()->m_fTrailWidth;

			ts.m_uVal = fUPrev + ((((vNew - vPrev).Mag()) / fWidth) * fScalar);

		}
		else
		{
			ts.m_uVal = 0.0f;
		}

		m_collPathPts.AddTail(ts);
		
		m_tmElapsedEmission = 0.0f;
	}

	// Render the tube....

	if (m_collPathPts.GetSize() < 2) return true;

	CLinkListNode<PT_TRAIL_SECTION> *pNode = m_collPathPts.GetHead();

	// Fudge the last point to be the current one...

	if( !IsShuttingDown() )
		m_collPathPts.GetTail()->m_Data.m_vPos = m_vPos;

	// Transform the path

	LTMatrix mCam;
	if( m_bReallyClose || (GetProps()->m_eAllignment != ePTA_Camera))
	{
		mCam.Identity();
	}
	else
	{
		mCam = GetCamTransform(m_pLTClient, m_hCamera);
	}
	 
	while (pNode)
	{
		MatVMul(&pNode->m_Data.m_vTran, &mCam, &pNode->m_Data.m_vPos);
		pNode = pNode->m_pNext;
	}

	// Do some precalculations

	pNode = m_collPathPts.GetHead();

	float fCurU = 0.0f;

	while (pNode)
	{
		pNode->m_Data.m_tmElapsed += tmFrameTime;

		if( GetProps()->m_eAllignment == ePTA_Camera )
		{
			LTVector vBisector;
			vBisector.z = 0.0f;

			// Compute the midpoint vectors

			if (pNode == m_collPathPts.GetHead())
			{
				LTVector vStart = pNode->m_Data.m_vTran;
				LTVector vEnd   = pNode->m_pNext->m_Data.m_vTran;
				
				vBisector.x = vEnd.y - vStart.y;
				vBisector.y = -(vEnd.x - vStart.x);
			}
			else if (pNode == m_collPathPts.GetTail())
			{
				LTVector vEnd   = pNode->m_Data.m_vTran;
				LTVector vStart = pNode->m_pPrev->m_Data.m_vTran;
				
				vBisector.x = vEnd.y - vStart.y;
				vBisector.y = -(vEnd.x - vStart.x);
			}
			else
			{
				LTVector vPrev  = pNode->m_pPrev->m_Data.m_vTran;
				LTVector vStart = pNode->m_Data.m_vTran;
				LTVector vEnd   = pNode->m_pNext->m_Data.m_vTran;

				float x1 = vEnd.y - vStart.y;
				float y1 = -(vEnd.x - vStart.x);
				float z1 = vStart.z - vEnd.z;

				float x2 = vStart.y - vPrev.y;
				float y2 = -(vStart.x - vPrev.x);
				float z2 = vPrev.z - vEnd.z;
				
				vBisector.x = (x1 + x2) / 2.0f;
				vBisector.y = (y1 + y2) / 2.0f;
			}

			pNode->m_Data.m_vBisector = vBisector;
		}
		
		LTFLOAT fWidth = CalcCurWidth();
		pNode->m_Data.m_vBisector.Norm( fWidth );

		// Setup the colour
		
		float r, g, b, a;			
		CalcColour(pNode->m_Data.m_tmElapsed, GetProps()->m_tmSectionLifespan, &r, &g, &b, &a);			

		int ir = (int)(r * 255.0f);
		int ig = (int)(g * 255.0f);
		int ib = (int)(b * 255.0f);
		int ia = (int)(a * 255.0f);

		pNode->m_Data.m_red = Clamp( ir, 0, 255 );
		pNode->m_Data.m_green = Clamp( ig, 0, 255 );
		pNode->m_Data.m_blue = Clamp( ib, 0, 255 );
		pNode->m_Data.m_alpha = Clamp( ia, 0, 255 );
	
		pNode = pNode->m_pNext;
	}

	pNode = m_collPathPts.GetHead();

	pNode = m_collPathPts.GetHead();

	// Delete any dead nodes

	while (pNode->m_pNext)
	{
		CLinkListNode<PT_TRAIL_SECTION> *pDelNode= NULL;

		if (pNode->m_Data.m_tmElapsed >= GetProps()->m_tmSectionLifespan)
		{
			pDelNode = pNode;
		}
		
		pNode = pNode->m_pNext;

		if (pDelNode) m_collPathPts.Remove(pDelNode);
	}

	// Increment the offset
	m_uOffset += tmFrameTime * GetProps()->m_uAdd;

	// Success !!

	return true;
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
void CLightningFX::EmitBolts( float tmFrameTime )
{
	// Make sure enough time between emissions has passed...
	m_tmElapsedEmission += tmFrameTime;

	if( m_fDelay < m_tmElapsedEmission )
	{
		LTransform		lTrans;
		LTVector		vAttractorPos;
		ILTModel		*pModelLT = m_pLTClient->GetModelLT();

		uint32	nActiveBolts = GetRandom( (int)GetProps()->m_nMinNumBolts, (int)GetProps()->m_nMaxNumBolts );
		uint32	nBolt;

		bool	bCanUseAttractors = (m_lstAttractors.size() > 0);
		bool	bCanUseRadius = (GetProps()->m_fOmniDirectionalRadius >= 1.0f);

		CLightningBolt *pBolt = LTNULL;
		LightningBolts::iterator iter;

		for( nBolt = 0, iter = m_lstBolts.begin(); iter != m_lstBolts.end(), nBolt < nActiveBolts; ++iter, ++nBolt )
		{
			pBolt = *iter;
			
			pBolt->m_fWidth = GetRandom( GetProps()->m_fMinBoltWidth, GetProps()->m_fMaxBoltWidth );
			pBolt->m_fLifetime = GetRandom( GetProps()->m_fMinLifetime, GetProps()->m_fMaxLifetime );
			pBolt->m_tmElapsed = 0.0f;
			pBolt->m_bActive = true;
			
			// Grab the position of the object to compensate for offset
		
			if( m_hTarget )
			{
				m_pLTClient->GetObjectPos( m_hTarget, &vAttractorPos );
			}
			else
			{
				vAttractorPos = m_vTargetPos;
			}

			// Decide if we should use an attractor or radius for the end pos...
			
			if( bCanUseAttractors && (!bCanUseRadius || GetRandom(0,1)) )
			{
				uint8	nIndex = GetRandom( 0, (int)(m_lstAttractors.size()) - 1 );
				CAttractor cAttractor = m_lstAttractors[nIndex];

				if( cAttractor.GetTransform( lTrans, true ) == LT_OK )
				{
					vAttractorPos = lTrans.m_Pos;
				}
			}	
			else if( bCanUseRadius )
			{
				LTVector vRandomPos;
				vRandomPos.x = GetRandom( -1.0f, 1.0f );
				vRandomPos.y = GetRandom( -1.0f, 1.0f );
				vRandomPos.z = GetRandom( -1.0f, 1.0f );
				
				vRandomPos.Normalize();
				vRandomPos *= GetRandom( -GetProps()->m_fOmniDirectionalRadius, GetProps()->m_fOmniDirectionalRadius );

				vAttractorPos = m_vPos + vRandomPos;

				IntersectQuery	iQuery;
				IntersectInfo	iInfo;

				iQuery.m_From	= m_vPos;
				iQuery.m_To		= vAttractorPos;

				if( m_pLTClient->IntersectSegment( &iQuery, &iInfo ))
				{
					vAttractorPos = iInfo.m_Point;
				}
			}

			
			LTVector vNew = m_vPos;
			LTVector vDir = vAttractorPos - vNew;
						
			float fStep = vDir.Length() / (float)pBolt->m_nNumSegments;
			float fPerturb = GetRandom( GetProps()->m_fMinPerturb, GetProps()->m_fMaxPerturb );
			
			vDir.Normalize();
			LTRotation rRot = LTRotation( vDir, LTVector( 0.0f, 1.0f, 0.0f ));
				
			CLinkListNode<PT_TRAIL_SECTION> *pNode = pBolt->m_collPathPts.GetHead();
			while( pNode )
			{
				pNode->m_Data.m_vPos = vNew;
				pNode->m_Data.m_tmElapsed = 0.0f;
				pNode->m_Data.m_vBisector.Init();
												
				// Add in some perturb going in the direction of the attractor pos for the next section...
				
				vNew +=	(rRot.Forward() * fStep );
				vNew += (rRot.Up() * GetRandom( -fPerturb, fPerturb ));
				vNew += (rRot.Right() * GetRandom( -fPerturb, fPerturb ));

				// Make sure the last section goes to the end pos...

				if( !pNode->m_pNext )
					pNode->m_Data.m_vPos = vAttractorPos;

				pNode = pNode->m_pNext;
			}
		}

		// Decide when the next emission will be...

		m_tmElapsedEmission = 0.0f;
		m_fDelay = GetRandom( GetProps()->m_fMinDelay, GetProps()->m_fMaxDelay );
	}
}
示例#16
0
void CLaserBeam::Update(LTVector &vBeamStartPos, const LTRotation* pRDirRot,
                        LTBOOL b3rdPerson, LTBOOL bDetect)
{
	if (!m_bOn) return;

	// Calculate beam position...

	HOBJECT hCamera = g_pPlayerMgr->GetCamera();
	if (!hCamera) return;

    HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject();
	if (!hPlayerObj) return;

    HOBJECT hFilterList[] = {hPlayerObj, g_pPlayerMgr->GetMoveMgr()->GetObject(), LTNULL};

	IntersectQuery qInfo;
	IntersectInfo iInfo;

    LTVector vPos(0, 0, 0);
    LTRotation rRot;

    LTVector vU, vR, vF;

	if (pRDirRot && b3rdPerson)
	{
		vPos = vBeamStartPos;

		vU = pRDirRot->Up();
		vR = pRDirRot->Right();
		vF = pRDirRot->Forward();
	}
	else
	{
		g_pLTClient->GetObjectRotation(hCamera, &rRot);
		g_pLTClient->GetObjectPos(hCamera, &vPos);

		vU = rRot.Up();
		vR = rRot.Right();
		vF = rRot.Forward();

		if (g_cvarLaserBeamDebug.GetFloat() == 0.0f)
		{
			vBeamStartPos += vPos;
		}
		else if (g_cvarLaserBeamDebug.GetFloat() == 1.0f)
		{
			vBeamStartPos = vPos;
		}
		else if (pRDirRot)
		{
			vU = pRDirRot->Up();
			vR = pRDirRot->Right();
			vF = pRDirRot->Forward();
			vBeamStartPos = vBeamStartPos;
		}

	}


    LTVector vEndPos = vPos + (vF * 10000.0f);

	qInfo.m_From = vPos;
	qInfo.m_To   = vEndPos;

	qInfo.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	qInfo.m_FilterFn = ObjListFilterFn;
	qInfo.m_pUserData = hFilterList;

    if (g_pLTClient->IntersectSegment(&qInfo, &iInfo))
	{
		vEndPos = iInfo.m_Point;
	}


	// Show the light beam...

    LTVector vColor = LTVector(GetRandom(235.0f, 255.0f), GetRandom(35.0f, 55.0f), GetRandom(35.0f, 55.0f));;

    LTFLOAT fAlpha = g_cvarLaserBeamAlpha.GetFloat();

	if (iInfo.m_hObject && bDetect)
	{
        uint32 dwUsrFlgs = 0;
        g_pCommonLT->GetObjectFlags(iInfo.m_hObject, OFT_User, dwUsrFlgs);

		if (dwUsrFlgs & USRFLG_CHARACTER)
		{
			fAlpha	= 0.95f;
			vColor.Init(GetRandom(35.0f, 55.0f), GetRandom(235.0f, 255.0f), GetRandom(35.0f, 55.0f));;
		}
	}

    LTFLOAT fWidth = g_cvarLaserBeamThickness.GetFloat();
	fWidth = b3rdPerson ? fWidth*2.0f : fWidth;

	vBeamStartPos += (vF * g_cvarLaserBeamFOffset.GetFloat());
	vBeamStartPos += (vR * g_cvarLaserBeamROffset.GetFloat());
	vBeamStartPos += (vU * g_cvarLaserBeamUOffset.GetFloat());

	PLFXCREATESTRUCT pls;

	if (g_cvarLaserBeamDebug.GetFloat() >= 0.0f)
	{
        // g_pLTClient->CPrint("StartPos = %.2f, %.2f, %.2f", VEC_EXPAND(vBeamStartPos));
        // g_pLTClient->CPrint("EndPos = %.2f, %.2f, %.2f", VEC_EXPAND(vEndPos));
	}

	pls.vStartPos			= vBeamStartPos;
	pls.vEndPos				= vEndPos;
	pls.vInnerColorStart	= vColor;
	pls.vInnerColorEnd		= pls.vInnerColorStart;
    pls.vOuterColorStart    = LTVector(0, 0, 0);
    pls.vOuterColorEnd      = LTVector(0, 0, 0);
	pls.fAlphaStart			= fAlpha;
	pls.fAlphaEnd			= fAlpha;
	pls.fMinWidth			= 0;
	pls.fMaxWidth			= fWidth;
	pls.fMinDistMult		= 1.0f;
	pls.fMaxDistMult		= 1.0f;
	pls.fLifeTime			= 1.0f;
	pls.fAlphaLifeTime		= 1.0f;
	pls.fPerturb			= 0.0f;
    pls.bAdditive           = LTTRUE;
    pls.bAlignFlat          = b3rdPerson ? LTFALSE : LTTRUE;
	pls.nWidthStyle			= PLWS_CONSTANT;
	pls.nNumSegments		= (int)g_cvarLaserBeamNumSegments.GetFloat();

	if (m_LightBeam.HasBeenDrawn())
	{
		// Keep the light beam in the vis list...

		m_LightBeam.SetPos(vBeamStartPos);

		// Hide the beam in portals if 1st person...Also set flag really
		// close to true...

        uint32 dwFlags2, dwFlags;

		dwFlags = m_LightBeam.GetFlags();
		dwFlags2 = m_LightBeam.GetFlags2();

		if (b3rdPerson)
		{
			dwFlags &= ~FLAG_REALLYCLOSE;
		}
		else
		{
			if (g_cvarLaserBeamDebug.GetFloat() > 1.0f)
			{
				dwFlags |= FLAG_REALLYCLOSE;
                pls.bUseObjectRotation = LTTRUE;
			}
		}

		m_LightBeam.SetFlags(dwFlags);
		m_LightBeam.SetFlags2(dwFlags2);

		m_LightBeam.ReInit(&pls);
	}
	else
	{
		m_LightBeam.Init(&pls);
        m_LightBeam.CreateObject(g_pLTClient);
	}


	m_LightBeam.Update();
}
示例#17
0
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;
}