예제 #1
0
파일: DeathFX.cpp 프로젝트: Arc0re/lithtech
void CDeathFX::CreateVehicleDeathFX()
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	GIBCREATESTRUCT gib;

    m_pClientDE->AlignRotation(&(gib.rRot), &m_vDir, LTNULL);

    LTFLOAT fDamage = VEC_MAG(m_vDir);

	VEC_COPY(gib.vPos, m_vPos);
	VEC_SET(gib.vMinVel, 50.0f, 100.0f, 50.0f);
	VEC_MULSCALAR(gib.vMinVel, gib.vMinVel, fDamage);
	VEC_SET(gib.vMaxVel, 100.0f, 200.0f, 100.0f);
	VEC_MULSCALAR(gib.vMaxVel, gib.vMaxVel, fDamage);
	gib.fLifeTime		= 20.0f;
	gib.fFadeTime		= 7.0f;
	gib.nGibFlags		= 0;
    gib.bRotate         = LTTRUE;
	gib.eModelId		= m_eModelId;
	gib.eModelStyle		= m_eModelStyle;
	gib.nCode			= m_eCode;
    gib.bSubGibs        = LTTRUE;

	SetupGibTypes(gib);

	psfxMgr->CreateSFX(SFX_GIB_ID, &gib);
}
예제 #2
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;
}
예제 #3
0
DBOOL CShellCasingFX::CreateObject(CClientDE *pClientDE)
{
	if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;

	char* pModelName = DNULL;
	char* pSkinName = DNULL;
	if (!GetFileNames(&pModelName, &pSkinName))
		return DFALSE;

	if (!pModelName || !pSkinName) return DFALSE;

	// Setup the shell...

	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_MODEL;
	createStruct.m_Flags = 0;
	_mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)pModelName);
	_mbscpy((unsigned char*)createStruct.m_SkinName, (const unsigned char*)pSkinName);
	VEC_COPY(createStruct.m_Pos, m_vStartPos);
	ROT_COPY(createStruct.m_Rotation, m_rRot);

	m_hObject = pClientDE->CreateObject(&createStruct);
	if (!m_hObject) return DFALSE;


	m_pClientDE->SetObjectScale(m_hObject, &m_vScale);

	DVector vU, vR, vF;
	pClientDE->GetRotationVectors(&m_rRot, &vU, &vR, &vF);

	DVector vVel;

	if(m_bLeftHanded)
		VEC_NEGATE(vR, vR);

	DFLOAT fUpVel = GetRandom(60.0f, 90.0f);
	VEC_MULSCALAR(vU, vU, fUpVel);
	DFLOAT fRightVel = GetRandom(50.0f, 70.0f);
	VEC_MULSCALAR(vR, vR, fRightVel);
	DFLOAT fForwardVel = GetRandom(10.0f, 25.0f);
	VEC_MULSCALAR(vF, vF, fForwardVel);

	VEC_ADD(vVel, vU, vR);
	VEC_ADD(vVel, vVel, vF);

	InitMovingObject(&m_movingObj, &m_vStartPos, &vVel);;
	m_movingObj.m_PhysicsFlags |= MO_HALFGRAVITY;

	m_fExpireTime = 20.0f + m_pClientDE->GetTime();

	// Set the pitch velocity
	m_fPitchVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2);
	m_fYawVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2);
	m_fPitch	= m_fYaw = 0.0f;

	return DTRUE;
}
예제 #4
0
void DeathShroud::MC_Dead()
{
	DVector vColor;
	DFLOAT fAlpha = 0.0f;

	m_pServerDE->GetObjectColor(m_hObject,&vColor.x, &vColor.y, &vColor.z, &fAlpha);

    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_DEAD)
    {	
		if(m_hLoopSound)
		{
			m_pServerDE->KillSound(m_hLoopSound);
			m_hLoopSound = DNULL;
		}

		m_pServerDE->SetObjectColor(m_hObject,vColor.x,vColor.y,vColor.z, 1.0f);
	
		int nSideHit = m_damage.GetSideHit();

		switch(m_damage.GetNodeHit())
		{
			case NODE_NECK:		m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[0 + nSideHit]; break;
			case NODE_TORSO:	m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[1 + nSideHit]; break;
			case NODE_RARM:		m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[2 + nSideHit]; break;
			case NODE_LARM:		m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[3 + nSideHit]; break;
			case NODE_LLEG:		m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[4 + nSideHit]; break;
			case NODE_RLEG:		m_nCorpseType = m_pAnim_Sound->m_nAnim_DEATH[5 + nSideHit]; break;
		}

		m_pServerDE->SetModelLooping(m_hObject, DFALSE);

		m_bAnimating = DTRUE;
		m_nCurMetacmd = MC_DEAD;
	}
	else
	{
		VEC_MULSCALAR(m_vScale, m_vScale, 0.9f);
		VEC_MULSCALAR(m_vDims, m_vDims, 0.9f);

		m_pServerDE->ScaleObject(m_hObject, &m_vScale);
		m_pServerDE->SetObjectDims2(m_hObject, &m_vDims);

		fAlpha -= 0.05f;
		if(fAlpha <= 0.0f)		fAlpha = 0.0f;

		m_pServerDE->SetObjectColor(m_hObject,vColor.x,vColor.y,vColor.z, fAlpha);

		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)		
		{
			m_bAnimating = DFALSE;
			Metacmd++;

			m_bRemoveMe = DTRUE;
		}
	}

	return;
}
예제 #5
0
DBOOL UpdateMovingObject(PhysicsState *pUserState, MovingObject *pObject, DVector *pNewPos)
{
	if (!pObject || !pNewPos) return DFALSE;

	PhysicsState* pState = pUserState ? pUserState : GetCurPhysicsState(pObject);
	if (!pState) return DFALSE;

	DVector vTemp, velocityDelta, posDelta;

	if(pObject->m_PhysicsFlags & MO_RESTING)
		return DFALSE;
	
	// Prevent tiny movements.
	if(VEC_MAGSQR(pObject->m_Acceleration) < 0.01f)
	{
		VEC_INIT(pObject->m_Acceleration);
	}

	if(VEC_MAGSQR(pObject->m_Velocity) < 0.01f)
	{
		VEC_INIT(pObject->m_Velocity);
	}

	// velocityDelta = ( acceleration + accelDelta * 0.5 ) * dt;
	VEC_INIT(vTemp);
	if (!(pObject->m_PhysicsFlags & MO_NOGRAVITY))
	{
		DFLOAT fScale = 0.5f;
		if (pObject->m_PhysicsFlags & MO_HALFGRAVITY)
		{
			fScale = 0.20f;
		}
		VEC_MULSCALAR(vTemp, pState->m_GravityAccel, fScale);
	}
	VEC_ADD(vTemp, vTemp, pObject->m_Acceleration);
	VEC_MULSCALAR(velocityDelta, vTemp, pState->m_TimeStep);

	// Apply the velocity to the position (p = p + vt + 0.5a(t^2)).
	VEC_MULSCALAR(posDelta, pObject->m_Acceleration, pState->m_TimeStepIntegral);
	VEC_ADDSCALED(posDelta, posDelta, pObject->m_Velocity, pState->m_TimeStep);

	// Add the final velocity to the new velocity.
	VEC_ADD(pObject->m_Velocity, pObject->m_Velocity, velocityDelta);

	if(!pNewPos)
		pNewPos = &pObject->m_Pos;

	VEC_ADD(*pNewPos, pObject->m_Pos, posDelta);
	
	// Zero out the acceleration.
	VEC_INIT(pObject->m_Acceleration);

	return DTRUE;
}
예제 #6
0
HLOCALOBJ CParticleExplosionFX::CreateDebris()
{
    LTVector vScale;
    VEC_SET(vScale, 1.0f, 1.0f, 1.0f);
    VEC_MULSCALAR(vScale, vScale, GetRandom(1.0f, 5.0f));

    char* pFilename = GetDebrisModel(DBT_STONE_BIG, vScale);
    char* pSkin     = GetDebrisSkin(DBT_STONE_BIG);

    if (!pFilename) return LTNULL;

    ObjectCreateStruct createStruct;
    INIT_OBJECTCREATESTRUCT(createStruct);

    createStruct.m_ObjectType = OT_MODEL;
    SAFE_STRCPY(createStruct.m_Filename, pFilename);
    SAFE_STRCPY(createStruct.m_SkinName, pSkin);
    createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT;
    VEC_COPY(createStruct.m_Pos, m_vPos);

    HLOCALOBJ hObj = m_pClientDE->CreateObject(&createStruct);

    m_pClientDE->SetObjectScale(hObj, &vScale);

    return hObj;
}
예제 #7
0
LTBOOL CFolderIntel::UpdateSelection()
{
	LTBOOL bChanged = CBaseSelectionFolder::UpdateSelection();
	if (bChanged)
	{
		CLTGUICtrl *pCtrl = GetControl(m_nLastListItem);
		if (!pCtrl) return LTFALSE;
		int nIndex = pCtrl->GetParam1();
		if (!nIndex) return LTFALSE;



		IntelItem *pItem = m_intelArray[nIndex-1];
		HSTRING hStr = g_pLTClient->FormatString(pItem->nID);
		m_pDescription->SetString(hStr);
        g_pLTClient->FreeString(hStr);

		CScaleFX* pScaleFX = g_pFXButeMgr->GetScaleFX(pItem->nType);
		SAFE_STRCPY(m_szModel, pScaleFX->szFile);
		SAFE_STRCPY(m_szSkin, pScaleFX->szSkin);
		m_vScale = pScaleFX->vInitialScale;
		m_bChromakey = pScaleFX->bChromakey;
		
		if (pScaleFX->fDirOffset > 0.0f)
		{
			LTFLOAT fScaleMult = (100.0f/pScaleFX->fDirOffset);
			VEC_MULSCALAR(m_vScale, m_vScale, fScaleMult);
		}
		CreateModelSFX();

	}
	return bChanged;	

}
예제 #8
0
DBOOL CBaseParticleSystemFX::Update()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;


	// See if we should rotate this bad-boy...

	if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f)
	{
		DFLOAT fDelta = m_pClientDE->GetFrameTime();

		DRotation rRot;
		m_pClientDE->GetObjectRotation(m_hObject, &rRot);

		DVector vTemp;
		VEC_MULSCALAR(vTemp, m_vRotVel, fDelta);
		VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp);

		if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x);
		if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y);
		if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z);

		m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	}


	return DTRUE;
}
예제 #9
0
void CProjectile::Setup(DVector *vDir, DBYTE nType, DFLOAT fDamage, DFLOAT fVelocity,
						int nRadius, HOBJECT hFiredFrom)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	VEC_COPY(m_vDir, *vDir);
	m_fDamage		= fDamage;
	m_fVelocity		= fVelocity;
	m_nRadius		= nRadius;

	m_hFiredFrom	= hFiredFrom;
	pServerDE->CreateInterObjectLink( m_hObject, m_hFiredFrom );

	m_nWeaponType	= nType;

	DVector vVel;
	VEC_MULSCALAR(vVel, m_vDir, m_fVelocity);

	// Set the rotation of the projectile...
	DRotation rRot;
	pServerDE->AlignRotation(&rRot, &m_vDir, DNULL);
	pServerDE->SetObjectRotation(m_hObject, &rRot);

	// And away we go...
	pServerDE->SetVelocity(m_hObject, &vVel);
	pServerDE->SetObjectFlags(m_hObject, m_dwFlags);


	// Add smoke trail
	if (m_bSmokeTrail) AddSmokeTrail(vVel);
}
void CBodyFX::CreateMarker(LTVector & vPos, LTBOOL bSame)
{
	if (!m_pClientDE || !g_pGameClientShell || !m_hServerObject) return;

	if (!bSame) return;


	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	CString str = g_pClientButeMgr->GetSpecialFXAttributeString("TeamSprite");
	LTFLOAT fScaleMult = g_pClientButeMgr->GetSpecialFXAttributeFloat("TeamScale");
	LTFLOAT fAlpha = g_pClientButeMgr->GetSpecialFXAttributeFloat("TeamAlpha");

	LTVector	vScale(1.0f,1.0f,1.0f);

	VEC_MULSCALAR(vScale, vScale, fScaleMult);

	SAFE_STRCPY(createStruct.m_Filename, (char *)(LPCSTR)str);
	createStruct.m_ObjectType	= OT_SPRITE;
	createStruct.m_Flags		= FLAG_VISIBLE | FLAG_FOGDISABLE | FLAG_NOLIGHT;
	createStruct.m_Pos			= vPos;

	m_hMarker = m_pClientDE->CreateObject(&createStruct);
	if (!m_hMarker) return;

	m_pClientDE->SetObjectScale(m_hMarker, &vScale);

    LTFLOAT r, g, b, a;
	m_pClientDE->GetObjectColor(m_hServerObject, &r, &g, &b, &a);

	m_pClientDE->SetObjectColor(m_hObject, r, g, b, (fAlpha * a));

}
예제 #11
0
DVector	CPlayerCamera::FindFirstPersonCameraPosition(DVector vPos, DVector vF)
{
	DVector vTemp;
	VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x);
	VEC_ADD(vPos, vPos, vTemp);
	vPos.y += m_TargetFirstPersonOffset.y;

	return vPos;
}
예제 #12
0
파일: bug.cpp 프로젝트: Arc0re/lithtech
void BugAI::MC_Run()
{
   if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_RUN)
    {
		DBOOL bRet = DFALSE;

    	m_fTimeStart = m_pServerDE->GetTime();

		Move(m_MoveObj.GetForwardVector(),m_fRunSpeed);
        
        m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_RUN;
    }
    else
    {   
		//Check for obstruction; otherwise continue on
		if(CheckObstructed(m_MoveObj.GetForwardVector(), m_fRunSpeed))
		{
			IntersectQuery IQuery;
			IntersectInfo ii;
	
			IQuery.m_Flags	  = INTERSECT_OBJECTS;
			IQuery.m_FilterFn = DNULL;

			DVector vTemp;
			VEC_MULSCALAR(vTemp,m_MoveObj.GetForwardVector(),m_fRunSpeed);
			VEC_COPY(IQuery.m_From,m_MoveObj.GetPos());
			VEC_ADD(IQuery.m_To,IQuery.m_From,vTemp);

			if(m_pServerDE->IntersectSegment(&IQuery, &ii))
			{
				//climb the object
				DRotation rRot;
				m_pServerDE->AlignRotation(&rRot,&m_MoveObj.GetUpVector(),&ii.m_Plane.m_Normal);

				m_pServerDE->SetObjectRotation(m_hObject,&rRot);

				m_bAnimating = DFALSE; 
				Metacmd++;

				return;
			}
		}

		Move(m_MoveObj.GetForwardVector(),m_fRunSpeed);
    
		//Are we done running?
		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)
        {
            m_bAnimating = DFALSE; 
            Metacmd++;
        }
    }
	
    return;
}
예제 #13
0
DBOOL BounceMovingObject(PhysicsState *pUserState, MovingObject *pObject, 
						 DVector *pNewPos, ClientIntersectInfo* pInfo, SurfaceType *eType)
{

	if (!pObject || !pNewPos || !pInfo) return DFALSE;

	PhysicsState* pState = pUserState ? pUserState : GetCurPhysicsState(pObject);
	if (!pState) return DFALSE;

	ClientIntersectQuery query;
	float dot;

	// Only do an intersection test if the line is long enough (sometimes the 
	// intersection test will fail on really short lines).
	memset(&query, 0, sizeof(query));
	VEC_COPY(query.m_From, pObject->m_Pos);
	VEC_COPY(query.m_To, *pNewPos);

	if (eType)
		query.m_Flags = INTERSECT_HPOLY;

	if (pState->m_pClientDE->IntersectSegment(&query, pInfo))
	{
		// get the surface type
		if (eType)
			*eType = GetSurfaceType(pInfo->m_hObject, pInfo->m_hPoly);

		// Reflect the velocity.
		dot = VEC_DOT(pObject->m_Velocity, pInfo->m_Plane.m_Normal);
		dot *= -2.0f;

		VEC_ADDSCALED(pObject->m_Velocity, pObject->m_Velocity, pInfo->m_Plane.m_Normal, dot);

		// If the plane hit is in the opposite direction of travel, then move back a little...
		if( dot > 0.0f )
		{
			// Move the dest point a little in front of the plane.
			VEC_ADDSCALED(*pNewPos, pInfo->m_Point, pInfo->m_Plane.m_Normal, 0.3f);
		}
	
		// Dampen it.
		VEC_MULSCALAR(pObject->m_Velocity, pObject->m_Velocity, pState->m_VelocityDampen);
		
		// (250 is the max squared magnitude).
		if(pInfo->m_Plane.m_Normal.y > 0.6f && (VEC_MAGSQR(pObject->m_Velocity) < (250.0f)))
		{
			pObject->m_PhysicsFlags |= MO_RESTING;
		}

		return DTRUE;
	}

	return DFALSE;
}
예제 #14
0
DVector CMovement::FindTurn(DVector vStart, DVector vTestDir, DVector vMoveDir, DFLOAT fMoveLen, 
							DFLOAT fTestLen)
{
	DVector vFinal,vCurPos;
	DBOOL	bStop = DTRUE;
	DFLOAT fMaxDist = 0.0f;

	VEC_INIT(vFinal);
	VEC_COPY(vCurPos, vStart);

	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return vFinal;

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = DNULL;

	VEC_COPY(IQuery.m_From,vStart);
	VEC_COPY(IQuery.m_Direction,vMoveDir);

	//find maximum searchable distance in vMoveDir
	if(pServerDE->CastRay(&IQuery,&IInfo))
	{
		fMaxDist = VEC_DIST(vStart,IInfo.m_Point);
	}

	//loop til we find a spot to turn
	for(float fDist = 0.0f; !((fDist + fMoveLen) >= fMaxDist); fDist += fMoveLen)
	{
		VEC_ADDSCALED(vCurPos, vCurPos, vMoveDir, fMoveLen);

		VEC_COPY(IQuery.m_From,vCurPos);
		VEC_ADDSCALED(IQuery.m_To,vCurPos, vTestDir, fTestLen);

		if(!pServerDE->IntersectSegment(&IQuery, &IInfo))
		{
			VEC_ADDSCALED(vFinal, vCurPos, vMoveDir, fMoveLen);
			return vFinal;
		}
	}

	if(m_nNumPoints >= 10 || (VEC_DIST(vCurPos,vStart) <= 0.0))
		return vCurPos;

	//we can't turn here so we add to list and keep searching in new direction
	AddPosToPathList(vCurPos);

	DVector vNewMoveDir;
	VEC_MULSCALAR(vNewMoveDir, vTestDir, -1.0f);

	return FindTurn(vCurPos, vMoveDir, vNewMoveDir, fMoveLen, (fMaxDist - fDist) + 1.0f);
}
예제 #15
0
void CHandWeaponModel::Drop()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	m_bDropped = DTRUE;

	DVector vF, vR, vU;
	DRotation rRot;

	// Set some minimum dims, and make sure x and z are the same.
	DVector vDims;
	pServerDE->GetModelAnimUserDims(m_hObject, &vDims, pServerDE->GetModelAnimation(m_hObject));
	if (vDims.x < 10.0f)
		vDims.x = 10.0f;
	if (vDims.x > vDims.z)
		vDims.z = vDims.x;
	else 
		vDims.x = vDims.z;

//	g_pServerDE->BPrint("Setting PU dims %f,%f,%f", VEC_EXPAND(vDims));
	if (pServerDE->SetObjectDims2(m_hObject, &vDims) == DE_ERROR)

	// Get vectors to set a velocity	
	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	// Set some forward and upward velocity
	VEC_ADD(vF, vF, vU);
	VEC_MULSCALAR(vF, vF, 150.0f);

	pServerDE->SetVelocity(m_hObject, &vF);

	// Make it visible
	DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject);
	pServerDE->SetObjectFlags(m_hObject, dwFlags | FLAG_NOSLIDING | FLAG_VISIBLE | FLAG_GRAVITY | FLAG_REMOVEIFOUTSIDE);

	// Show the model on the client now
/*	if(m_dwClientID)
	{
		HMESSAGEWRITE hMsg = pServerDE->StartSpecialEffectMessage(this);
		pServerDE->WriteToMessageByte(hMsg, SFX_WEAPONHANDMODEL_ID);
		pServerDE->WriteToMessageDWord(hMsg, m_dwClientID);
		pServerDE->WriteToMessageByte(hMsg, (m_bLeftHand << 1) | DTRUE);
		pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED);
	}
*/
	// Set next update for 1 second to spawn a powerup
	pServerDE->SetNextUpdate( m_hObject, 1.0f);
}
예제 #16
0
void CClientExplosionSFX::Setup(DVector *vPos, DVector *vNormal, DFLOAT fOffset)
{
	VEC_COPY(m_vPos, *vPos);
	VEC_COPY(m_vNormal, *vNormal);
	m_fOffset = fOffset;

	if(m_fOffset)
	{
		DVector	temp;
		VEC_NORM(m_vNormal);
		VEC_MULSCALAR(temp, m_vNormal, m_fOffset);
		VEC_ADD(m_vPos, m_vPos, temp);
	}
}
예제 #17
0
void UndeadGideon::MC_Dodge_Left()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_DODGE_LEFT)
    {
        SetAnimation(m_pAnim_Sound->m_nAnim_JUMP[TYPE_MELEE]);

        m_pServerDE->SetModelLooping(m_hObject, DFALSE);

		DVector vVel, vLeft;
		VEC_MULSCALAR(vLeft, m_MoveObj.GetRightVector(), -1.0f);
		
		vVel.y = m_MoveObj.GetUpVector().y * m_fJumpSpeed;
		vVel.x = vLeft.x * m_fRunSpeed;
		vVel.z = vLeft.z * m_fRunSpeed;

		Move(vVel, MATH_EPSILON);

		m_nCurMetacmd = MC_DODGE_LEFT;
        m_bAnimating = DTRUE; 
    }
    else
    {        
		CollisionInfo collisionInfo;
		DVector vVel;

		m_pServerDE->GetVelocity(m_hObject,&vVel);

		m_pServerDE->GetStandingOn(m_hObject, &collisionInfo);

		if ((collisionInfo.m_hObject == m_pServerDE->GetWorldObject()) && (vVel.y <= 0.0f))
		{
			DVector vVel;
			VEC_INIT(vVel);

			Move(vVel, MATH_EPSILON);

			m_bAnimating = DFALSE; 
			Metacmd++;
		}
    }               
	
    return;
}
예제 #18
0
void GremlinAI::MC_Dodge_Left()
{
    if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_DODGE_LEFT)
    {
        SetAnimation(m_pAnim_Sound->m_nAnim_DODGE_RIGHT);

        m_pServerDE->SetModelLooping(m_hObject, DFALSE);

		DVector vVel, vLeft;
		VEC_MULSCALAR(vLeft, m_MoveObj.GetRightVector(), -1.0f);
		
		vVel.y = m_MoveObj.GetUpVector().y * m_fJumpSpeed;
		vVel.x = vLeft.x * m_fRunSpeed;
		vVel.z = vLeft.z * m_fRunSpeed;

		Move(vVel, MATH_EPSILON);

		m_nCurMetacmd = MC_DODGE_LEFT;
        m_bAnimating = DTRUE; 
    }
    else
    {        
		CollisionInfo collisionInfo;
		m_pServerDE->GetStandingOn(m_hObject, &collisionInfo);

		if (collisionInfo.m_hObject)
		{
			DVector vVel;
			VEC_INIT(vVel);

			Move(vVel, MATH_EPSILON);

			m_bAnimating = DFALSE; 
			Metacmd++;
		}
    }               
	
    return;
}
예제 #19
0
void CDestructable::ApplyDamagePhysics(DFLOAT fDamage, DVector *pvDir)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !pvDir) return;

	// Don't apply damage physics if the object is a trapped character (Andy 2/22/99)
	if(IsBaseCharacter(m_hObject))
	{
		CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(m_hObject);
		if(pObj->IsTrapped()) return;
	}

	if (VEC_MAGSQR(*pvDir) < 0.01) return;

	DVector vTemp, vVel;

	pServerDE->GetVelocity(m_hObject, &vVel);

	VEC_COPY(vTemp, *pvDir);
	VEC_NORM(vTemp);

	if (m_fMass <= 0) m_fMass = 1;
	
	DFLOAT fMultiplier = (fDamage * PA_DAMAGE_VEL_MUTLIPLIER) / m_fMass;

	VEC_MULSCALAR(vTemp, vTemp, fMultiplier);
	VEC_ADD(vVel, vTemp, vVel);

	// Accumulate damage velocity for player objects to send to the client..
	if (IsPlayer(m_hObject))
	{
		VEC_ADD(m_vAddVelocity, m_vAddVelocity, vTemp);
		m_bAddVelocity = DTRUE;
	}

	pServerDE->SetVelocity(m_hObject, &vVel);
}
예제 #20
0
void CPlayerCamera::CircleAroundTarget()
{
	if (!m_pClientDE || !m_hTarget) return;

	DVector vTargetPos;
	DRotation rRot;
	DVector vU, vR, vF;

	DFLOAT fTimeDelta = m_pClientDE->GetTime() - m_CircleStartTime;
	DFLOAT fAngle = fTimeDelta * DEFAULT_ROTATE_SPEED; // * MATH_PI * 2;
	fAngle = (DFLOAT)fmod(fAngle, MATH_PI*2);

	m_pClientDE->GetObjectRotation(m_hTarget, &rRot);
	m_pClientDE->EulerRotateY(&rRot, fAngle);
	m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);

	VEC_MULSCALAR(vF, vF, -m_CameraDistBack*1.2f)
//	VEC_ADD(vTargetPos, vTargetPos, vF);

	m_DeathOptX = vF.x;
	m_DeathOptZ = vF.z;
}
예제 #21
0
LTBOOL CParticleExplosionFX::CreateObject(ILTClient *pClientDE)
{
    LTBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE);
    if (!bRet) return bRet;

    // Initialize the emmitters velocity ranges based on our rotation...

    LTVector vVelMin, vVelMax, vTemp, vU, vR, vF;
    VEC_SET(vVelMin, 1.0f, 1.0f, 1.0f);
    VEC_SET(vVelMax, 1.0f, 1.0f, 1.0f);

    m_pClientDE->Common()->GetRotationVectors(m_rSurfaceRot, vU, vR, vF);

    if (vF.y <= -0.95f || vF.y >= 0.95f)
    {
        vF.y = vF.y > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 1.0f, 0.0f, 0.0f);
        VEC_SET(vU, 0.0f, 0.0f, 1.0f);
    }
    else if (vF.x <= -0.95f || vF.x >= 0.95f)
    {
        vF.x = vF.x > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 0.0f, 1.0f, 0.0f);
        VEC_SET(vU, 0.0f, 0.0f, 1.0f);
    }
    else if (vF.z <= -0.95f || vF.z >= 0.95f)
    {
        vF.z = vF.z > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 1.0f, 0.0f, 0.0f);
        VEC_SET(vU, 0.0f, 1.0f, 0.0f);
    }

    VEC_MULSCALAR(vVelMin, vF, m_vMinVel.y);
    VEC_MULSCALAR(vVelMax, vF, m_vMaxVel.y);

    VEC_MULSCALAR(vTemp, vR, m_vMinVel.x);
    VEC_ADD(vVelMin, vVelMin, vTemp);

    VEC_MULSCALAR(vTemp, vR, m_vMaxVel.x);
    VEC_ADD(vVelMax, vVelMax, vTemp);

    VEC_MULSCALAR(vTemp, vU, m_vMinVel.z);
    VEC_ADD(vVelMin, vVelMin, vTemp);

    VEC_MULSCALAR(vTemp, vU, m_vMaxVel.z);
    VEC_ADD(vVelMax, vVelMax, vTemp);


    // Initialize our emmitters...

    LTVector vStartVel;
    for (int i=0; i < m_nNumEmmitters; i++)
    {
        if (m_bCreateDebris)
        {
            m_hDebris[i] = CreateDebris();
        }

        m_ActiveEmmitters[i] = LTTRUE;
        m_BounceCount[i] = 2;

        VEC_SET(vStartVel, GetRandom(vVelMin.x, vVelMax.x),
                GetRandom(vVelMin.y, vVelMax.y),
                GetRandom(vVelMin.z, vVelMax.z));

        InitMovingObject(&(m_Emmitters[i]), &m_vPos, &vStartVel);
        m_Emmitters[i].m_PhysicsFlags |= m_nEmmitterFlags;
    }

    return bRet;
}
예제 #22
0
void CProjectileFX::Detonate(CollisionInfo* pInfo)
{
	if (!m_pClientDE || m_bDetonated) return;

    m_bDetonated = LTTRUE;

	SurfaceType eType = ST_UNKNOWN;

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

	// Determine the normal of the surface we are impacting on...

    LTVector vNormal;
	VEC_SET(vNormal, 0.0f, 1.0f, 0.0f);

	if (pInfo)
	{
		if (pInfo->m_hObject)
		{
			eType = GetSurfaceType(pInfo->m_hObject);
		}
		else if (pInfo->m_hPoly != INVALID_HPOLY)
		{
			eType = GetSurfaceType(pInfo->m_hPoly);

			VEC_COPY(vNormal, pInfo->m_Plane.m_Normal);

            LTRotation rRot(vNormal, LTVector(0.0f, 1.0f, 0.0f));
			m_pClientDE->SetObjectRotation(m_hServerObject, &rRot);

			// Calculate where we really hit the plane...

            LTVector vVel, vP0, vP1;
			g_pPhysicsLT->GetVelocity(m_hServerObject, &vVel);

			VEC_COPY(vP1, vPos);
			VEC_MULSCALAR(vVel, vVel, g_pGameClientShell->GetFrameTime());
			VEC_SUB(vP0, vP1, vVel);

            LTFLOAT fDot1 = VEC_DOT(pInfo->m_Plane.m_Normal, vP0) - pInfo->m_Plane.m_Dist;
            LTFLOAT fDot2 = VEC_DOT(pInfo->m_Plane.m_Normal, vP1) - pInfo->m_Plane.m_Dist;

			if (fDot1 < 0.0f && fDot2 < 0.0f || fDot1 > 0.0f && fDot2 > 0.0f)
			{
				VEC_COPY(vPos, vP1);
			}
			else
			{
                LTFLOAT fPercent = -fDot1 / (fDot2 - fDot1);
				VEC_LERP(vPos, vP0, vP1, fPercent);
			}
		}
	}
	else
	{
		// Since pInfo was null, this means the projectile's lifetime was up,
		// so we just blow-up in the air.

		eType = ST_AIR;
	}


    HOBJECT hObj = !!pInfo ? pInfo->m_hObject : LTNULL;
	::AddLocalImpactFX(hObj, m_vFirePos, vPos, vNormal, eType, m_vPath,
					   m_nWeaponId, m_nAmmoId, 0);

    m_bWantRemove = LTTRUE;
}
예제 #23
0
void Body::Init(const BODYINITSTRUCT& bi)
{
	if (!bi.pCharacter || !bi.pCharacter->m_hObject) return;

	// Get the death type etc

	m_eDeathType		= bi.pCharacter->GetDeathType();
	m_eModelId			= bi.pCharacter->GetModelId();
	m_eModelSkeleton    = bi.pCharacter->GetModelSkeleton();
	m_eModelStyle		= bi.pCharacter->GetModelStyle();

	// Get the body lifetime

	m_fLifetime		= bi.fLifetime;

	// Create the SFX

	BODYCREATESTRUCT bcs;
	bcs.eBodyState = bi.eBodyState;
	if (IsPlayer(bi.pCharacter->m_hObject))
	{
		CPlayerObj* pPlayer = (CPlayerObj*) bi.pCharacter;
		bcs.nClientId = (uint8) g_pLTServer->GetClientID(pPlayer->GetClient());
	}

    HMESSAGEWRITE hMessage = g_pLTServer->StartSpecialEffectMessage(this);
    g_pLTServer->WriteToMessageByte(hMessage, SFX_BODY_ID);
    bcs.Write(g_pLTServer, hMessage);
    g_pLTServer->EndMessage(hMessage);


	// Create the death scene

	CreateDeathScene(bi.pCharacter);

	// We'll handle creating the necessary debris...

	m_damage.m_bCreatedDebris = LTTRUE;

	m_damage.SetCanDamage(LTFALSE);//bi.pCharacter->CanDamageBody());
	m_damage.SetApplyDamagePhysics(LTFALSE);//bi.pCharacter->CanDamageBody());
	m_damage.SetMass(g_pModelButeMgr->GetModelMass(m_eModelId));

	// Let us get hit by decay powder

	m_damage.ClearCantDamageTypes(DamageTypeToFlag(DT_GADGET_DECAYPOWDER));

	switch ( g_pModelButeMgr->GetModelType(m_eModelId) )
	{
		case eModelTypeVehicle:
		{
			m_eDeathType = CD_GIB;
		}
		break;
	}

	CDestructible* pDest = bi.pCharacter->GetDestructible();
	if (pDest)
	{
		m_eDamageType = pDest->GetDeathType();
		VEC_COPY(m_vDeathDir, pDest->GetDeathDir());
		VEC_NORM(m_vDeathDir);
		VEC_MULSCALAR(m_vDeathDir, m_vDeathDir, 1.0f + (pDest->GetDeathDamage() / pDest->GetMaxHitPoints()));
	}

	LTFLOAT fHitPts = pDest->GetMaxHitPoints();
	m_damage.Reset(fHitPts, 0.0f);
	m_damage.SetHitPoints(fHitPts);
	m_damage.SetMaxHitPoints(fHitPts);
	m_damage.SetArmorPoints(0.0f);
	m_damage.SetMaxArmorPoints(0.0f);

	// Copy our user flags over, setting our surface type to flesh

    uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(m_hObject) | USRFLG_NIGHT_INFRARED;
	dwUsrFlags |= SurfaceToUserFlag(ST_FLESH);
    g_pLTServer->SetObjectUserFlags(m_hObject, dwUsrFlags);

	// Make sure model doesn't slide all over the place...

    g_pLTServer->SetFrictionCoefficient(m_hObject, 500.0f);

	LTVector vDims;
    g_pLTServer->GetObjectDims(bi.pCharacter->m_hObject, &vDims);

	// Set the dims.  If we can't set the dims that big, set them
	// as big as possible...

    if (g_pLTServer->SetObjectDims2(m_hObject, &vDims) == LT_ERROR)
	{
        g_pLTServer->SetObjectDims2(m_hObject, &vDims);
	}


	// Create the box used for weapon impact detection...

	CreateHitBox(bi);


	LTFLOAT r, g, b, a;
    g_pLTServer->GetObjectColor(bi.pCharacter->m_hObject, &r, &g, &b, &a);
    g_pLTServer->SetObjectColor(m_hObject, r, g, b, a);

	LTVector vScale;
    g_pLTServer->GetObjectScale(bi.pCharacter->m_hObject, &vScale);
    g_pLTServer->ScaleObject(m_hObject, &vScale);

	// Copy our animation over

    HMODELANIM hAni = g_pLTServer->GetModelAnimation(bi.pCharacter->m_hObject);
    g_pLTServer->SetModelAnimation(m_hObject, hAni);
    g_pLTServer->SetModelLooping(m_hObject, LTFALSE);

	// Copy the flags from the character to us

	uint32 dwFlags = g_pLTServer->GetObjectFlags(bi.pCharacter->m_hObject);
	m_dwFlags |= FLAG_REMOVEIFOUTSIDE;
    g_pLTServer->SetObjectFlags(m_hObject, dwFlags);

	// Move the attachments aggregate from the char to us...

	if (!m_pAttachments && bi.eBodyState != eBodyStateLaser)
	{
		m_hWeaponItem = bi.pCharacter->TransferWeapon(m_hObject);

		// Make sure we're playing the correct ani...

		if (m_hWeaponItem)
		{
			uint32 dwAni = g_pLTServer->GetAnimIndex(m_hWeaponItem, "Hand");
		 	if (dwAni != INVALID_ANI)
			{
				g_pLTServer->SetModelAnimation(m_hWeaponItem, dwAni);
				g_pLTServer->SetModelLooping(m_hWeaponItem, LTFALSE);
			}
		}
	}

	if (!m_pAttachments)
	{
		m_pAttachments = bi.pCharacter->TransferAttachments();

		if (m_pAttachments)
		{
			AddAggregate(m_pAttachments);
			m_pAttachments->ReInit(m_hObject);
		}
	}

	// Set up the spears

	bi.pCharacter->TransferSpears(this);

	// Set our state

	SetState(bi.eBodyState);
}
예제 #24
0
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;
}
예제 #25
0
파일: Debris.cpp 프로젝트: Arc0re/lithtech
void CDebris::Create(DVector vDir, DFLOAT fDamage)
{
	if (!g_pServerDE) return;

//	HCLASS hClass = g_pServerDE->GetClass( "CClientGibFX" );
//	if( !hClass )
//		return;

	VEC_NEGATE(vDir, vDir);

	DFLOAT fVelFactor = 1.0f;

//	DDWORD nType = m_eType*10;
//	if (nType == SURFTYPE_STONE || nType == SURFTYPE_METAL)
//		fVelFactor = 0.75f;

	DFLOAT fVel = 50.0f + fDamage;

	vDir.y -= 1.0f;
	VEC_NORM(vDir);

	VEC_MULSCALAR(vDir, vDir, fVel);

//	ObjectCreateStruct ocStruct;
//	INIT_OBJECTCREATESTRUCT(ocStruct);

	DVector vPos;
	g_pServerDE->GetObjectPos(m_hObject, &vPos);

	if (m_bExploding)
		AddExplosion(vPos);
	
//	VEC_COPY(ocStruct.m_Pos, vPos);
//	g_pServerDE->GetObjectRotation(m_hObject, &ocStruct.m_Rotation);

	DVector vDims;
	g_pServerDE->GetObjectDims( m_hObject, &vDims );

	DDWORD dwCustom = (m_hstrModel1 || m_hstrTexture1 || m_hstrSound) ? TYPEFLAG_CUSTOM : 0;

//	CClientGibFX* pGib;

	if (m_bStone /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_STONE/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_STONE/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bMetal /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_METAL/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_METAL/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bWood /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_WOOD/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_WOOD/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bTerrain /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_TERRAIN/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_TERRAIN/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bPlastic /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_PLASTIC/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_PLASTIC/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bGlass /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_GLASS/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_GLASS/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bFlesh /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_FLESH/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_FLESH/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bLiquid /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_LIQUID/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_LIQUID/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bEnergy /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_ENERGY/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_ENERGY/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}
}
예제 #26
0
DBOOL CSmokePuffFX::Update()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	if (m_fStartTime < 0)
	{
		m_fStartTime = m_fLastTime = fTime;
	}


	// Make sure we update our position relative to the server object (if the
	// server object is valid)...

	if (m_hServerObject)
	{
		DVector vServPos;
		m_pClientDE->GetObjectPos(m_hServerObject, &vServPos);
		m_pClientDE->SetObjectPos(m_hObject, &vServPos);
	}


	// Check to see if we should just wait for last smoke puff to go away...

	DFLOAT fTimeDelta = fTime - m_fStartTime;

	if (fTimeDelta > m_fLifeTime)
	{
		return DFALSE;
	}

	if (m_fDriftDeceleration)
	{
		DFLOAT fDecel = 1 - m_pClientDE->GetFrameTime() * m_fDriftDeceleration;
		VEC_MULSCALAR(m_vMinDriftVel, m_vMinDriftVel, fDecel);
		VEC_MULSCALAR(m_vMaxDriftVel, m_vMaxDriftVel, fDecel);
	}


	DFLOAT fScale = ((m_fLifeTime - fTimeDelta) / m_fLifeTime) * m_fMaxAlpha;

	// Adjust the alpha
	DFLOAT 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 add some more smoke...

	if (fTime > m_fLastTime + m_fParticleCreateDelta && (fTimeDelta < m_fCreateLifetime) )
	{
		DVector vDriftVel, vColor, vPos;

		// What is the range of colors?

		DFLOAT fRange = m_vColor2.x - m_vColor1.x;


		// Build the individual smoke puffs...

		for (DDWORD j=0; j < m_nNumParticles; j++)
		{
			DFLOAT fX, fY, fAngle, fRadius;
			fAngle = GetRandom(-MATH_PI, MATH_PI);
			fRadius = GetRandom(0.0f, m_fVolumeRadius);
			fX = fRadius * (DFLOAT)cos(fAngle);
			fY = fRadius * (DFLOAT)sin(fAngle);
			VEC_SET(vPos,  fX, -2.0f, fY);

			VEC_SET(vDriftVel,	
					GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), 
					GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), 
					GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z));

			if (!m_bIgnoreWind)
			{
				VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel);
			}

			DFLOAT fOffset  = GetRandom(m_vColor1.x, m_vColor2.x);
			DFLOAT fPercent = 1.0f;

			if (fRange > 0.01)
			{
				fPercent = fOffset / fRange;
			}

			vColor.x = m_vColor1.x + fOffset;

			fOffset = fPercent * (m_vColor2.y - m_vColor1.y);
			vColor.y = m_vColor1.y + fOffset;

			fOffset = fPercent * (m_vColor2.z - m_vColor1.z);
			vColor.z = m_vColor1.z + fOffset;

			DFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife);

			m_pClientDE->AddParticle(m_hObject, &vPos, &vDriftVel, &vColor, fLifeTime);
		}

		m_fLastTime = fTime;
	}

	return DTRUE;
}
예제 #27
0
void CNodeController::UpdateScriptControl(NCSTRUCT *pNodeControl)
{
    LTFLOAT fTime = g_pLTClient->GetTime() - pNodeControl->fScriptTime;
	ModelNScript eScript = (ModelNScript)pNodeControl->nScript;
	int nCurPt = pNodeControl->nCurrentScriptPt;
	int nLastPt = pNodeControl->nLastScriptPt;

//  g_pLTClient->CPrint("Running node script!");

	// Check to see if the script is over... and make it invalid if so
	if(fTime > g_pModelButeMgr->GetNScriptPtTime(eScript, nLastPt))
	{
//      g_pLTClient->CPrint("Ending node script!");

        pNodeControl->bValid = LTFALSE;
		return;
	}

	// Get access to the controls...
    ILTMath *pMathLT = g_pLTClient->GetMathLT();

	// Get the current script point
	while(fTime > g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt))
		nCurPt++;

	// Calculate the scale value from the last position to the current
    LTFLOAT fPtTime1 = g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt - 1);
    LTFLOAT fPtTime2 = g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt);
    LTFLOAT fScale = (fTime - fPtTime1) / (fPtTime2 - fPtTime1);

	//----------------------------------------------------------------------------
	// Setup the initial position vector
    LTVector vPos;

	// Get a direction vector from the last position to the current
    LTVector vPosDir = g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt) - g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt - 1);
	VEC_MULSCALAR(vPosDir, vPosDir, fScale);
	vPos = g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt - 1) + vPosDir;

	//----------------------------------------------------------------------------
	// Setup the initial rotation vector
    LTVector vRot;

	// Get a direction rotation from the last position to the current
    LTVector vRotDir = g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt) - g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt - 1);
	VEC_MULSCALAR(vRotDir, vRotDir, fScale);
	vRot = g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt - 1) + vRotDir;

	// Calculate the rotation...
    LTRotation rRot;
    LTVector vR, vU, vF;

    rRot.Init();
	pMathLT->GetRotationVectors(rRot, vR, vU, vF);

	pMathLT->RotateAroundAxis(rRot, vR, vRot.x);
	pMathLT->RotateAroundAxis(rRot, vU, vRot.y);
	pMathLT->RotateAroundAxis(rRot, vF, vRot.z);

	//----------------------------------------------------------------------------
	// Setup the matrix using the offset position and rotation
    LTMatrix m1;
	pMathLT->SetupTransformationMatrix(m1, vPos, rRot);
	m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1;
}
예제 #28
0
파일: MarkSFX.cpp 프로젝트: Arc0re/lithtech
DBOOL CMarkSFX::CreateObject(CClientDE *pClientDE)
{
	if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;

	CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr();
	if (!psfxMgr) return DFALSE;


	// Before we create a new buillet hole see if there is already another
	// bullet hole close by that we could use instead...

	CSpecialFXList* pList = psfxMgr->GetBulletHoleFXList();
	if (!pList) return DFALSE;

	int nNumBulletHoles = pList->GetSize();

	HOBJECT hMoveObj		 = DNULL;
	HOBJECT hObj			 = DNULL;
	DFLOAT	fClosestMarkDist = REGION_DIAMETER;
	DBYTE	nNumInRegion	 = 0;
	DVector vPos;

	for (int i=0; i < nNumBulletHoles; i++)
	{
		if ((*pList)[i])
		{
			hObj = (*pList)[i]->GetObject();
			if (hObj)
			{
				pClientDE->GetObjectPos(hObj, &vPos);
				
				DFLOAT fDist = VEC_DISTSQR(vPos, m_Pos);
				if (fDist < REGION_DIAMETER)
				{
					if (fDist < fClosestMarkDist)
					{
						fClosestMarkDist = fDist;
						hMoveObj = hObj;
					}

					if (++nNumInRegion > MAX_MARKS_IN_REGION)
					{
						// Just move this bullet-hole to the correct pos, and
						// remove thyself...

						pClientDE->SetObjectPos(hMoveObj, &m_Pos);
						return DFALSE;
					}
				}
			}
		}
	}


	// Setup the mark...
	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_SPRITE;
	_mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)m_pClientDE->GetStringData( m_hstrSprite ));
	createStruct.m_Flags	  = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE;
	VEC_COPY(createStruct.m_Pos, m_Pos);
	ROT_COPY( createStruct.m_Rotation, m_Rotation );

	m_hObject = pClientDE->CreateObject(&createStruct);

	m_pClientDE->SetObjectScale(m_hObject, &m_vScale);


	// See what it hit
	DVector vU, vR;
	pClientDE->GetRotationVectors(&m_Rotation, &vU, &vR, &m_vForward);

	ClientIntersectQuery iq;
	ClientIntersectInfo  ii;

	iq.m_Flags = INTERSECT_OBJECTS | INTERSECT_HPOLY;

	VEC_COPY(iq.m_From, vPos);			// Get start point at the last known position.
	VEC_MULSCALAR(iq.m_To, m_vForward, -1.0f);
	VEC_ADD(iq.m_To, iq.m_To, iq.m_From);	// Get destination point slightly past where we should be

	// Hit something!  try to clip against it. (since this is only being used for bullet marks,
	if (pClientDE->IntersectSegment(&iq, &ii))
	{
		HPOLY hPoly = ii.m_hPoly;
		pClientDE->ClipSprite(m_hObject, hPoly);
	}
	m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f);
	
	return DTRUE;
}
LTBOOL CBaseParticleSystemFX::Update()
{
    if (!CSpecialFX::Update() || !m_hObject || !m_pClientDE) return LTFALSE;


	// See if we should rotate this bad-boy...

	if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f)
	{
        LTFLOAT fDelta = g_pGameClientShell->GetFrameTime();

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

        LTVector vTemp;
		VEC_MULSCALAR(vTemp, m_vRotVel, fDelta);
		VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp);

		if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x);
		if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y);
		if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z);

		m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	}


	// Update each particles scale / alpha if necessary...

    LTParticle *pCur, *pTail;

	if (m_basecs.bAdjustParticleScale || m_basecs.bAdjustParticleAlpha)
	{
		if (m_pClientDE->GetParticles(m_hObject, &pCur, &pTail))
		{
            LTFLOAT fLifetime = 0.0f, fTotalLifetime = 0.0f;
            LTFLOAT fAlphaRange = m_basecs.fEndParticleAlpha - m_basecs.fStartParticleAlpha;
            LTFLOAT fScaleRange = m_basecs.fEndParticleScale - m_basecs.fStartParticleScale;
            LTVector vColorRange = m_vColor2 - m_vColor1;

			while (pCur && pCur != pTail)
			{
				m_pClientDE->GetParticleLifetime(m_hObject, pCur, fLifetime);
				m_pClientDE->GetParticleTotalLifetime(m_hObject, pCur, fTotalLifetime);

				if (fLifetime > 0.0f && fTotalLifetime > 0.0f)
				{
                    LTFLOAT fLifePercent = 1.0f - (fLifetime / fTotalLifetime);

					// Adjust scale...

					if (m_basecs.bAdjustParticleScale)
					{
						pCur->m_Size = m_fRadius * (m_basecs.fStartParticleScale + (fScaleRange * fLifePercent));
					}

					// Adjust alpha...

					if (m_basecs.bAdjustParticleAlpha)
					{
						pCur->m_Alpha = m_basecs.fStartParticleAlpha + (fAlphaRange * fLifePercent);
					}
				}

				pCur = pCur->m_pNext;
			}
		}
	}


	// Make sure we update our position relative to the server object
	// (if the server object is valid and the client isn't controling
	// the particle system pos)...

	if (m_hServerObject && !m_basecs.bClientControlsPos)
	{
        LTVector vNewPos;
		m_pClientDE->GetObjectPos(m_hServerObject, &vNewPos);
		vNewPos += m_vPosOffset;

		m_pClientDE->SetObjectPos(m_hObject, &vNewPos);
	}

    return LTTRUE;
}
예제 #30
0
LTBOOL CParticleTrailSegmentFX::Update()
{
    if (!m_hObject || !m_pClientDE) return LTFALSE;

    if (!CBaseParticleSystemFX::Update()) return LTFALSE;

	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
    if (!pSettings) return LTFALSE;

    uint8 nDetailLevel = pSettings->SpecialFXSetting();


    LTFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
        if (!m_hServerObject) return LTFALSE;

        m_bFirstUpdate = LTFALSE;
		m_fStartTime   = fTime;
		m_fLastTime	   = fTime;

		// Where is the server (moving) object...

        LTVector vPos, vTemp;
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);

		// Current position is relative to the particle system's postion (i.e.,
		// each puff of Particle is some distance away from the particle system's
		/// position)...

		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vPos, vPos, vTemp);

		VEC_COPY(m_vLastPos, vPos);
	}


	// Check to see if we should just wait for last Particle puff to go away...

	if (m_bWantRemove || (fTime > m_fStartTime + m_fFadeTime))
	{
		if (fTime > m_fLastTime + m_fLifeTime)
		{
            return LTFALSE;
		}

        LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime;

        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;
	}


	// See if it is time to create a new Particle puff...

	if ((fTime > m_fLastTime + m_fOffsetTime) && m_hServerObject)
	{
        LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor;

		// Calculate Particle puff position...

		// Where is the server (moving) object...

		m_pClientDE->GetObjectPos(m_hServerObject, &vCurPos);


		// Current position is relative to the particle system's postion (i.e.,
		// each puff of Particle is some distance away from the particle system's
		/// position)...

		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vCurPos, vCurPos, vTemp);


		// How long has it been since the last Particle puff?

        LTFLOAT fTimeOffset = fTime - m_fLastTime;


		// 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 Particle puffs...

		int nNumSteps = (m_fLastTime > 0) ? (((m_nType & PT_BLOOD) || (m_nType & PT_GIBSMOKE)) ? 20 : 5): 1;

		if (nDetailLevel != RS_HIGH)
		{
			nNumSteps /= 2;
		}

		VEC_SUB(vTemp, vCurPos, m_vLastPos);
		VEC_MULSCALAR(vDelta, vTemp, 1.0f/float(nNumSteps));

		VEC_COPY(vPos, m_vLastPos);

        LTFLOAT fCurLifeTime = 10.0f;
		if (nDetailLevel == RS_HIGH)
		{
			fCurLifeTime /= 2;
		}

        LTFLOAT fLifeTimeOffset = fTimeOffset / float(nNumSteps);

        LTFLOAT fOffset = 0.5f;

		int nNumPerPuff = GetNumParticles(m_nNumPerPuff);

		for (int i=0; i < nNumSteps; i++)
		{
			// Build the individual Particle puffs...

			for (int j=0; j < nNumPerPuff; j++)
			{
				VEC_COPY(vTemp, vPos);

				if (m_bIgnoreWind)
				{
					VEC_SET(vDriftVel, GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x),
									   GetRandom(5.0f, 6.0f),
									   GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z));
				}
				else
				{
					VEC_SET(vDriftVel, g_vWorldWindVel.x + GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x),
									   g_vWorldWindVel.y + GetRandom(5.0f, 6.0f),
									   g_vWorldWindVel.z + GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z));
				}

				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, fCurLifeTime);
			}

			VEC_ADD(vPos, vPos, vDelta);
			fCurLifeTime += fLifeTimeOffset;
		}

		m_fLastTime = fTime;

		VEC_COPY(m_vLastPos, vCurPos);
	}

    return LTTRUE;
}