示例#1
0
//given a capsule specified with a transform, two points, and a radius, this will approximate how much is submerged
//and distribute that force to the appropriate points on the capsule
static bool ApplyCapsuleBuoyancy(const LTVector& vPt1, const LTVector& vPt2, float fLength, float fRadius, 
								 const LTPlane& WSPlane, float& fVolume, LTVector& vApplyAt,
								 float& fSurfaceArea)
{
	//convert the capsule to an OBB and apply it
	
	//determine information about the main axis
	LTVector vMainAxis = vPt2 - vPt1;
	LTASSERT( fLength > 0.0f, "Invalid capsule length." );
	LTVector vUnitAxis = vMainAxis / fLength;

	//we can now build up a rotation given the plane normal and the axis to build our transform
	LTVector vUp = WSPlane.Normal();
	if(fabsf(vUp.Dot(vUnitAxis)) > 0.99f)
	{
		//too close to use, built an arbitrary orthonormal
		vUp = vUnitAxis.BuildOrthonormal();
	}

	LTMatrix3x4 mTemp;
	LTVector vRight = vUnitAxis.Cross(vUp);
	vRight.Normalize( );
	LTVector vTrueUp = vRight.Cross( vUnitAxis );
	mTemp.SetBasisVectors(vRight, vTrueUp, vUnitAxis);

	LTRotation rRot;
	rRot.ConvertFromMatrix(mTemp);

	//now we can form our transform
	LTRigidTransform tTransform((vPt1 + vPt2) * 0.5f, rRot);
	LTVector vHalfDims(fRadius, fRadius, fLength * 0.5f + fRadius);

	return ApplyOBBBuoyancy(tTransform, vHalfDims, WSPlane, fVolume, vApplyAt, fSurfaceArea);
}
bool CClientWeaponDisc::CalculateControlDirection( LTVector *pvControlDirection )
{
    //
    // safety check
    //

    // params
    ASSERT( 0 != pvControlDirection );

    // globals
    ASSERT( 0 != g_pLTClient );
    ASSERT( 0 != g_pPlayerMgr );


    //
    // The control direction is the direction the player is facing
    //

    // get the camera
    HOBJECT hCamera;
    hCamera = g_pPlayerMgr->GetCamera();
    ASSERT( 0 != hCamera );

    // determine the orientation of the segment
    LTRotation rRot;
    g_pLTClient->GetObjectRotation( hCamera, &rRot );

    // determine the direction of the segment
    LTVector vForward;
    *pvControlDirection = rRot.Forward();

    return true;
}
示例#3
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;
}
示例#4
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;
}
示例#5
0
void CDestructibleModel::DoExplosion(char* pTargetName)
{
	CWeapons weapons;
	weapons.Init(m_hObject);
	weapons.ObtainWeapon(m_nExplosionWeaponId);
	weapons.ChangeWeapon(m_nExplosionWeaponId);

	CWeapon* pWeapon = weapons.GetCurWeapon();
	if (!pWeapon) return;

	weapons.SetAmmo(pWeapon->GetAmmoId());

	pWeapon->SetDamageFactor(m_fDamageFactor);

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

	LTVector vF, vPos;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);
	vF = rRot.Forward();

	// Just blow up in place if we're not supposed to fire along
	// forward vector and we don't have a target...

	if (!m_bFireAlongForward)
	{
		pWeapon->SetLifetime(0.0f);
		VEC_SET(vF, 0.0f, -1.0f, 0.0f);  // Fire down
	}

	// See if we have a target...If so, point at it.

	if (pTargetName)
	{
		ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
		g_pLTServer->FindNamedObjects(pTargetName, objArray);

		if (objArray.NumObjects())
		{
			LTVector vObjPos;
			g_pLTServer->GetObjectPos(objArray.GetObject(0), &vObjPos);
			vF = vObjPos - vPos;
			vF.Normalize();

			rRot = LTRotation(vF, LTVector(0.0f, 1.0f, 0.0f));
			g_pLTServer->SetObjectRotation(m_hObject, &rRot);
		}
	}

	WeaponFireInfo weaponFireInfo;
	weaponFireInfo.hFiredFrom	= m_hObject;
	weaponFireInfo.vPath		= vF;
	weaponFireInfo.vFirePos	= vPos;
	weaponFireInfo.vFlashPos	= vPos;

	pWeapon->Fire(weaponFireInfo);
}
void GameBase::CreateBoundingBox()
{
	if (m_hDimsBox) return;

	if (!g_vtDimsAlpha.IsInitted())
	{
        g_vtDimsAlpha.Init(g_pLTServer, "DimsAlpha", LTNULL, 1.0f);
	}

	ObjectCreateStruct theStruct;
	INIT_OBJECTCREATESTRUCT(theStruct);

    LTVector vPos;
    g_pLTServer->GetObjectPos(m_hObject, &vPos);
	theStruct.m_Pos = vPos;

	SAFE_STRCPY(theStruct.m_Filename, "Models\\1x1_square.abc");
	SAFE_STRCPY(theStruct.m_SkinName, "Models\\1x1_square.dtx");

	theStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_GOTHRUWORLD;
	theStruct.m_ObjectType = OT_MODEL;

    HCLASS hClass = g_pLTServer->GetClass("BaseClass");
    LPBASECLASS pModel = g_pLTServer->CreateObject(hClass, &theStruct);

	if (pModel)
	{
		m_hDimsBox = pModel->m_hObject;

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

        LTVector vScale;
		VEC_DIVSCALAR(vScale, vDims, 0.5f);
        g_pLTServer->ScaleObject(m_hDimsBox, &vScale);
	}


    LTVector vOffset;
    LTRotation rOffset;
	vOffset.Init();
    rOffset.Init();

	HATTACHMENT hAttachment;
    LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hDimsBox, LTNULL,
											     &vOffset, &rOffset, &hAttachment);
    if (dRes != LT_OK)
	{
        g_pLTServer->RemoveObject(m_hDimsBox);
        m_hDimsBox = LTNULL;
	}

    LTVector vColor = GetBoundingBoxColor();

    g_pLTServer->SetObjectColor(m_hDimsBox, vColor.x, vColor.y, vColor.z, g_vtDimsAlpha.GetFloat());
}
示例#7
0
bool WorldModel::AttachServerMark( CServerMark& mark, CLIENTWEAPONFX & theStruct)
{
	LTransform globalTransform, parentTransform, localTransform;
    ILTTransform *pTransformLT;
    LTVector vParentPos, vOffset;
    LTRotation rParentRot, rRot;
    LTRotation rOffset;

	pTransformLT = g_pLTServer->GetTransformLT();

	// Attach the mark to the parent object...

	// Figure out what the rotation we want is.
    rOffset.Init();
	rRot = LTRotation(theStruct.vSurfaceNormal, LTVector(0.0f, 1.0f, 0.0f));


	// MD
	// Ok, now we have the transform in global space but attachments are specified in
	// local space (so they can move as the object moves and rotates).

	// Set the global LTransform.
	pTransformLT->Set(globalTransform, theStruct.vPos, rRot);

	// Get the object's transform.
	g_pLTServer->GetObjectPos( m_hObject, &vParentPos);
	g_pLTServer->GetObjectRotation( m_hObject, &rParentRot);
	parentTransform.m_Pos = vParentPos;
	parentTransform.m_Rot = rParentRot;
	
	parentTransform.m_Scale.Init(1,1,1);
	globalTransform.m_Scale.Init(1,1,1);

	// Get the offset.
	pTransformLT->Difference(localTransform, globalTransform, parentTransform);
	vOffset = localTransform.m_Pos;
	rOffset = localTransform.m_Rot;


	HATTACHMENT hAttachment = NULL;
    LTRESULT dRes = g_pLTServer->CreateAttachment( m_hObject, mark.m_hObject, LTNULL,
											     &vOffset, &rOffset, &hAttachment);
    if (dRes != LT_OK)
	{
		return false;
	}

	// Add to the attachment list.
	LTObjRefNotifier ref( *this );
	ref = mark.m_hObject;
	m_AttachmentList.push_back( ref );

	return true;
}
示例#8
0
void CCoin::RotateToRest()
{
	if ( !m_bRotatedToRest )
	{
		char szSpawn[1024];
		sprintf(szSpawn, "WeaponItem Gravity 0;AmmoAmount 1;WeaponType Coin;AmmoType Coin");

		LTVector vPos;
		g_pLTServer->GetObjectPos(m_hObject, &vPos);
		vPos.y += 2.0f; // This offsets us from the floor a bit so we don't pop through when WeaponItem sets its dims.

		LTRotation rRot;
		rRot.Init();

		BaseClass* pObj = SpawnObject(szSpawn, vPos, rRot);

		if ( pObj && pObj->m_hObject )
		{
			g_pLTServer->SetAcceleration(pObj->m_hObject, &LTVector(0,0,0));
			g_pLTServer->SetVelocity(pObj->m_hObject, &LTVector(0,0,0));
		}

		g_pLTServer->SetObjectFlags(m_hObject, g_pLTServer->GetObjectFlags(m_hObject)&~FLAG_VISIBLE);
	}

	CGrenade::RotateToRest();

	if ( IsCharacter(m_hFiredFrom) )
	{
		LTVector vPosition;
        g_pLTServer->GetObjectPos(m_hObject, &vPosition);

        CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(m_hFiredFrom);

		CharCoinInfo cinfo;
        cinfo.fTime = g_pLTServer->GetTime();
		cinfo.eSurfaceType = m_eLastHitSurface;
		cinfo.vPosition = vPosition;

		SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eLastHitSurface);
		_ASSERT(pSurf);
		if (pSurf)
		{
			cinfo.fVolume = pSurf->fMovementNoiseModifier;
		}
		else
		{
			cinfo.fVolume = 1.0f;
		}

		pCharacter->SetLastCoinInfo(&cinfo);
	}
}
LTBOOL CBaseParticleSystemFX::CreateObject(ILTClient *pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE)) return LTFALSE;

    LTVector vPos = m_vPos;
    LTRotation rRot;
	rRot.Init();

	// Use server object position if a position wasn't specified...

	if (m_hServerObject)
	{
        LTVector vZero(0, 0, 0), vServObjPos;
        if (vPos.Equals(vZero))
        {
			pClientDE->GetObjectPos(m_hServerObject, &vServObjPos);
			vPos = vServObjPos;
		}
		else
		{
            m_basecs.bClientControlsPos = LTTRUE;
		}

		// Calculate our offset from the server object...

		m_vPosOffset = vPos - vServObjPos;
	}

	// Use the specified rotation if applicable

	if (!m_rRot.IsIdentity())
	{
		rRot = m_rRot;
	}


	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_PARTICLESYSTEM;
	createStruct.m_Flags = FLAG_VISIBLE | FLAG_UPDATEUNSEEN | FLAG_FOGDISABLE;
	createStruct.m_Pos = vPos;
	createStruct.m_Rotation = rRot;

	m_hObject = m_pClientDE->CreateObject(&createStruct);

	// Setup the ParticleSystem...

	return SetupSystem();
}
void CMuzzleFlashFX::SetRot(LTRotation rRot)
{
	if (!m_pClientDE) return;

	HOBJECT hObj;

	if (m_bUsingParticles)
	{
		hObj = m_Particle.GetObject();
		if (hObj)
		{
			if (g_vtReallyClose.GetFloat())
			{
				LTRotation rInitRot;
				rInitRot.Init();
				m_pClientDE->SetObjectRotation(hObj, &rInitRot);
			}
			else
			{
				m_pClientDE->SetObjectRotation(hObj, &rRot);
			}
		}
	}

	if (m_bUsingLight)
	{
		hObj = m_Light.GetObject();
		if (hObj)
		{
            m_pClientDE->SetObjectRotation(hObj, &rRot);
		}
	}

	if (m_bUsingScale)
	{
		hObj = m_Scale.GetObject();
		if (hObj)
		{
			LTRotation rTempRot = rRot;

			// Camera relative rotation...
			if (m_cs.bPlayerView)
			{
				rTempRot.Init();
			}

            m_pClientDE->SetObjectRotation(hObj, &rTempRot);
		}
	}
}
示例#11
0
bool GunMount::FireWeapon( )
{
	CWeapon* pWeapon = m_Arsenal.GetCurWeapon( );
	if( !pWeapon )
		return false;

	// Get the direction we're firing.
	LTRotation rot;
	g_pLTServer->GetObjectRotation( m_hObject, &rot );
	LTVector vDir = rot.Forward( );

	LTVector vPos;
	if( !GetFirePos( vPos ))
	{
		g_pLTServer->GetObjectPos( m_hObject, &vPos );
	}

	// Tell the weapon to fire.
	WeaponFireInfo weaponFireInfo;
	static uint8 s_nCount = GetRandom( 0, 255 );
	s_nCount++;

	weaponFireInfo.hFiredFrom	= m_hObject;
	weaponFireInfo.hFiringWeapon = pWeapon->GetModelObject( );
	weaponFireInfo.vPath		= vDir;
	weaponFireInfo.vFirePos		= vPos;
	weaponFireInfo.vFlashPos	= vPos;
	weaponFireInfo.nSeed		= (uint8)GetRandom( 2, 255 );
	weaponFireInfo.nPerturbCount	= s_nCount;
	weaponFireInfo.nFireTimestamp = g_pLTServer->GetRealTimeMS( );

	WeaponState eWeaponState = pWeapon->UpdateWeapon( weaponFireInfo, true );
	if( eWeaponState == W_FIRED )
	{
		// Count the round as fired.
		if( m_nRoundsToFire > 0 )
			m_nRoundsToFire--;

	}

	// Keep ammo count up and clip loaded.  The weapon could have refused
	// firing due to weapon fire time limitations, but it still decrements
	// ammo.
	m_Arsenal.AddAmmo( pWeapon->GetAmmoRecord(), 10 );
	pWeapon->ReloadClip( false );

	return true;
}
示例#12
0
void SecurityCamera::CreateLight()
{
	// Create the light...and attach it to the camera...

	ObjectCreateStruct theStruct;
	INIT_OBJECTCREATESTRUCT(theStruct);

	theStruct.m_Pos = m_vPos;

	g_pServerButeMgr->GetSecurityCameraString("GreenLight",
		theStruct.m_Filename, ARRAY_LEN(theStruct.m_Filename));

	theStruct.m_Flags = FLAG_VISIBLE | FLAG_GLOWSPRITE;
	theStruct.m_Flags2 = FLAG2_ADDITIVE;
	theStruct.m_ObjectType = OT_SPRITE;

    HCLASS hClass = g_pLTServer->GetClass("BaseClass");
    LPBASECLASS pSprite = g_pLTServer->CreateObject(hClass, &theStruct);
	if (!pSprite) return;

	m_hLight = pSprite->m_hObject;

    LTVector vScale(1, 1, 1);
	vScale.x = g_pServerButeMgr->GetSecurityCameraFloat("LightScale");
	vScale.y = vScale.x;

    g_pLTServer->ScaleObject(m_hLight, &vScale);

	// Attach the sprite to the the camera...

    LTVector vOffset(0, 0, 0);
    LTRotation rOffset;
	rOffset.Init();

	HATTACHMENT hAttachment;
    LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hLight, "Light",
											     &vOffset, &rOffset, &hAttachment);
    if (dRes != LT_OK)
	{
        g_pLTServer->RemoveObject(m_hLight);
        m_hLight = LTNULL;
		return;
	}
}
示例#13
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;
}
示例#14
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;
}
示例#15
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;
		}
	}
}
示例#16
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;
}
示例#17
0
void CDestructibleModel::SetSurfaceType()
{
	uint32 dwSurfUsrFlgs = 0;
	SurfaceType eSurfType = ST_UNKNOWN;

	// See if this object is a world model...

	if (GetObjectType(m_hObject) == OT_WORLDMODEL)
	{
        LTBOOL bDoBruteForce = LTTRUE;

		// See if we have a surface override...

		if (m_hstrSurfaceOverride)
		{
			const char* pSurfName = g_pLTServer->GetStringData(m_hstrSurfaceOverride);
			if (pSurfName)
			{
				SURFACE* pSurf = g_pSurfaceMgr->GetSurface(pSurfName);
				if (pSurf && pSurf->eType != ST_UNKNOWN)
				{
					eSurfType = pSurf->eType;
					bDoBruteForce = LTFALSE;
				}
			}
		}


		// Determine our surface...the hard way...

		if (bDoBruteForce)
		{
			IntersectQuery qInfo;
			IntersectInfo iInfo;

			LTVector vPos, vDims;
			LTRotation rRot;

			g_pLTServer->GetObjectPos(m_hObject, &vPos);
			g_pLTServer->GetObjectRotation(m_hObject, &rRot);
			g_pPhysicsLT->GetObjectDims(m_hObject, &vDims);

			LTFLOAT fMaxDims = vDims.x;
			fMaxDims = Max(fMaxDims, vDims.y);
			fMaxDims = Max(fMaxDims, vDims.z);

			qInfo.m_From = vPos + (rRot.Forward() * (fMaxDims + 1));
			qInfo.m_To   = vPos;

			qInfo.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY;

			SurfaceType eType = ST_UNKNOWN;

			if (g_pLTServer->IntersectSegment(&qInfo, &iInfo))
			{
				if (iInfo.m_hObject == m_hObject)
				{
					eSurfType = GetSurfaceType(iInfo);
				}
			}
		}
	}
	else
	{
		DEBRIS* pDebris = g_pDebrisMgr->GetDebris(m_nDebrisId);
		if (pDebris)
		{
			eSurfType = pDebris->eSurfaceType;
		}
	}

	dwSurfUsrFlgs = SurfaceToUserFlag(eSurfType);
	g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, dwSurfUsrFlgs, dwSurfUsrFlgs);

	g_pCommonLT->GetObjectFlags(m_hObject, OFT_Flags, m_dwOriginalFlags);
}
示例#18
0
bool CCreateRayFX::Update( float tmFrameTime )
{
	//track our performance
	CTimedSystemBlock TimingBlock(g_tsClientFXCreateRayFX);

	//update our base object
	BaseUpdate(tmFrameTime);
	
	//we only want to create the effect as we become active
	if(IsInitialFrame() && (GetProps()->m_nNumToCreate > 0))
	{
		//determine the object position and orientation of our object
		LTVector vObjPos;
		LTRotation rObjRot;

		GetCurrentTransform(GetUnitLifetime(), vObjPos, rObjRot);

		//handle two special pipelines to gain performance when there is no scattering
		if(MATH_RADIANS_TO_DEGREES(GetProps()->m_fRandomCone) < 1.0f)
		{
			LTRigidTransform tHitTrans;
			HOBJECT hHitObj;

			//no scattering, just do a single intersection for all effects
			if(DetermineIntersection(vObjPos, rObjRot.Forward(), hHitObj, tHitTrans))
			{
				//and now generate all of our effects
				for(uint32 nCurrEffect = 0; nCurrEffect < GetProps()->m_nNumToCreate; nCurrEffect++)
				{
					CLIENTFX_CREATESTRUCT CreateStruct("", GetProps()->m_nFXFlags, hHitObj, tHitTrans);
					CBaseCreateFX::CreateEffect(CreateStruct);
				}
			}
		}
		else
		{
			//we need to scatter

			//extract our vectors from the orientation
			LTVector vObjRight, vObjUp, vObjForward;
			rObjRot.GetVectors(vObjRight, vObjUp, vObjForward);

			//and now generate all of our effects
			for(uint32 nCurrEffect = 0; nCurrEffect < GetProps()->m_nNumToCreate; nCurrEffect++)
			{
				LTRigidTransform tHitTrans;
				HOBJECT hHitObj;

				//now build up the forward within a specified cone

				//first off spin it randomly around the forward
				float fPlaneAngle = GetRandom(0.0f, MATH_CIRCLE);
				LTVector vPlaneVector = vObjRight * cosf(fPlaneAngle) + vObjUp * sinf(fPlaneAngle);

				//now tilt it away from the forward vector
				float fTiltPercent	= powf(GetRandom(0.0f, 1.0f), GetProps()->m_fCenterBias);
				float fTiltAngle	= fTiltPercent * GetProps()->m_fRandomCone;
				LTVector vRandomForward = vObjForward * cosf(fTiltAngle) + vPlaneVector * sinf(fTiltAngle);

				if(DetermineIntersection(vObjPos, vRandomForward, hHitObj, tHitTrans))
				{
					CLIENTFX_CREATESTRUCT CreateStruct("", GetProps()->m_nFXFlags, hHitObj, tHitTrans);
					CBaseCreateFX::CreateEffect(CreateStruct);
				}
			}
		}
	}

	//we always return false because we always want to be placed into a shutting down state since
	//we just emit and then do nothing
	return false;
}
示例#19
0
void CNodeController::UpdateHeadFollowPosControl(NCSTRUCT *pNodeControl)
{
    LTVector vPos;
    LTRotation rRot;
	LTransform transform;
    LTVector vU, vR, vF;

	//----------------------------------------------------------------------
	// Get information about the control node...
	// *** NOTE: On the head node... vU faces forward, vR faces down, vF faces right ***

	// Get access to the controls...
    ILTMath *pMathLT = g_pLTClient->GetMathLT();
    ILTModel *pModelLT = g_pLTClient->GetModelLT();
    ILTTransform *pTransformLT = g_pLTClient->GetTransformLT();

	// Get the transform of the node we're controlling
    pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), m_aNodes[pNodeControl->eModelNode].hModelNode, transform, LTTRUE);

	// Decompose the transform into the position and rotation
	pTransformLT->Get(transform, vPos, rRot);
	pMathLT->GetRotationVectors(rRot, vR, vU, vF);

	// Get information about the follow position...
    LTVector vObjPos = pNodeControl->vFollowPos;

	// Turn the follow control off if the expire time has past
	if(pNodeControl->fFollowExpireTime <= 0.0f)
	{
		pNodeControl->fFollowExpireTime = 0.0f;
        pNodeControl->bFollowOn = LTFALSE;
	}
	else
        pNodeControl->fFollowExpireTime -= g_pGameClientShell->GetFrameTime();

	//----------------------------------------------------------------------
	// Setup the rotation matrix to directly follow the destination position

	// Get the direction that we're going to face...
    LTVector vDir = vObjPos - vPos;

	// Setup some temp vectors that are on the x/z plane...
    LTVector vTempU, vTempF, vTempDir;
	vTempU = vU; vTempU.y = 0.0f;
	vTempF = vF; vTempF.y = 0.0f;
	vTempDir = vDir; vTempDir.y = 0.0f;

	VEC_NORM(vTempU);
	VEC_NORM(vTempF);
	VEC_NORM(vTempDir);

	// Get the dot products between the dir vector and the up and forward to determine the rotation angles
    LTFLOAT fDotUDir = VEC_DOT(vTempU, vTempDir);
    LTFLOAT fDotFDir = VEC_DOT(vTempF, vTempDir);
    LTFLOAT fDotRDir = 0.0f;

	// Init the vectors to get a rotation matrix from...
    LTVector vRotAxisR(1.0f, 0.0f, 0.0f);

	// Get the first rotation angle
    LTFLOAT fAngle1 = pNodeControl->bFollowOn ? fDotUDir : 1.0f;
	if(fAngle1 < -0.1f) fAngle1 = -0.1f;		// HACK! Limit the head rotation
	fAngle1 = (1.0f - fAngle1) * MATH_HALFPI;
	if(fDotFDir < 0.0f) fAngle1 *= -1.0f;

	// Do a full rotation around the first axis so we can get an angle for the second axis
    LTFLOAT fTempAngle = pNodeControl->bFollowOn ? ((1.0f - fDotUDir) * MATH_HALFPI) : 0.0f;
	pMathLT->RotateAroundAxis(rRot, vR, (fDotFDir < 0.0f) ? -fTempAngle : fTempAngle);
	pMathLT->GetRotationVectors(rRot, vR, vU, vF);

	VEC_NORM(vDir);
	fDotUDir = VEC_DOT(vU, vDir);
	fDotRDir = VEC_DOT(vR, vDir);

	// Get the second rotation angle
    LTFLOAT fAngle2 = pNodeControl->bFollowOn ? fDotUDir : 1.0f;
	if(fAngle2 < 0.25f) fAngle2 = 0.25f;		// HACK! Limit the head rotation
	fAngle2 = (1.0f - fAngle2) * MATH_HALFPI;
	if(fDotRDir > 0.0f) fAngle2 *= -1.0f;

	// Calculate a max rotation value
    LTFLOAT fRotMax = (pNodeControl->fFollowRate * g_pGameClientShell->GetFrameTime() / 180.0f) * MATH_PI;

	// Interpolate the angles based off the previous angle
	if(fAngle1 > pNodeControl->vFollowAngles.y + fRotMax) fAngle1 = pNodeControl->vFollowAngles.y + fRotMax;
	else if(fAngle1 < pNodeControl->vFollowAngles.y - fRotMax) fAngle1 = pNodeControl->vFollowAngles.y - fRotMax;

	if(fAngle2 > pNodeControl->vFollowAngles.x + fRotMax) fAngle2 = pNodeControl->vFollowAngles.x + fRotMax;
	else if(fAngle2 < pNodeControl->vFollowAngles.x - fRotMax) fAngle2 = pNodeControl->vFollowAngles.x - fRotMax;

	// Create a new rotation and rotate around each controlled axis
    LTRotation rNewRot;
    rNewRot.Init();

	pMathLT->RotateAroundAxis(rNewRot, vRotAxisR, fAngle1);
	pNodeControl->vFollowAngles.y = fAngle1;

	pMathLT->GetRotationVectors(rNewRot, vR, vU, vF);

	pMathLT->RotateAroundAxis(rNewRot, vF, fAngle2);
	pNodeControl->vFollowAngles.x = fAngle2;

	// If we're turned off and back at the start rotation... make the control invalid
	if(!pNodeControl->bFollowOn && pNodeControl->vFollowAngles.x == 0.0f && pNodeControl->vFollowAngles.y == 0.0f)
	{
        pNodeControl->bValid = LTFALSE;
		return;
	}

	// Create a rotation matrix and apply it to the current offset matrix
    LTMatrix m1;
	pMathLT->SetupRotationMatrix(m1, rNewRot);
	m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1;
}
示例#20
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;
}
示例#21
0
void CNodeController::UpdateLipSyncControl(NCSTRUCT *pNodeControl)
{
	// Make sure the sound handle is valid and check to see if the sound is done...
    if(!pNodeControl->hLipSyncSound || g_pLTClient->IsDone(pNodeControl->hLipSyncSound))
	{
		g_pLTClient->KillSound(pNodeControl->hLipSyncSound);
        pNodeControl->hLipSyncSound = LTNULL;

		if (pNodeControl->bShowingSubtitles)
		{
 			g_pInterfaceMgr->ClearSubtitle();
		}

        pNodeControl->pSixteenBitBuffer = LTNULL;
        pNodeControl->pEightBitBuffer = LTNULL;
        pNodeControl->bValid = LTFALSE;
		return;
	}


	//
	// Process the current sound data (average over sound amplitude).
	//

    LTFLOAT fAverage = 0.0f;  // this will hold the average, normalized from 0.0f to 1.0f.

	// Get the sound buffer.
	if( !pNodeControl->pSixteenBitBuffer && !pNodeControl->pEightBitBuffer )
	{
        uint32 dwChannels = 0;

        g_pLTClient->GetSoundData(pNodeControl->hLipSyncSound,
							pNodeControl->pSixteenBitBuffer,
							pNodeControl->pEightBitBuffer,
							&pNodeControl->dwSamplesPerSecond,
							&dwChannels);
		ASSERT( dwChannels == 1);
		// If you want to use multi-channel sounds (why would you?), you'll need to
		//  to account for the interleaving of channels in the following code.
	}

	ASSERT( pNodeControl->pSixteenBitBuffer || pNodeControl->pEightBitBuffer );


	// Average over the data.  We do an average of the data from the current point
	// being played to 1/g_vtLipSyncFreq.GetFloat() seconds ahead of that point.
    uint32 dwOffset = 0;
    uint32 dwSize   = 0;

    if( LT_OK == g_pLTClient->GetSoundOffset(pNodeControl->hLipSyncSound, &dwOffset, &dwSize) )
	{
		// Determine the end of the data we wish to average over.
        const uint32 dwDivisor = uint32(g_vtLipSyncFreq.GetFloat());
        uint32 dwOffsetEnd = dwOffset + pNodeControl->dwSamplesPerSecond/dwDivisor;
		if( dwOffsetEnd > dwSize )
			dwOffsetEnd = dwSize;


		// Accumulate the the amplitudes for the average.
        uint32 dwMaxAmplitude = 0;

        uint32 dwNumSamples = 0;
        uint32 dwAccum = 0;

		if( pNodeControl->pSixteenBitBuffer )
		{
			for( int16 * pIterator = pNodeControl->pSixteenBitBuffer + dwOffset;
			     pIterator < pNodeControl->pSixteenBitBuffer + dwOffsetEnd;
				 ++pIterator)
			{
				dwAccum += abs(*pIterator);
				++dwNumSamples;
			}

			dwMaxAmplitude = 65536/2;

			#ifdef GRAPH_LIPSYNC_SOUND
				g_GraphPoints.RecordData(pNodeControl->pSixteenBitBuffer,dwSize,dwOffset);
			#endif

		}
		else if( pNodeControl->pEightBitBuffer )
		{
			for( int8 * pIterator = pNodeControl->pEightBitBuffer + dwOffset;
			     pIterator < pNodeControl->pEightBitBuffer + dwOffsetEnd;
				 ++pIterator)
			{
				dwAccum += abs(*pIterator);
				++dwNumSamples;
			}

			dwMaxAmplitude = 256/2;

			#ifdef GRAPH_LIPSYNC_SOUND
				g_GraphPoints.RecordData(pNodeControl->pEightBitBuffer,dwSize,dwOffset);
			#endif
		}

		// And find the average!
		if( dwNumSamples > 0 )
            fAverage = LTFLOAT(dwAccum) / LTFLOAT(dwNumSamples) / LTFLOAT(dwMaxAmplitude);

    } //if( LT_OK == g_pLTClient->GetSoundOffset(pNodeControl->hLipSyncSound, &dwOffset, &dwSize) )

	//
	// Do the rotation.
	//
    ILTMath *pMathLT = g_pLTClient->GetMathLT();

    LTRotation rRot;
    rRot.Init();
    LTVector vAxis(0.0f, 0.0f, 1.0f);
    LTFLOAT fMaxRot = MATH_DEGREES_TO_RADIANS(g_vtLipSyncMaxRot.GetFloat());

	// Calculate the rotation.
	m_fCurLipSyncRot =  fAverage*fMaxRot;
	pMathLT->RotateAroundAxis(rRot, vAxis, -m_fCurLipSyncRot);

	// Create a rotation matrix and apply it to the current offset matrix
    LTMatrix m1;
	pMathLT->SetupRotationMatrix(m1, rRot);
	m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1;
}
示例#22
0
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTronPlayerObj::GetDefensePercentage()
//
//	PURPOSE:	How much of the attack damage has our defenese prevented
//
//	NOTES:		There are actually 2 defense percentages.  One is based
//				on timing, i.e. player's reation speed, animation speed,
//				etc.  The other is based on the player's orientation to
//				the incoming projectile.  If the vector parameter is
//				specified, BOTH percentages will be computed and the
//				combined result will be returned.  If the vector is NOT
//				specified, only the timing will be computed.
//
// ----------------------------------------------------------------------- //
float CTronPlayerObj::GetDefensePercentage( LTVector const *pIncomingProjectilePosition /*=0*/) const
{
	if ( TRONPLAYEROBJ_NO_DEFEND == m_cDefendType )
	{
		// not blocking
		return 0.0f;
	}

	//
	// Do this in 2 passes.  The first pass willl determine
	// the contribution to the defense percentage due to the
	// timing of the player/animations.  The second pass
	// will add the contribution of the player's orientation.
	//
	float fDefenseTimingPercentage;
	float fDefenseOrientationPercentage;

	// get the weapon
	AMMO const *pAmmoData = g_pWeaponMgr->GetAmmo( m_cDefendAmmoId );
	ASSERT( 0 != pAmmoData );
	ASSERT( 0 != pAmmoData->pProjectileFX );

	// get the ammo specific data
	DISCCLASSDATA *pDiscData =
		dynamic_cast< DISCCLASSDATA* >(
			pAmmoData->pProjectileFX->pClassData
		);
	ASSERT( 0 != pDiscData );


	//
	// Determine Timing Percentage
	//

	switch ( m_cDefendType )
	{
		case MPROJ_START_SWAT_BLOCK:
		case MPROJ_START_ARM_BLOCK:
		{
			// get the current server time
			float fCurrentServerTime = g_pLTServer->GetTime() * 1000.0f;

			// make sure we're within the range of the block
			if ( ( static_cast< int >( fCurrentServerTime ) -
			       m_nDefendServerTimeStarted ) > m_nDefendDuration )
			{
				// nope, the block is over
				return 0.0f;
			}

			// Swat and Arm defenses are similar, so fill out these
			// variables uniquely (depending on which case we are
			// handling), then use the common generic math to figure
			// out the answer.
			float fMidpointTime;
			float fMaxStartTime;
			float fMaxEndTime;
			float fStartDefendPercentage;
			float fMaxDefendPercentage;
			float fEndDefendPercentage;

			if ( MPROJ_START_SWAT_BLOCK == m_cDefendType )
			{
				// determine at exactly what time the midpoint takes place
				// NOTE: this is relative time, not absolute
				fMidpointTime = 
					( pDiscData->fSwatDefendMidpoint * m_nDefendDuration );

				// determine at exactly what time the max starts
				// NOTE: this is relative time, not absolute
				fMaxStartTime =
					fMidpointTime - 
					fMidpointTime * pDiscData->fSwatDefendStartMaxDefendPercentage;

				// determine at exactly what time the max ends
				// NOTE: this is relative time, not absolute
				fMaxEndTime =
					fMidpointTime +
					(
						( m_nDefendDuration - fMidpointTime ) *
						pDiscData->fSwatDefendEndMaxDefendPercentage
					);

				// determine the starting defend percentage
				fStartDefendPercentage = pDiscData->fSwatDefendStartDefendPercentage;

				// detecmine the max defend percentage					
				fMaxDefendPercentage = pDiscData->fSwatDefendMaxDefendPercentage;

				// determine the ending defend percentage
				fEndDefendPercentage = pDiscData->fSwatDefendEndDefendPercentage;
			}
			else if ( MPROJ_START_ARM_BLOCK == m_cDefendType )
			{
				// Not implemented yet.  The main question I haven't figured
				// out yet is where does the information come from?
				fMidpointTime = 0.0f;
				fMaxStartTime = 0.0f;
				fMaxEndTime = 0.0f;
				fStartDefendPercentage = 0.0f;
				fMaxDefendPercentage = 0.0f;
				fEndDefendPercentage = 0.0f;
			}

			// determine at exactly how much time we've been in the block
			// NOTE: this is relative time, not absolute
			float fBlockTime = 
				fCurrentServerTime - m_nDefendServerTimeStarted;

			if ( ( -MATH_EPSILON <= fBlockTime ) && 
			     ( fBlockTime <= fMaxStartTime ) )
			{
				// somewhere on the uprise
				fDefenseTimingPercentage =
					fStartDefendPercentage + 
						(
							(
								( 
									fMaxDefendPercentage -
									fStartDefendPercentage
								) /
								fMaxStartTime 
							) * 
							fBlockTime
						);
			}
			else if ( ( fMaxStartTime < fBlockTime ) &&
			          ( fBlockTime <= fMaxEndTime ) )
			{
				// within the max range
				fDefenseTimingPercentage = fMaxDefendPercentage;
			}
			else if ( ( fMaxEndTime < fBlockTime ) &&
			          ( fBlockTime <= m_nDefendDuration ) )
			{
				// somewhere on the downfall
				fDefenseTimingPercentage =
					fMaxDefendPercentage - 
						(
							(
								( 
									fMaxDefendPercentage -
									fEndDefendPercentage
								) /
								( m_nDefendDuration - fMaxEndTime )
							) * 
							( fBlockTime - fMaxEndTime )
						);
			}
			else
			{
				// math problem, we should be here if we are outside
				// the bounds of the defense
				ASSERT( 0 );
				fDefenseTimingPercentage = 0.0f;
			}
		}
		break;


		case MPROJ_START_HOLD_BLOCK:
		{
			// get the current server time
			float fCurrentServerTime = g_pLTServer->GetTime() * 1000.0f;

			// determine the starting defend percentage
			float fStartDefendPercentage = pDiscData->fHoldDefendStartDefendPercentage;

			// determine the max defend percentage					
			float fMaxDefendPercentage = pDiscData->fHoldDefendMaxDefendPercentage;

			// determine at exactly how much time we've been in the block
			// NOTE: this is relative time, not absolute
			float fBlockTime = 
				fCurrentServerTime - m_nDefendServerTimeStarted;

			if ( ( -MATH_EPSILON <= fBlockTime ) && 
			     ( fBlockTime <= m_nDefendDuration ) )
			{
				// somewhere on the uprise
				fDefenseTimingPercentage =
					fStartDefendPercentage + 
						(
							(
								( 
									fMaxDefendPercentage -
									fStartDefendPercentage
								) /
								static_cast< float >( m_nDefendDuration )
							) * 
							fBlockTime
						);
			}
			else if ( m_nDefendDuration < fBlockTime )
			{
				// within the max range
				fDefenseTimingPercentage = fMaxDefendPercentage;
			}
			else
			{
				// math problem, we should be here if we are outside
				// the bounds of the defense
				ASSERT( 0 );
				fDefenseTimingPercentage = 0.0f;
			}
		}
		break;

		case MPROJ_END_HOLD_BLOCK:
		{
			// get the current server time
			float fCurrentServerTime = g_pLTServer->GetTime() * 1000.0f;

			// make sure we're within the range of the block
			if ( ( static_cast< int >( fCurrentServerTime ) -
			       m_nDefendServerTimeStarted ) > m_nDefendDuration )
			{
				// nope, the block is over
				return 0.0f;
			}

			// detecmine the max defend percentage					
			float fMaxDefendPercentage = pDiscData->fHoldDefendMaxDefendPercentage;

			// determine the ending defend percentage
			float fEndDefendPercentage = pDiscData->fHoldDefendEndDefendPercentage;

			// determine at exactly how much time we've been in the block
			// NOTE: this is relative time, not absolute
			float fBlockTime = 
				fCurrentServerTime - m_nDefendServerTimeStarted;

			// somewhere on the downfall
			fDefenseTimingPercentage =
				fMaxDefendPercentage - 
					(
						(
							( 
								fMaxDefendPercentage -
								fEndDefendPercentage
							) /
							( m_nDefendDuration )
						) * 
						( fBlockTime )
					);
		}
		break;

		default:
		{
			// There is some type of block defined that we
			// are not handling, and we SHOULD be handling it.
			ASSERT( 0 );

			return 0.0f;
		}
		break;
	};


	//TODO: skip this section of the camera position is too old?

	// check if the oriention percentage should be computed
	if ( 0 == pIncomingProjectilePosition )
	{
		// No vector specifed, there is no way
		// to compute orientation defense.
		return fDefenseTimingPercentage;
	}

	//
	// Determine Orientation percentage
	//

	// The 3 cases are the same, but they could have different
	// control values.  Figure out what the specific variables
	// are (depending on the specific type of block), then apply
	// the generic equations.

	float fOrientationMinDefendPercentage;
	float fOrientationMaxDefendPercentage;
	float fOrientationDeadZone;
	float fOrientationMaxZone;

	switch ( m_cDefendType )
	{
		case MPROJ_START_SWAT_BLOCK:
		{
			fOrientationMinDefendPercentage  = pDiscData->fSwatDefendOrientationMinDefendPercentage;
			fOrientationMaxDefendPercentage  = pDiscData->fSwatDefendOrientationMaxDefendPercentage;
			fOrientationDeadZone             = MATH_PI - pDiscData->fSwatDefendOrientationDeadZone;
			fOrientationMaxZone              = pDiscData->fSwatDefendOrientationMaxZone;
		}
		break;

		case MPROJ_START_HOLD_BLOCK:
		case MPROJ_END_HOLD_BLOCK:
		{
			fOrientationMinDefendPercentage  = pDiscData->fHoldDefendOrientationMinDefendPercentage;
			fOrientationMaxDefendPercentage  = pDiscData->fHoldDefendOrientationMaxDefendPercentage;
			fOrientationDeadZone             = MATH_PI - pDiscData->fHoldDefendOrientationDeadZone;
			fOrientationMaxZone              = pDiscData->fHoldDefendOrientationMaxZone;
		}
		break;

		case MPROJ_START_ARM_BLOCK:
		{
			// Not implemented yet.  The main question I haven't figured
			// out yet is where does the information come from?
			fOrientationMinDefendPercentage  = 0.0f;
			fOrientationMaxDefendPercentage  = 0.0f;
			fOrientationDeadZone             = 0.0f;
			fOrientationMaxZone              = 0.0f;
		}
		break;

		default:
		{
			// There is some type of block defined that we
			// are not handling, and we SHOULD be handling it.
			ASSERT( 0 );

			return 0.0f;
		}
		break;
	};

	LTRESULT ltResult;
	LTVector vDefendPos;
	LTVector vDefendPosToProjectile;

	// get the player's position
	ltResult = g_pLTServer->GetObjectPos( m_hObject, &vDefendPos );
	ASSERT( LT_OK == ltResult );

	// REMOVE THIS CODE FOR FINAL RELEASE, BUT LEAVE FOR TESTING MULTIPLAYER
	// print a warning if the time is new enough
	if ( TRONPLAYEROBJ_CLIENT_CAMERA_TIME_OLD_THRESHOLD < ( g_pLTServer->GetTime() - m_nClientCameraOffsetTimeReceivedMS ) )
	{
		g_pLTServer->CPrint( "Client Camera Offset time is low, possible lag\n" );
		g_pLTServer->CPrint( "   condition that will affect defensive accuracy.\n" );
		g_pLTServer->CPrint( "   Currnt value is %5.3f units old.\n", ( g_pLTServer->GetTime() - m_nClientCameraOffsetTimeReceivedMS ) );

	}
	
	// add the camera offset vDefendPos += m_vClientCameraOffset;

	// find a unit vector from us to the projectile
	vDefendPosToProjectile  = *pIncomingProjectilePosition -
	                         ( m_vClientCameraOffset +
	                           vDefendPos );
	vDefendPosToProjectile.y = 0;
	vDefendPosToProjectile.Normalize();

	// determine a forward vector reprensenting the direction the
	// player is facing
	LTRotation vPlayerViewOrientation;
	ltResult = g_pLTServer->GetObjectRotation( m_hObject, &vPlayerViewOrientation );
	ASSERT( LT_OK == ltResult );

	LTVector vPlayerViewForward = vPlayerViewOrientation.Forward();
	vPlayerViewForward.y = 0;
	vPlayerViewForward.Normalize();

	float fDotProd = vPlayerViewForward.Dot( vDefendPosToProjectile );

	// find the angle between the two vectors
	float fDefenseAngle = ltacosf( vPlayerViewForward.Dot( vDefendPosToProjectile ) );

	if ( ( MATH_EPSILON <= fDefenseAngle) && ( fDefenseAngle <= fOrientationMaxZone ) )
	{
		// it's within the max zone
		fDefenseOrientationPercentage = fOrientationMaxDefendPercentage;
	}
	else if ( ( fOrientationMaxZone < fDefenseAngle) && ( fDefenseAngle <= fOrientationDeadZone ) )
	{
		// it's within the dropoff range
		fDefenseOrientationPercentage = 
			fOrientationMaxDefendPercentage +
			( fDefenseAngle - fOrientationMaxZone ) *
				( fOrientationMinDefendPercentage - fOrientationMaxDefendPercentage ) /
				( fOrientationDeadZone - fOrientationMaxZone );
	}
	else if ( fOrientationDeadZone <= fDefenseAngle)
	{
		// it's within the dead zone
		fDefenseOrientationPercentage = 0.0f;
	}

	//
	// Final Defense Result
	//

	float fFinalDefensePercentage = fDefenseTimingPercentage -
	                                fDefenseOrientationPercentage;
	return fFinalDefensePercentage;
}
示例#23
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();
}
示例#24
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 );
	}
}
示例#25
0
bool CTracerFX::Init(const FX_BASEDATA *pBaseData, const CBaseFXProps *pProps)
{
	//track our performance
	CTimedSystemBlock TimingBlock(g_tsClientFXTracer);

	//cleanup any old data
	Term();

	// Perform base class initialisation
	if( !CBaseFX::Init(pBaseData, pProps))
		return false;

	//determine our starting position and orientation
	LTVector vPos;
	LTRotation rRot;

	GetCurrentTransform(0.0f, vPos, rRot);	
	m_vStartPos = vPos;

	//determine what target position we want to use
	LTVector vTargetPos;

	//if we are using target data, just get the transform from this
	if(GetProps()->m_bUseTargetPos && pBaseData->m_bUseTargetData)
	{
		LTRigidTransform tTargetOffset(pBaseData->m_vTargetOffset, LTRotation::GetIdentity());
		LTRigidTransform tWS = GetWorldSpaceTransform(NULL, pBaseData->m_hTargetObject, INVALID_MODEL_NODE, INVALID_MODEL_SOCKET, tTargetOffset);

		LTVector vToTarget = tWS.m_vPos - vPos;
		m_fRayLength	= vToTarget.Mag();
		m_vDirection	= vToTarget / m_fRayLength;
		vTargetPos		= tWS.m_vPos;
	}
	else
	{
		//determine the end point where we want to stop testing
		m_vDirection	= rRot.Forward();
		m_fRayLength	= GetProps()->m_fMaxDistance;
		vTargetPos		= vPos + m_vDirection * m_fRayLength;
	}

	//handle intersection if we need to
	if(GetProps()->m_bBlockedByGeometry)
	{
		//we need to perform a ray cast and determine if we actually hit anything in the world. If not,
		//we just want to use the maximum tracer length
		IntersectQuery	iQuery;
		IntersectInfo	iInfo;

		iQuery.m_Flags		= INTERSECT_HPOLY | INTERSECT_OBJECTS | IGNORE_NONSOLID;
		iQuery.m_FilterFn	= TracerListFilterFn;
		iQuery.m_pUserData	= NULL;
		iQuery.m_From		= m_vStartPos;
		iQuery.m_To			= vTargetPos;

		//now find the point of intersection
		if( g_pLTClient->IntersectSegment( iQuery, &iInfo ) )
		{
			//we hit something, so use that as our ending position
			m_fRayLength = (iInfo.m_Point - m_vStartPos).Mag();
		}
	}

	//now determine our starting position (this is zero unless we start emitted, in which case
	//it is the length of the tracer)
	if(GetProps()->m_bStartEmitted)
	{
		//determine the length of this tracer
		m_fRayPosition = GetTracerLength();
	}
	
	// Combine the direction we would like to face with our parents rotation...
	ObjectCreateStruct ocs;
	
	//create a custom render object with the associated material
	ocs.m_Pos				= vPos;
	ocs.m_Rotation			= rRot;
	ocs.m_ObjectType		= OT_CUSTOMRENDER;
	
	if(!GetProps()->m_bSolid)
		ocs.m_Flags2 |= FLAG2_FORCETRANSLUCENT;

	if(!GetProps()->m_bTranslucentLight)
		ocs.m_Flags |= FLAG_NOLIGHT;
	
	m_hObject = g_pLTClient->CreateObject( &ocs );
	if( !m_hObject )
		return false;

	//setup our rendering layer
	if(GetProps()->m_bPlayerView)
		g_pLTClient->GetRenderer()->SetObjectDepthBiasTableIndex(m_hObject, eRenderLayer_Player);

	//setup the callback on the object so that it will render us
	g_pLTClient->GetCustomRender()->SetRenderingSpace(m_hObject, eRenderSpace_World);
	g_pLTClient->GetCustomRender()->SetRenderCallback(m_hObject, CustomRenderCallback);
	g_pLTClient->GetCustomRender()->SetCallbackUserData(m_hObject, this);

	//load up the material for this particle system, and assign it to the object
	HMATERIAL hMaterial = g_pLTClient->GetRenderer()->CreateMaterialInstance(GetProps()->m_pszMaterial);
	g_pLTClient->GetCustomRender()->SetMaterial(m_hObject, hMaterial);
	g_pLTClient->GetRenderer()->ReleaseMaterialInstance(hMaterial);

	//we don't setup the visibility for this object yet since when it starts out it is not visible

	//setup the dynamic light object if the user specified a radius
	if(GetProps()->m_fLightRadius > 0.1f)
	{
		ObjectCreateStruct LightOCS;
		LightOCS.m_Pos			= vPos;
		LightOCS.m_Rotation		= rRot;
		LightOCS.m_ObjectType	= OT_LIGHT;

		m_hTracerLight = g_pLTClient->CreateObject( &LightOCS );

		//setup the properties of the light
		g_pLTClient->SetLightRadius(m_hTracerLight, GetProps()->m_fLightRadius);
		g_pLTClient->SetObjectColor(m_hTracerLight, VEC4_EXPAND(GetProps()->m_vLightColor));
		g_pLTClient->SetLightType(m_hTracerLight, eEngineLight_Point);
		g_pLTClient->SetLightDetailSettings(m_hTracerLight, GetProps()->m_eLightLOD, GetProps()->m_eWorldShadowsLOD, GetProps()->m_eObjectShadowsLOD);
	}

	// Success !!
	return true;
}
示例#26
0
void CTargetMgr::CheckForIntersect(float &fDistAway)
{
	m_hTarget = LTNULL;
	m_ActivationData.Init();

	uint32 dwUsrFlags = 0;
	const float fMaxDist = 100000.0f;

	// Cast ray from the camera to see if there is an object to activate...

    LTRotation rRot;
    LTVector vPos;

	HLOCALOBJ hCamera = g_pPlayerMgr->GetCamera();
	g_pLTClient->GetObjectPos(hCamera, &vPos);
	g_pLTClient->GetObjectRotation(hCamera, &rRot);

 	m_ActivationData.m_vPos = vPos;
	m_ActivationData.m_rRot = rRot;

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	IQuery.m_From = vPos;
	IQuery.m_To   = IQuery.m_From + (rRot.Forward() * fMaxDist);

	// NOTE the use of the CHECK_FROM_POINT_INSIDE_OBJECTS flag.  This flag will
	// make sure that any objects that m_From is inside are considered
	IQuery.m_Flags = CHECK_FROM_POINT_INSIDE_OBJECTS | INTERSECT_HPOLY | INTERSECT_OBJECTS | IGNORE_NONSOLID;

	IQuery.m_FilterActualIntersectFn	= ActivateFilterFn;
	IQuery.m_pActualIntersectUserData	= (void*)&IQuery;
	IQuery.m_PolyFilterFn				= DoVectorPolyFilterFn;

	// [KLS 8/3/02] - ActivateFilterFn may save an object to use that may not be
	// the best activation choice (i.e., a fallback choice).  However, if a
	// better choice isn't found, the fallback choice should be used.  That
	// fallback choice is stored in g_adFallbackActivationObject so we clear
	// it here...
	g_adFallbackActivationObject.Init();

	if (g_pLTClient->IntersectSegment(&IQuery, &IInfo))
	{
		m_ActivationData.m_vIntersect = IInfo.m_Point;

        if (IsMainWorld(IInfo.m_hObject))
		{
			if (IInfo.m_hPoly != INVALID_HPOLY)
			{
				SurfaceType eType = GetSurfaceType(IInfo.m_hPoly);
				SURFACE *pSurf = g_pSurfaceMgr->GetSurface(eType);

				// See if the surface we tried to activate has an activation
				// sound...If so, the user can activate it...

				if (pSurf && pSurf->szActivationSnd[0] && pSurf->fActivationSndRadius > 0)
				{
					m_hTarget = IInfo.m_hObject;
					m_ActivationData.m_hTarget = m_hTarget;
					m_ActivationData.m_nSurfaceType = eType;
				}
			}
		}
		else
		{
			LTVector vObjPos = m_ActivationData.m_vIntersect;
			vObjPos -= vPos;

			if (vObjPos.Mag() <= fMaxDist)
			{
				m_hTarget = IInfo.m_hObject;
				m_ActivationData.m_hTarget = m_hTarget;
			}
		}

		// Calculate how far away the object is...

		LTVector vDist = m_ActivationData.m_vIntersect - vPos;
		fDistAway = vDist.Mag();
	}
	
	// [KLS 8/3/02] - Use the fallback object if we have one and we didn't 
	// find another object more suitable object... 

	bool bCanUseFallback = (m_ActivationData.m_hTarget ? false : true);
	if (!bCanUseFallback)
	{
		// We can still use the fallback object if it isn't the world or a
		// world model...

		if (IsMainWorld(m_ActivationData.m_hTarget) || 
			OT_WORLDMODEL == GetObjectType(m_ActivationData.m_hTarget))
		{
			bCanUseFallback = true;
		}
	}

	if ( bCanUseFallback && g_adFallbackActivationObject.m_hTarget )
	{
		// Ok we hit the fallback object reset some of our target data
	
		LTVector vObjPos;
		g_pLTClient->GetObjectPos(g_adFallbackActivationObject.m_hTarget, &vObjPos);

		m_ActivationData.m_vIntersect = vObjPos;

		vObjPos -= vPos;

		if (vObjPos.Mag() <= fMaxDist)
		{
			m_hTarget = g_adFallbackActivationObject.m_hTarget;
			m_ActivationData.m_hTarget = m_hTarget;
		}

		// Calculate how far away the object is...

		LTVector vDist = m_ActivationData.m_vIntersect - vPos;
		fDistAway = vDist.Mag();
	}
}
示例#27
0
LTBOOL CProjectileFX::CreateObject(ILTClient* pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE) || !m_hServerObject) return LTFALSE;

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

    uint8 nDetailLevel = pSettings->SpecialFXSetting();

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

	//m_pClientDE->CPrint("Client start pos (%.2f, %.2f, %.2f)", vPos.x, vPos.y, vPos.z);
	//m_fStartTime = m_pClientDE->GetTime();

	if (nDetailLevel != RS_LOW)
	{
		if (m_nFX & PFX_SMOKETRAIL)
		{
			CreateSmokeTrail(vPos, rRot);
		}

		if (m_nFX & PFX_LIGHT)
		{
			CreateLight(vPos, rRot);
		}
	}

	if (m_nFX & PFX_FLARE)
	{
		CreateFlare(vPos, rRot);
	}

	if (m_nFX & PFX_FLYSOUND)
	{
		CreateFlyingSound(vPos, rRot);
	}


	// Do client-side projectiles in multiplayer games...

	if ( g_pClientMultiplayerMgr->IsConnectedToRemoteServer( ))
	{
		// Set the velocity of the "server" object if it is really just a local
		// object...

		if (m_bLocal)
		{
			VEC_COPY(m_vFirePos, vPos);

			m_fStartTime = m_pClientDE->GetTime();

            LTVector vVel, vF;
			vF = rRot.Forward();

			m_vPath = vF;

			// Special case of adjusting the projectile speed...

            LTFLOAT fVel = (LTFLOAT) m_pProjectileFX->nVelocity;
			if (m_bAltFire)
			{
                fVel = (LTFLOAT) m_pProjectileFX->nAltVelocity;
			}

            LTFLOAT fMultiplier = 1.0f;
            if (m_pClientDE->GetSConValueFloat("MissileSpeed", fMultiplier) != LT_NOTFOUND)
			{
				fVel *= fMultiplier;
			}

			vVel = vF * fVel;
			g_pPhysicsLT->SetVelocity(m_hServerObject, &vVel);
		}
	}

    return LTTRUE;
}
示例#28
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);
}
示例#29
0
void CLTMessage_Write::WriteYRotation(CPacket_Write &cPacket, const LTRotation &cRotation)
{
	LTVector forward = cRotation.Forward();
	float fAngle = (float)atan2(forward.x, forward.z);
	cPacket.Writeint8((int8)(fAngle * (127.0f / MATH_PI)));
}
示例#30
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;
  	}
}