Exemplo n.º 1
0
LTBOOL CScanner::CanSeeObject(ObjectFilterFn ofn, HOBJECT hObject)
{
	_ASSERT(hObject);
    if (!hObject) return LTFALSE;

	if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && m_nPlayerTeamFilter && IsPlayer(hObject))
	{
		CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(hObject);
		if (pPlayer->GetTeamID() != m_nPlayerTeamFilter)
			return LTFALSE;
	}


    LTVector vPos;
    g_pLTServer->GetObjectPos(hObject, &vPos);

    LTVector vDir;
	vDir = vPos - GetScanPosition();

	if (VEC_MAGSQR(vDir) >= m_fVisualRange)
	{
        return LTFALSE;
	}

	vDir.Norm();

    LTRotation rRot = GetScanRotation();

    LTVector vUp, vRight, vForward;
    g_pLTServer->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

    LTFLOAT fDp = vDir.Dot(vForward);

	if (fDp < m_fFOV)
	{
        return LTFALSE;
	}

	// See if we can see the position in question

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, GetScanPosition());
	VEC_COPY(IQuery.m_To, vPos);
	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = ofn;

    if (g_pLTServer->IntersectSegment(&IQuery, &IInfo))
	{
		if (IInfo.m_hObject == hObject)
		{
            return LTTRUE;
		}
	}

    return LTFALSE;
}
Exemplo n.º 2
0
//determines if this polygon is concave or not
bool CEditPoly::IsConcave()
{
	uint32 nNumPts = NumVerts();

	if(nNumPts <= 3)
	{
		return false;
	}

	//get the normal for this polygon
	LTVector vNormal = Normal();

	//now go through every edge
	uint32 nPrevPt = nNumPts - 1;
	for(uint32 nCurrPt = 0; nCurrPt < nNumPts; nPrevPt = nCurrPt, nCurrPt++)
	{
		//build the edge normal
		LTVector vEdge = m_pBrush->m_Points[Index(nCurrPt)] - m_pBrush->m_Points[Index(nPrevPt)];

		//find the normal
		LTVector vEdgeNorm = vNormal.Cross(vEdge);
		vEdgeNorm.Norm();

		//now run through all the other points
		for(uint32 nTestPt = 0; nTestPt < nNumPts; nTestPt++)
		{
			//ignore the points on the edge
			if((nTestPt == nCurrPt) || (nTestPt == nPrevPt))
				continue;

			//see if it is on the correct side
			if(vEdgeNorm.Dot(m_pBrush->m_Points[Index(nTestPt)] - m_pBrush->m_Points[Index(nCurrPt)]) > 0.001f)
			{
				return true;
			}
		}
	}

	return false;

}
Exemplo n.º 3
0
LTBOOL CScanner::CanSeePos(ObjectFilterFn ofn, const LTVector& vPos)
{
    LTVector vDir;
	vDir = vPos - GetScanPosition();

	if (VEC_MAGSQR(vDir) >= m_fVisualRange)
	{
        return LTFALSE;
	}

	vDir.Norm();

    LTRotation rRot = GetScanRotation();

    LTVector vUp, vRight, vForward;
    g_pLTServer->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

    LTFLOAT fDp = vDir.Dot(vForward);

	if (fDp < m_fFOV)
	{
        return LTFALSE;
	}

	// See if we can see the position in question

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, GetScanPosition());
	VEC_COPY(IQuery.m_To, vPos);
	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = ofn;

    if (!g_pLTServer->IntersectSegment(&IQuery, &IInfo))
	{
        return LTTRUE;
	}

    return LTFALSE;
}
static void CreateServerExitMark(const CLIENTWEAPONFX & theStruct)
{
	SURFACE* pSurf = g_pSurfaceMgr->GetSurface((SurfaceType)theStruct.nSurfaceType);
	if (!pSurf || !pSurf->bCanShootThrough) return;

	int nMaxThickness = pSurf->nMaxShootThroughThickness;
	if (nMaxThickness < 1) return;

	// Determine if there is an "exit" surface...

	IntersectQuery qInfo;
	IntersectInfo iInfo;

    LTVector vDir = theStruct.vPos - theStruct.vFirePos;
	vDir.Norm();

    qInfo.m_From = theStruct.vPos + (vDir * (LTFLOAT)(nMaxThickness + 1));
	qInfo.m_To   = theStruct.vPos;

	qInfo.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY;

	SurfaceType eType = ST_UNKNOWN;

    if (g_pLTServer->IntersectSegment(&qInfo, &iInfo))
	{
		eType = GetSurfaceType(iInfo);
		if (ShowsMark(eType))
		{
            LTRotation rNormRot;
            g_pLTServer->AlignRotation(&rNormRot, &(iInfo.m_Plane.m_Normal), LTNULL);

			CLIENTWEAPONFX exitStruct = theStruct;
			exitStruct.vPos = iInfo.m_Point + vDir;
			exitStruct.vSurfaceNormal = iInfo.m_Plane.m_Normal;

            CreateServerMark(exitStruct);
		}
	}
}
Exemplo n.º 5
0
void gr_BuildFrameOfReference(LTVector *pVec, LTVector *pUpRef, LTVector *pRight, LTVector *pUp, LTVector *pForward)
{
	LTVector tempRef;

	*pForward = *pVec;
	pForward->Norm();

	// Treat the vector as the forward vector and come up with 2 other vectors.
	if(pUpRef)
	{
		tempRef = *pUpRef;
		tempRef.Norm();
		gr_GetPerpendicularVector(pForward, &tempRef, pUp);
	}
	else
	{
		gr_GetPerpendicularVector(pForward, LTNULL, pUp);
	}

	// Create the right vector.	
	*pRight = pForward->Cross(*pUp);
}
void Breakable::CrushObject(HOBJECT hObj)
{
	if (!hObj) return;

    LTVector vPos;
    LTVector vHisPos;

    g_pLTServer->GetObjectPos(m_hObject, &vPos);
    g_pLTServer->GetObjectPos(m_hObject, &vHisPos);

    LTVector vDir = vPos - vHisPos;
	vDir.Norm();

	DamageStruct damage;

	damage.eType	= DT_CRUSH;
	damage.fDamage	= damage.kInfiniteDamage;
	damage.hDamager = m_hObject;
	damage.vDir		= vDir;

	damage.DoDamage(this, hObj);
}
Exemplo n.º 7
0
LTBOOL CSearchLightFX::Update()
{
    if (!m_pClientDE || !m_hServerObject || m_bWantRemove || !m_hBeam) return LTFALSE;

    uint32 dwFlags = 0;

	// Update the lens flare...

	m_LensFlare.Update();

	// Hide/show the fx if necessary...

	if (m_hServerObject)
	{
        uint32 dwUserFlags;
		m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwUserFlags);

		if (!(dwUserFlags & USRFLG_VISIBLE))  // Hide fx
		{
			if (m_hBeam)
			{
				dwFlags = m_pClientDE->GetObjectFlags(m_hBeam);
				m_pClientDE->SetObjectFlags(m_hBeam, dwFlags & ~FLAG_VISIBLE);
			}
			if (m_hLight)
			{
				dwFlags = m_pClientDE->GetObjectFlags(m_hLight);
				m_pClientDE->SetObjectFlags(m_hLight, dwFlags & ~FLAG_VISIBLE);
			}

            return LTTRUE;
		}
		else  // Make all fx visible
		{
			if (m_hBeam)
			{
				dwFlags = m_pClientDE->GetObjectFlags(m_hBeam);
				m_pClientDE->SetObjectFlags(m_hBeam, dwFlags | FLAG_VISIBLE);
			}
			if (m_hLight)
			{
				dwFlags = m_pClientDE->GetObjectFlags(m_hLight);
				m_pClientDE->SetObjectFlags(m_hLight, dwFlags | FLAG_VISIBLE);
			}
		}
	}


	// Update the position/rotation of the beam...

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

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

    LTVector vU, vR, vF;
	m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);


	// See how long to make the beam...

    LTVector vDest = vPos + (vF * m_cs.fBeamLength);

	IntersectInfo iInfo;
	IntersectQuery qInfo;
	qInfo.m_Flags		= INTERSECT_OBJECTS | IGNORE_NONSOLID;
	qInfo.m_FilterFn	= AttackerLiquidFilterFn;
	qInfo.m_pUserData	= m_hServerObject;
	qInfo.m_From		= vPos;
	qInfo.m_To			= vDest;

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

    LTVector vDir = vDest - vPos;
    LTFLOAT fDistance = vDir.Mag();
	vDir.Norm();

    LTVector vNewPos = vPos + vDir * fDistance/2.0f;
	m_pClientDE->AlignRotation(&rRot, &vDir, NULL);

	if (m_cs.fBeamRotTime > 0.0f)
	{
		m_fBeamRotation += (360.0f/m_cs.fBeamRotTime * g_pGameClientShell->GetFrameTime());
		m_fBeamRotation = m_fBeamRotation > 360.0f ? m_fBeamRotation - 360.0f : m_fBeamRotation;
		m_pClientDE->RotateAroundAxis(&rRot, &vDir, DEG2RAD(m_fBeamRotation));
	}

	m_pClientDE->SetObjectRotation(m_hBeam, &rRot);
	m_pClientDE->SetObjectPos(m_hBeam, &vNewPos);

    LTVector vScale(m_cs.fBeamRadius, m_cs.fBeamRadius, fDistance);
	m_pClientDE->SetObjectScale(m_hBeam, &vScale);


	// Move the dynamic light...

	if (m_hLight)
	{
		vDest -= (vDir * 5.0f);
		m_pClientDE->SetObjectPos(m_hLight, &vDest);
	}

    return LTTRUE;
}
Exemplo n.º 8
0
void Lock::HandleGadgetMsg(HOBJECT hSender, ConParse & parse)
{
	if (parse.m_nArgs < 2 || !parse.m_Args[1]) return;

	AMMO* pAmmo = g_pWeaponMgr->GetAmmo(atol(parse.m_Args[1]));
	if (!pAmmo) return;

	LTBOOL bProcess = LTFALSE;

	if (m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_WELDER)
	{
		bProcess = LTTRUE;
	}
	else if (m_bLightable && pAmmo->eInstDamageType == DT_GADGET_LIGHTER)
	{
		bProcess = LTTRUE;
	}
	else if (!m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_LOCK_PICK)
	{
		bProcess = LTTRUE;
	}

	if (!bProcess) return;

	// Pick the lock by doing lock-pick damage to it...

	DamageStruct damage;

	damage.eType	= pAmmo->eInstDamageType;
	damage.fDamage  = GetRandom(m_fMinUnlockHitPts, m_fMaxUnlockHitPts);
	damage.vDir.Init(0, 1, 0);

	damage.hDamager = m_hObject;
	damage.DoDamage(this, m_hObject);


	// Play the lock pick sound...

    LTVector vPos;
    g_pLTServer->GetObjectPos(m_hObject, &vPos);

	if (m_hstrPickSnd)
	{
 
        char* pSound = g_pLTServer->GetStringData(m_hstrPickSnd);
		if (pSound)
		{
			g_pServerSoundMgr->PlaySoundFromPos(vPos, pSound, m_fSndRadius,
				SOUNDPRIORITY_MISC_MEDIUM);
		}
	}

	
	// Do fx for welding the lock...

	if (m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_WELDER)
	{
		WEAPON* pWeapon = g_pWeaponMgr->GetWeapon("Lighter");
		if (!pWeapon) return;

		SURFACE* pSurf = g_pSurfaceMgr->GetSurface("Metal");
		if (!pSurf) return;

		LTVector vHisPos;
		g_pLTServer->GetObjectPos(hSender, &vHisPos);
		LTVector vDir = vHisPos - vPos;
		vDir.Norm();

		CLIENTWEAPONFX fxStruct;
		fxStruct.hFiredFrom		= hSender;
		fxStruct.vSurfaceNormal	= vDir;
		fxStruct.vFirePos		= vHisPos;
		fxStruct.vPos			= vPos + vDir;
		fxStruct.hObj			= m_hObject;
		fxStruct.nWeaponId		= pWeapon->nId;
		fxStruct.nAmmoId		= pAmmo->nId;
		fxStruct.nSurfaceType	= pSurf->eType;

		// This should be a player object, get the client id...

		if (IsPlayer(hSender))
		{
			CPlayerObj* pPlayer = (CPlayerObj*) g_pLTServer->HandleToObject(hSender);
			if (pPlayer)
			{
				fxStruct.nShooterId = (uint8) g_pLTServer->GetClientID(pPlayer->GetClient());
			}
		}

		CreateClientWeaponFX(fxStruct);
	}
}
Exemplo n.º 9
0
// Wrap the textures, starting at a poly index
void CRVTrackerTextureWrap::WrapTexture(CTWPolyInfo *pPoly, const CVector &vWrapDir, CTextExtents &cExtents) const
{
	// Mark this poly as wrapped
	pPoly->m_bTouched = TRUE;

	CTexturedPlane& Texture = pPoly->m_pPoly->GetTexture(GetCurrTexture());

	// Get the texture space
	LTVector vWrapO = Texture.GetO();
	LTVector vWrapP = Texture.GetP();
	LTVector vWrapQ = Texture.GetQ();

	// Get the texture offset projections
	float fWrapOdotP = vWrapO.Dot(vWrapP);
	float fWrapOdotQ = vWrapO.Dot(vWrapQ);

	// Update the texturing extents
	for (uint32 nExtentLoop = 0; nExtentLoop < pPoly->m_aEdges.GetSize(); ++nExtentLoop)
	{
		LTVector vEdgePt = pPoly->m_aEdges[nExtentLoop]->m_aPt[0];

		float fCurU = vWrapP.Dot(vEdgePt) - fWrapOdotP;
		float fCurV = vWrapQ.Dot(vEdgePt) - fWrapOdotQ;

		cExtents.m_fMinU = LTMIN(fCurU, cExtents.m_fMinU);
		cExtents.m_fMaxU = LTMAX(fCurU, cExtents.m_fMaxU);
		cExtents.m_fMinV = LTMIN(fCurV, cExtents.m_fMinV);
		cExtents.m_fMaxV = LTMAX(fCurV, cExtents.m_fMaxV);
	}

	CMoArray<uint32> aNeighbors;
	CMoArray<float> aDots;

	// Insert the neighbors into a list in dot-product order
	for (uint32 nNeighborLoop = 0; nNeighborLoop < pPoly->m_aNeighbors.GetSize(); ++nNeighborLoop)
	{
		CTWPolyInfo *pNeighbor = pPoly->m_aNeighbors[nNeighborLoop];

		// Skip edges that don't have a neighbor
		if (!pNeighbor)
			continue;

		// Skip neighbors that are already wrapped
		if (pNeighbor->m_bTouched)
			continue;

		// Get our dot product
		float fCurDot = vWrapDir.Dot(pPoly->m_aEdges[nNeighborLoop]->m_Plane.m_Normal);

		if ((m_bRestrictWalkDir) && (fCurDot < 0.707f))
			continue;

		// Mark this neighbor as touched (to avoid later polygons pushing it onto the stack)
		pNeighbor->m_bTouched = TRUE;

		// Insert it into the list
		for (uint32 nInsertLoop = 0; nInsertLoop < aNeighbors.GetSize(); ++nInsertLoop)
		{
			if (fCurDot > aDots[nInsertLoop])
				break;
		}
		aDots.Insert(nInsertLoop, fCurDot);
		aNeighbors.Insert(nInsertLoop, nNeighborLoop);
	}

	// Recurse through its neighbors
	for (uint32 nWrapLoop = 0; nWrapLoop < aNeighbors.GetSize(); ++nWrapLoop)
	{
		CTWPolyInfo *pNeighbor = pPoly->m_aNeighbors[aNeighbors[nWrapLoop]];
		CTWEdgeInfo *pEdge = pPoly->m_aEdges[aNeighbors[nWrapLoop]];

		//////////////////////////////////////////////////////////////////////////////
		// Wrap this neighbor

		// Create a matrix representing the basis of the polygon in relation to this edge
		LTMatrix mPolyBasis;
		mPolyBasis.SetTranslation(0.0f, 0.0f, 0.0f);
		mPolyBasis.SetBasisVectors(&pEdge->m_vDir, &pPoly->m_pPoly->m_Plane.m_Normal, &pEdge->m_Plane.m_Normal);

		// Create a new basis for the neighbor polygon
		LTMatrix mNeighborBasis;
		LTVector vNeighborForward;
		vNeighborForward = pNeighbor->m_pPoly->m_Plane.m_Normal.Cross(pEdge->m_vDir);
		// Just to be sure..
		vNeighborForward.Norm();
		mNeighborBasis.SetTranslation(0.0f, 0.0f, 0.0f);
		mNeighborBasis.SetBasisVectors(&pEdge->m_vDir, &pNeighbor->m_pPoly->m_Plane.m_Normal, &vNeighborForward);

		// Create a rotation matrix from here to there
		LTMatrix mRotation;
		mRotation = mNeighborBasis * ~mPolyBasis;

		// Rotate the various vectors
		LTVector vNewP;
		LTVector vNewQ;
		LTVector vNewDir;

		mRotation.Apply3x3(vWrapP, vNewP);
		mRotation.Apply3x3(vWrapQ, vNewQ);
		mRotation.Apply3x3(vWrapDir, vNewDir);

		// Rotate the texture basis if we're following a path
		if (m_nWrapStyle == k_WrapPath)
		{
			LTVector vNeighborEdgeDir;
			if (GetSimilarEdgeDir(pNeighbor, vNewDir, vNeighborEdgeDir, 0.707f))
			{
				LTMatrix mRotatedNeighbor;
				LTVector vNeighborRight;
				vNeighborRight = vNeighborEdgeDir.Cross(pNeighbor->m_pPoly->m_Plane.m_Normal);
				vNeighborRight.Norm();
				// Make sure we're pointing the right way...
				if (vNeighborRight.Dot(pEdge->m_vDir) < 0.0f)
					vNeighborRight = -vNeighborRight;
				mRotatedNeighbor.SetTranslation(0.0f, 0.0f, 0.0f);
				mRotatedNeighbor.SetBasisVectors(&vNeighborRight, &pNeighbor->m_pPoly->m_Plane.m_Normal, &vNeighborEdgeDir);
				// Build a basis based on an edge from the current polygon 
				LTVector vBestPolyEdge;
				GetSimilarEdgeDir(pPoly, vWrapDir, vBestPolyEdge);
				LTVector vPolyRight = vBestPolyEdge.Cross(pNeighbor->m_pPoly->m_Plane.m_Normal);
				vPolyRight.Norm();
				// Make sure we're pointing the right way...
				if (vPolyRight.Dot(pEdge->m_vDir) < 0.0f)
					vPolyRight = -vPolyRight;
				// Build the poly edge matrix
				LTMatrix mPolyEdgeBasis;
				mPolyEdgeBasis.SetTranslation(0.0f, 0.0f, 0.0f);
				mPolyEdgeBasis.SetBasisVectors(&vPolyRight, &pNeighbor->m_pPoly->m_Plane.m_Normal, &vBestPolyEdge);

				// Get a matrix from here to there
				LTMatrix mRotator;
				mRotator = mRotatedNeighbor * ~mPolyEdgeBasis;
				// Rotate the texture basis
				mRotator.Apply3x3(vNewP);
				mRotator.Apply3x3(vNewQ);
				// And use the new edge as the new direction
				vNewDir = vNeighborEdgeDir;
			}

			// Remove skew from vNewP/vNewQ
			if ((float)fabs(vNewP.Dot(vNewQ)) > 0.001f)
			{
				float fMagP = vNewP.Mag();
				float fMagQ = vNewQ.Mag();
				vNewQ *= 1.0f / fMagQ;
				vNewP -= vNewQ * vNewQ.Dot(vNewP);
				vNewP.Norm(fMagP);
				vNewQ *= fMagQ;
			}
		}

		// Get the first edge point..
		CVector vEdgePt = pEdge->m_aPt[0];

		// Calculate the texture coordinate at this point
		float fWrapU = vWrapP.Dot(vEdgePt) - fWrapOdotP;
		float fWrapV = vWrapQ.Dot(vEdgePt) - fWrapOdotQ;

		// Build the new offset
		float fNewOdotP = vNewP.Dot(vEdgePt) - fWrapU;
		float fNewOdotQ = vNewQ.Dot(vEdgePt) - fWrapV;
		LTVector vNewO;
		vNewO.Init();
		float fNewPMag = vNewP.MagSqr();
		if (fNewPMag > 0.0f)
			vNewO += vNewP * (fNewOdotP / fNewPMag);
		float fNewQMag = vNewQ.MagSqr();
		if (fNewQMag > 0.0f)
			vNewO += vNewQ * (fNewOdotQ / fNewQMag);

		pNeighbor->m_pPoly->SetTextureSpace(GetCurrTexture(), vNewO, vNewP, vNewQ);

		// Recurse into this neighbor
		WrapTexture(pNeighbor, vNewDir, cExtents);
	}
}
Exemplo n.º 10
0
LTBOOL CAIVolumeMgr::FindDangerScatterPosition(CAIVolume* pVolume, const LTVector& vAIPos, const LTVector& vDangerPos, LTFLOAT fDangerDistanceSqr, LTVector* pvScatterPosition, LTBOOL bNeighbor /* = LTFALSE */)
{
	// Is there a Position in this volume that is sufficiently far from the position in question?

	LTVector avCorners[] = 
	{
		pVolume->GetBackBottomLeft(),
		pVolume->GetBackBottomRight(),
		pVolume->GetFrontBottomLeft(),
		pVolume->GetFrontBottomRight() 
	};

	LTBOOL abCornerValid[] =
	{
		LTFALSE,
		LTFALSE,
		LTFALSE,
		LTFALSE
	};

	LTFLOAT fRandomRadiusModifier = GetRandom(1.0f, 1.0f);

	// Find all valid corners

	{for ( uint iCorner = 0 ; iCorner < 4 ; iCorner++ )
	{
		if ( avCorners[iCorner].DistSqr(vDangerPos) > fDangerDistanceSqr*fRandomRadiusModifier )
		{
			abCornerValid[iCorner] = LTTRUE;
		}
	}}

	// Decide which, if any, of the valid corners, is best for us to use (ie, don't run through the danger radius to get there)

	LTFLOAT fMinimumDistanceSqr = (LTFLOAT)INT_MAX;
	uint32 iCornerBest = -1;

	{for ( uint iCorner = 0 ; iCorner < 4 ; iCorner++ )
	{
		if ( !abCornerValid[iCorner] ) continue;

		LTFLOAT fDistanceSqr = avCorners[iCorner].DistSqr(vAIPos);
		if ( fDistanceSqr < fMinimumDistanceSqr )
		{
			iCornerBest = iCorner;
			fMinimumDistanceSqr = fDistanceSqr;
		}
	}}

	if ( iCornerBest != -1 )
	{
		// Find opposite corner

		_ASSERT(iCornerBest >= 0 && iCornerBest <= 3);

		uint32 iCornerOpposite;

		switch ( iCornerBest )
		{
			case 0:
				iCornerOpposite = 3;
				break;

			case 1:
				iCornerOpposite = 2;
				break;

			case 2:
				iCornerOpposite = 1;
				break;

			case 3:
				iCornerOpposite = 0;
				break;
		}

		// Extend towards opposite corner slightly

		LTVector vOffset = avCorners[iCornerOpposite] - avCorners[iCornerBest];
		vOffset.Norm();
		vOffset *= 50.0f;

		*pvScatterPosition = avCorners[iCornerBest] + vOffset;

		return LTTRUE;
	}

	// No - so look into all the neighbors (only 1 deep!)

	if ( !bNeighbor )
	{
		for ( int32 iNeighbor = 0 ; iNeighbor < pVolume->GetNumNeighbors() ; iNeighbor++ )
		{
			int32 iVolume = pVolume->GetNeighborByIndex(iNeighbor)->GetIndex();

			if ( FindDangerScatterPosition(&m_aVolumes[iVolume], vAIPos, vDangerPos, fDangerDistanceSqr, pvScatterPosition, LTTRUE) )
			{
				return LTTRUE;
			}
		}
	}

	return LTFALSE;
}
Exemplo n.º 11
0
//*
// ----------------------------------------------------------------------- //
// Returns the vector that the physics would have the object move by.
// ----------------------------------------------------------------------- //
void CalcMotion
(
    MotionInfo* pInfo,
    LTObject*   pObj,           //the object
    LTVector&   dr,             //displacement
    LTVector&   v,              //velocity
    LTVector&   a,              //acceleration
    const bool  bApplyGravity,
    const float dt              //time step
)
{
	LTVector velocityDelta, accelDelta;
	LTVector q, slopeVel, slopeAccel, vel;
	const LTVector *n;
	LTVector objectNormal, vTemp, vTemp2;

	float fExp;
	float timeIntegral;
	float velocityMagSqr, accelMagSqr;
	LTBOOL bFriction;

	bFriction = LTFALSE;
	timeIntegral = dt * dt * 0.5f;	
	velocityMagSqr = v.MagSqr();
	accelMagSqr = a.MagSqr();

	// [KLS - 3/12/02] - Added support for per-object force override...

	LTVector vForce = pObj->GetGlobalForceOverride();
	
	// If the global force override is zero, use the MotionInfo force...

	if (LTVector(0.0, 0.0, 0.0) == vForce)
	{
		vForce = pInfo->m_Force;
	}

	/* 
	// Debug variables
	LTVector vOldAccel, vOldVel, vOldPos;
	vOldAccel = a;
	vOldVel = v;
	vOldPos = pObj->GetPos();
	//*/

	// Stop objects that are moving very slowly...
	if(velocityMagSqr < 0.1f )
	{
		v.Init();
		velocityMagSqr = 0;
	}

	if( accelMagSqr < 0.1f )
	{
		a.Init();
		accelMagSqr = 0;
	}

	// Zero out the displacement to start with.
	dr.Init();

	// Update objects affected by gravity...
	if(bApplyGravity)
	{
		// Add friction to objects standing on something...
		if(pObj->m_pStandingOn)
		{
			// Try to disable their physics.
			if( velocityMagSqr < 0.1f && accelMagSqr < 0.1f )
			{
				pObj->m_Velocity.Init();
				pObj->m_Acceleration.Init();
				pObj->m_InternalFlags &= ~IFLAG_APPLYPHYSICS;
				return;
			}
			else
			{
				// Check if object on world geometry...
				if( pObj->m_pNodeStandingOn )
				{
					// Calculate vector parallel to plane...
					n = &pObj->m_pNodeStandingOn->GetPlane()->m_Normal;
				}
				else
				{
					// Object standing on another object, so assume opposite to gravity...
					n = &objectNormal;
					objectNormal = -pInfo->m_UnitForce;
				}

				// Calculate the acceleration including the force
				LTVector vAccelWithForce = a + vForce;

				// If we're on a slope that's at enough of an angle, allow it to slide
				LTVector vForceDir = vForce;
				vForceDir.Norm();
				if (vForceDir.Dot(*n) > pInfo->m_SlideRatio)
				{
					float fAccelMag = vAccelWithForce.Mag();
					a = vAccelWithForce - *n * n->Dot(vAccelWithForce);

					// Don't allow it to accelerate up the slope..
					float fAccelDotForce = a.Dot(vForceDir);
					if (fAccelDotForce < 0.0f)
					{
						a -= vForceDir * fAccelDotForce;
					}
					
					a.Norm(fAccelMag);

					// dsi_ConsolePrint("Steep");
				}				
				else
				{
					// Figure out what our new velocity would be if only the force was used (i.e. are they jumping?)
					LTVector vNewVel = v + vForce * dt;
					// If we're going to be moving away from the plane, use the full force
					if (vNewVel.Dot(*n) > 0.01f)
					{
						a = vAccelWithForce;
						// dsi_ConsolePrint("Jump");
					}
					// If the acceleration without the force isn't moving into the surface, project it there
					else if (a.Dot(*n) > 0.01f)
					{
						float fAccelMag = a.Mag();
						a -= *n * (n->Dot(a) + 1.0f);
						a.Norm(fAccelMag);

						bFriction = LTTRUE;

						// dsi_ConsolePrint("Downhill");
					}
					else
					{
						bFriction = LTTRUE;

						// dsi_ConsolePrint("Walk");
					}
				}
			}
		}
		// Otherwise just apply gravity
		else
		{
			a += vForce;
			// dsi_ConsolePrint("Fall");
		}
	}
	// If there's no gravity and they aren't moving, then disable their physics
	else if( velocityMagSqr < 0.1f && accelMagSqr < 0.1f )
	{
		pObj->m_Velocity.Init();
		pObj->m_Acceleration.Init();
		pObj->m_InternalFlags &= ~IFLAG_APPLYPHYSICS;
		return;
	}

	// If friction
	// new velocity is given by:		v = ( a / k ) + ( v_0 - a / k ) * exp( -k * t )
	// new position is given by:		x = x_0 + ( a / k ) * t + ( k * v_0 - a ) * ( 1 - exp( -k * t )) / k^2
	if( bFriction && pObj->m_FrictionCoefficient > 0.0f )
	{
		// Velocity...
		fExp = ( float )exp( -pObj->m_FrictionCoefficient * dt );
		vTemp = a / pObj->m_FrictionCoefficient;
		vTemp2 = v - vTemp;
		vTemp2 *= fExp;
		vel = vTemp2 + vTemp;

		// Position delta...
		dr = vTemp * dt;
		vTemp = v * pObj->m_FrictionCoefficient;
		vTemp -= a;
		vTemp *= (( 1.0f - fExp ) / pObj->m_FrictionCoefficient / pObj->m_FrictionCoefficient);
		dr += vTemp;
		pObj->m_Velocity = vel;
		v = pObj->m_Velocity;
	}
	// If no friction
	// new velocity is given by:	v = v_0 + a * t
	// new position is given by:	x = x_0 + v_0 * t + .5 * a * t^2
	else
	{
		// Find the change in velocity...
		velocityDelta = a * dt;

		// Position delta...
		dr = v * dt;

		vTemp = a * (timeIntegral * 0.5f);
		dr += vTemp;

		// Add the final velocity to the new velocity.
		pObj->m_Velocity += velocityDelta;
		v = pObj->m_Velocity;
	}

	/*
	// Show debug information, filtering out the server-side player object
	if(bApplyGravity)
	{
		dsi_ConsolePrint("Old - A:<%7.1f,%7.1f,%7.1f> V:<%7.1f,%7.1f,%7.1f> P:<%7.1f,%7.1f,%7.1f>",
			VEC_EXPAND(vOldAccel), VEC_EXPAND(vOldVel), VEC_EXPAND(vOldPos));

		LTVector vNewAccel, vNewVel, vNewPos;
		vNewAccel = a;
		vNewVel = v;
		vNewPos = vOldPos + dr;

		dsi_ConsolePrint("New   - A:<%7.1f,%7.1f,%7.1f> V:<%7.1f,%7.1f,%7.1f> P:<%7.1f,%7.1f,%7.1f>",
			VEC_EXPAND(vNewAccel), VEC_EXPAND(vNewVel), VEC_EXPAND(vNewPos));
	}
	//*/

	return;
}
Exemplo n.º 12
0
void RenderPolyTrail(ILTClient *pClientDE, 
					 CLinkList<TRAIL_SECTION> *pList, 
					 HOBJECT hCamera, 
					 float fTrailWidth,
					 uint8 r,
					 uint8 g,
					 uint8 b,
					 uint8 a,
					 HTEXTURE hTexture,
					 uint32 dwExtraFlags)
{
	CLinkListNode<TRAIL_SECTION> *pNode = pList->GetHead();

	// Transform the path

	LTMatrix mCam = GetCamTransform(pClientDE, hCamera);

	while (pNode)
	{
		MatVMul(&pNode->m_Data.m_vTran, &mCam, &pNode->m_Data.m_vPos);	
		
		pNode = pNode->m_pNext;
	}

	// Do some precalculations

	pNode = pList->GetHead();

	float fCurU = 0.0f;
	
	while (pNode)
	{	
		LTVector vBisector;
		vBisector.z = 0.0f;

		// Compute the midpoint vectors

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

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

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

		vBisector.Norm(fTrailWidth);
		pNode->m_Data.m_vBisector = vBisector;

		pNode->m_Data.m_red   = r;
		pNode->m_Data.m_green = g;
		pNode->m_Data.m_blue  = b;
		pNode->m_Data.m_alpha = a;

		pNode = pNode->m_pNext;
	}

	pNode = pList->GetHead();

	if (pList->GetSize() < 2) return;

	pNode = pList->GetHead();

	ILTDrawPrim *pDrawPrimLT;
	pDrawPrimLT = pClientDE->GetDrawPrim();

	pDrawPrimLT->SetTexture(hTexture);
	pDrawPrimLT->SetTransformType(DRAWPRIM_TRANSFORM_CAMERA);
	pDrawPrimLT->BeginDrawPrim();


	if (g_bAppFocus)
	{
		uint32 nTris = 0;
		uint32 nVerts = 0;

		LT_POLYGT3 *pTri = g_pTris;
		LTVector *pVerts = g_pVerts;

		while (pNode->m_pNext)
		{
			LTVector vStart = pNode->m_Data.m_vTran;
			LTVector vEnd   = pNode->m_pNext->m_Data.m_vTran;
		
			LTVector vBisector1 = pNode->m_Data.m_vBisector;
			LTVector vBisector2 = pNode->m_pNext->m_Data.m_vBisector;

			*pVerts ++ = vStart + vBisector1;
			*pVerts ++ = vEnd + vBisector2;
			*pVerts ++ = vEnd - vBisector2;
			*pVerts ++ = vStart - vBisector1;

			uint8 r1 = pNode->m_Data.m_red;
			uint8 g1 = pNode->m_Data.m_green;
			uint8 b1 = pNode->m_Data.m_blue;
			uint8 a1 = pNode->m_Data.m_alpha;
			float u1 = pNode->m_Data.m_uVal;

			uint8 r2 = pNode->m_pNext->m_Data.m_red;
			uint8 g2 = pNode->m_pNext->m_Data.m_green;
			uint8 b2 = pNode->m_pNext->m_Data.m_blue;
			uint8 a2 = pNode->m_pNext->m_Data.m_alpha;
			float u2 = pNode->m_pNext->m_Data.m_uVal;
			
			SetupVert(pTri, 0, g_pVerts[nVerts].x, g_pVerts[nVerts].y, g_pVerts[nVerts].z, r1, g1, b1, a1, u1, 0.0f);
			SetupVert(pTri, 1, g_pVerts[nVerts + 1].x, g_pVerts[nVerts + 1].y, g_pVerts[nVerts + 1].z, r2, g2, b2, a2, u2, 1.0f);
			SetupVert(pTri, 2, g_pVerts[nVerts + 2].x, g_pVerts[nVerts + 2].y, g_pVerts[nVerts + 2].z, r2, g2, b2, a2, u2, 1.0f);

			pTri ++;
			nTris ++;

			SetupVert(pTri, 0, g_pVerts[nVerts].x, g_pVerts[nVerts].y, g_pVerts[nVerts].z, r1, g1, b1, a1, u1, 0.0f);
			SetupVert(pTri, 1, g_pVerts[nVerts + 2].x, g_pVerts[nVerts + 2].y, g_pVerts[nVerts + 2].z, r2, g2, b2, a2, u2, 1.0f);
			SetupVert(pTri, 2, g_pVerts[nVerts + 3].x, g_pVerts[nVerts + 3].y, g_pVerts[nVerts + 3].z, r1, g1, b1, a1, u1, 0.0f);

			pTri ++;
			nTris ++;

			nVerts += 4;

			pNode = pNode->m_pNext;

			//see if we need to flush our buffer
			if(nTris >= MAX_BUFFER_TRIS - 2)
			{
				pDrawPrimLT->DrawPrim(g_pTris, nTris);
				nTris = 0;
			}
		}

		// Draw the polylist
		if(nTris > 0)
		{
			pDrawPrimLT->DrawPrim(g_pTris, nTris);
			nTris = 0;
		}
	}

	pDrawPrimLT->BeginDrawPrim();
}
Exemplo n.º 13
0
bool CLTBBouncyChunkFX::Init(ILTClient *pClientDE, FX_BASEDATA *pBaseData, const CBaseFXProps *pProps)
{
	// Perform base class initialisation

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

	LTVector vChunkDir = GetProps()->m_vChunkDir;
	if (pBaseData->m_bUseTargetData)
	{
		vChunkDir = pBaseData->m_vTargetNorm;
	}

	LTVector vPos;
	LTRotation rRot;
	if (m_hParent)
	{
		m_pLTClient->GetObjectPos(m_hParent, &vPos);
		m_pLTClient->GetObjectRotation(m_hParent, &rRot);
	}	
	else
	{
		vPos = m_vCreatePos;
		rRot = m_rCreateRot;
	}

	float scale;
	CalcScale(m_tmElapsed, GetProps()->m_tmLifespan, &scale);

	LTVector vScale(scale, scale, scale);

	ObjectCreateStruct ocs;
	INIT_OBJECTCREATESTRUCT(ocs);

	ocs.m_ObjectType		= OT_MODEL;
	ocs.m_Flags				= FLAG_NOLIGHT | FLAG_VISIBLE;
	ocs.m_Pos				= vPos + GetProps()->m_vOffset;
	ocs.m_Rotation			= rRot;
	ocs.m_Scale				= vScale;
	strcpy(ocs.m_Filename, GetProps()->m_sModelName);
	strcpy(ocs.m_SkinName, GetProps()->m_sSkinName);

	m_hBouncyChunk = m_pLTClient->CreateObject(&ocs);

	// Setup an initial vector for the velocity

	LTVector vOther;
	vOther.x = 1.0f;
	vOther.y = 0.0f;
	vOther.z = 1.0f;
	vOther.Norm();

	LTVector vRight = vChunkDir.Cross(vOther);
	LTVector vUp    = vRight.Cross(vOther);

	m_vVel = vRight * (-GetProps()->m_fChunkSpread + (float)(rand() % (int)(GetProps()->m_fChunkSpread * 2.0f)));
	m_vVel += vUp * (-GetProps()->m_fChunkSpread + (float)(rand() % (int)(GetProps()->m_fChunkSpread * 2.0f)));
	m_vVel += vChunkDir * GetProps()->m_fChunkSpeed;
	m_vVel.Norm(GetProps()->m_fChunkSpeed);

	// Create the base object

	CreateDummyObject();
		
	// Success !!

	return true;
}
void CAIVolumeNeighbor::Init(CAIVolume* pThis, CAIVolume* pNeighbor)
{
	m_iVolume = pNeighbor->GetIndex();

	// Compute the 2d intersection of the two volumes, and compute important
	// things about the geometry of the connection

    LTVector vFrontLeft(0,0,0);
    LTVector vFrontRight(0,0,0);
    LTVector vBackLeft(0,0,0);
    LTVector vBackRight(0,0,0);

	vFrontLeft.x = Max<LTFLOAT>(pThis->GetFrontTopLeft().x, pNeighbor->GetFrontTopLeft().x);
	vFrontLeft.z = Min<LTFLOAT>(pThis->GetFrontTopLeft().z, pNeighbor->GetFrontTopLeft().z);

	vFrontRight.x = Min<LTFLOAT>(pThis->GetFrontTopRight().x, pNeighbor->GetFrontTopRight().x);
	vFrontRight.z = Min<LTFLOAT>(pThis->GetFrontTopRight().z, pNeighbor->GetFrontTopRight().z);

	vBackLeft.x = Max<LTFLOAT>(pThis->GetBackTopLeft().x, pNeighbor->GetBackTopLeft().x);
	vBackLeft.z = Max<LTFLOAT>(pThis->GetBackTopLeft().z, pNeighbor->GetBackTopLeft().z);

	vBackRight.x = Min<LTFLOAT>(pThis->GetBackTopRight().x, pNeighbor->GetBackTopRight().x);
	vBackRight.z = Max<LTFLOAT>(pThis->GetBackTopRight().z, pNeighbor->GetBackTopRight().z);

	// We know connection position (the center of the intersection) easily.

	m_vConnectionPos = (vFrontLeft+vFrontRight+vBackLeft+vBackRight)/4.0f;

	// We need y for vertical movement

#define _A_b pThis->GetFrontBottomRight().y
#define _A_t pThis->GetFrontTopRight().y
#define _B_b pNeighbor->GetFrontBottomRight().y
#define _B_t pNeighbor->GetFrontTopRight().y

	if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b >= _B_t) && (_A_b >= _B_b) )
	{
		m_vConnectionPos.y = _A_b; // or _B_t
	}
	else if ( (_A_t <= _B_t) && (_A_t <= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) )
	{
		m_vConnectionPos.y = _A_t; // or _B_b
	}
	else if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b >= _B_b) )
	{
		m_vConnectionPos.y = (_A_b + _B_t)/2.0f;
	}
	else if ( (_A_t <= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) )
	{
		m_vConnectionPos.y = (_A_t + _B_b)/2.0f;
	}
	else if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) )
	{
		m_vConnectionPos.y = (_B_b + _B_t)/2.0f;
	}
	else if ( (_A_t <= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b >= _B_b) )
	{
		m_vConnectionPos.y = (_A_b + _A_t)/2.0f;
	}
	else
	{
		m_vConnectionPos.y = -float(INT_MAX);
        DANGER(g_pLTServer, blong);
	}

	// Find the endpoints of the line across the connection, and the vector perpendicular to this

	if ( pThis->Inside(pNeighbor->GetFrontTopLeft()) || pThis->Inside(pNeighbor->GetBackTopRight()) ||
		 pThis->Inside(pNeighbor->GetFrontBottomLeft()) || pThis->Inside(pNeighbor->GetBackBottomRight()) )
	{
        m_avConnectionEndpoints[0] = vFrontRight + LTVector(0, m_vConnectionPos.y, 0);
        m_avConnectionEndpoints[1] = vBackLeft + LTVector(0, m_vConnectionPos.y, 0);
		m_vConnectionPerpDir = vFrontRight - vBackLeft;
		m_vConnectionDir = m_avConnectionEndpoints[1] - m_avConnectionEndpoints[0];
		m_vConnectionDir.y = 0.0f;
		m_fConnectionLength = VEC_MAG(m_vConnectionDir);
		m_vConnectionDir.Norm();
	}
	else
	{
        m_avConnectionEndpoints[0] = vFrontLeft + LTVector(0, m_vConnectionPos.y, 0);
        m_avConnectionEndpoints[1] = vBackRight + LTVector(0, m_vConnectionPos.y, 0);
		m_vConnectionPerpDir = vFrontLeft - vBackRight;
		m_vConnectionDir = m_avConnectionEndpoints[1] - m_avConnectionEndpoints[0];
		m_vConnectionDir.y = 0.0f;
		m_fConnectionLength = VEC_MAG(m_vConnectionDir);
		m_vConnectionDir.Norm();
	}

	LTFLOAT fTemp = m_vConnectionPerpDir[0];
	m_vConnectionPerpDir[0] = m_vConnectionPerpDir[2];
	m_vConnectionPerpDir[2] = fTemp;
	m_vConnectionPerpDir.Norm();

	// Make sure it points into this volume

    LTVector vThisCenter = (pThis->GetFrontTopLeft()+pThis->GetBackTopRight())/2.0f;
    LTVector vThisCenterDir = vThisCenter - m_vConnectionPos;
	vThisCenterDir.y = 0;
	vThisCenterDir.Norm();

	if ( vThisCenterDir.Dot(m_vConnectionPerpDir) < 0.0f )
	{
		m_vConnectionPerpDir = -m_vConnectionPerpDir;
	}

//  g_pLTServer->CPrint("cxn @ %f,%f,%f in %f,%f,%f : %f,%f,%f",
//		EXPANDVEC(m_vConnectionPos), EXPANDVEC(vThisCenter), EXPANDVEC(m_vConnectionPerpDir));
}
Exemplo n.º 15
0
void CAIHelicopterStrategyShoot::UpdateFiring(CWeapon* pWeapon, BURSTSTRUCT* pBurst)
{
	// Get our fire position

	LTVector vFirePos = GetAI()->GetAttachmentPosition(pWeapon->GetModelObject());
    LTRotation rFireRot = GetAI()->GetAttachmentRotation(pWeapon->GetModelObject());
	LTVector vFireRight, vFireUp, vFireForward;
	g_pMathLT->GetRotationVectors(rFireRot, vFireUp, vFireRight, vFireForward);

	// Get target's position

	LTVector vTargetPos;
    g_pLTServer->GetObjectPos(m_hTarget, &vTargetPos);

	// Get our firing vector

	LTVector vFireDir = vTargetPos - vFirePos;
	vFireDir.Norm();

	// Make sure it's in our field of firce

	LTFLOAT fDp = vFireDir.Dot(vFireForward);
//    g_pLTServer->CPrint("fireangle = %f", (acos(fDp)/MATH_PI)*180.0f);
	if ( fDp <= c_fFOV90 )
	{
		Aim(pWeapon, pBurst);
		return;
	}

	// Now fire the weapon

	WFireInfo fireInfo;
	fireInfo.hFiredFrom = GetAI()->GetObject();
	fireInfo.vPath		= vFireDir;
	fireInfo.vFirePos	= vFirePos;
	fireInfo.vFlashPos	= vFirePos;
	fireInfo.hTestObj	= m_hTarget;
	fireInfo.fPerturbR	= 4.0f*(1.0f - GetAI()->GetAccuracy());
	fireInfo.fPerturbU	= 4.0f*(1.0f - GetAI()->GetAccuracy());

    pWeapon->UpdateWeapon(fireInfo, LTTRUE);

	// Decrement our burst counter and update the last ammo count

	pBurst->m_nBurstShots -= Max<int>(0, pBurst->m_nLastAmmoInClip - pWeapon->GetAmmoInClip());
	pBurst->m_nLastAmmoInClip = pWeapon->GetAmmoInClip();

	if ( pBurst->m_nBurstShots <= 0 )
	{
		// We just finished our burst. Start waiting.

		CalculateBurst(pWeapon, pBurst);

		// And just aim.

		Aim(pWeapon, pBurst);
	}
	else
	{
		// Keep firing

		Fire(pWeapon, pBurst);
	}
}
Exemplo n.º 16
0
LTBOOL CAIMovementHelicopter::Update()
{
    LTFLOAT fTimeDelta = g_pLTServer->GetFrameTime();

	switch ( m_eState )
	{
		case eStateUnset:
		{

		}
		break;

		case eStateSet:
		{
			// Find our unit movement vector

			LTVector vMove = m_vDest - GetAI()->GetPosition();
//			vMove.y = 0.0f;

			// See if we'll overshoot our

			LTFLOAT fRemainingDist = vMove.Mag();
			LTFLOAT fMoveDist;

			fMoveDist = GetAI()->GetSpeed()*fTimeDelta;

			vMove.Norm();

			LTBOOL bCrossed = LTFALSE;

			// See if we crossed the dest plane

			if ( (vMove.Dot(m_vDestDir) < 0.0f) )
			{
				bCrossed = LTTRUE;
			}

			// If we'd overshoot our destination, just move us there

			if ( (fRemainingDist < fMoveDist) || bCrossed )
			{
				fMoveDist = fRemainingDist;
				m_eState = eStateDone;
			}

			// Scale based on our movement distance

			vMove *= fMoveDist;

			// Calculate our new position

			LTVector vNewPos = GetAI()->GetPosition() + vMove;

			// Move us - this is an expensive call

//			GetAI()->Move(vNewPos);

			// Face us in the right direction

			GetAI()->FacePos(vNewPos);
		}
		break;

		case eStateDone:
		{
		}
		break;
	}

	return LTTRUE;
}
Exemplo n.º 17
0
LTBOOL CAIMovementHuman::Update()
{
    LTFLOAT fTimeDelta = g_pLTServer->GetFrameTime();

	switch ( m_eState )
	{
		case eStateUnset:
		{

		}
		break;

		case eStateSet:
		{
			// Set our speed based on our movement type

			if ( GetAI()->GetAnimationContext()->IsPropSet(aniWalk) )
			{
				GetAI()->Walk();
			}
			else if ( GetAI()->GetAnimationContext()->IsPropSet(aniRun) )
			{
				GetAI()->Run();
			}
			else if ( GetAI()->GetAnimationContext()->IsPropSet(aniSwim) )
			{
				GetAI()->Swim();
			}
			else
			{
				// We're not moving yet...

				GetAI()->Stop();
			}

			// Find our unit movement vector

			LTVector vMove = m_vDest - GetAI()->GetPosition();

			if ( !m_bUnderwater )
			{
				vMove.y = 0.0f;
			}

			// See if we'll overshoot our

			LTFLOAT fRemainingDist = vMove.Mag();
			LTFLOAT fMoveDist;

			fMoveDist = GetAI()->GetSpeed()*fTimeDelta;

			// If we'd overshoot our destination, just move us there

			if ( fRemainingDist < fMoveDist )
			{
				fMoveDist = fRemainingDist;
				m_eState = eStateDone;
			}

			// Scale based on our movement distance

			vMove.Norm();
			vMove *= fMoveDist;

			// Calculate our new position

			LTVector vNewPos = GetAI()->GetPosition() + vMove;

			// Move us - this is an expensive call

			GetAI()->Move(vNewPos);

			// Face us in the right direction

			GetAI()->FacePos(vNewPos);
		}
		break;

		case eStateDone:
		{

		}
		break;
	}

	return LTTRUE;
}
Exemplo n.º 18
0
void CNodeController::HandleNodeControlRecoilMessage(HMESSAGEREAD hMessage)
{
	if ( m_cRecoils >= MAX_RECOILS )
		return;

	m_fRecoilTimers[m_cRecoils++] = 0.50f;


	ModelNode eModelNode;
    eModelNode = (ModelNode)g_pLTClient->ReadFromMessageByte(hMessage);

    LTVector vRecoilDir;
    g_pLTClient->ReadFromMessageCompVector(hMessage, &vRecoilDir);

	// Get the magnitude of the recoil vector

    LTFLOAT fRecoilMag = VEC_MAGSQR(vRecoilDir);

	// Get the unit impact/recoil vector

	vRecoilDir /= (float)sqrt(fRecoilMag);

	// Cap it if necessary

	if ( fRecoilMag > 100.0f )
	{
		fRecoilMag = 100.0f;
	}

	// Get the position of the impact

	NSTRUCT* pNode = &m_aNodes[eModelNode];
    ILTModel* pModelLT = g_pLTClient->GetModelLT();
	LTransform transform;
    pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), pNode->hModelNode, transform, LTTRUE);

	// Decompose the transform into the position and rotation

    LTVector vPos;
    ILTTransform* pTransformLT = g_pLTClient->GetTransformLT();
	pTransformLT->GetPos(transform, vPos);

    LTVector vRecoilPos = vPos;

	// Add angular rotations up the recoil parent chain

	ModelNode eModelNodeCurrent = g_pModelButeMgr->GetSkeletonNodeRecoilParent(GetCFX()->GetModelSkeleton(), eModelNode);

	while ( eModelNodeCurrent != eModelNodeInvalid )
	{
		// Get the rotation of the node

		NSTRUCT* pNode = &m_aNodes[eModelNodeCurrent];

		LTransform transform;
        ILTModel* pModelLT = g_pLTClient->GetModelLT();

		// Get the transform of the node we're controlling

        pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), pNode->hModelNode, transform, LTTRUE);

        ILTTransform* pTransformLT = g_pLTClient->GetTransformLT();

		// Decompose the transform into the position and rotation

        LTVector vPos;
        LTRotation rRot;
		pTransformLT->Get(transform, vPos, rRot);

		// Get the rotation vectors of the transform

        LTVector vRight, vUp, vForward;
        g_pLTClient->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

		// Cross the right vector with the impact vector to get swing

        LTVector vRotationAxis = vRight.Cross(vRecoilDir);
		vRotationAxis.Norm();

		// Add the timed rotation control for the swing

		// !!! HACK
		// !!! Do not add swing if this is a leg node

		if ( !strstr(g_pModelButeMgr->GetSkeletonNodeName(GetCFX()->GetModelSkeleton(), eModelNodeCurrent), "leg") )
		AddNodeControlRotationTimed(eModelNodeCurrent, vRotationAxis, MATH_PI/1000.0f*fRecoilMag, 0.50f);

		// Use the right vector to get twist, but make sure the sign is correct based on location
		// of impact and whether we're getting shot at from behind/front etc

		vRotationAxis = vRight;
		vRotationAxis.Norm();

		// Get the twist

        LTVector vSideDir = vRecoilPos-vPos;
		vSideDir.Norm();

        LTFLOAT fSign = vUp.Dot(vRecoilDir);
		fSign *= vForward.Dot(vSideDir);

		if ( fSign > 0.0f )
		{
			vRotationAxis = -vRotationAxis;
		}

		// Add the timed rotation control for the twist

	//	AddNodeControlRotationTimed(eModelNodeCurrent, vRotationAxis, MATH_PI/1000.0f*fRecoilMag, 0.50f);

		// Decrease the magnitude

		fRecoilMag /= 2.0f;

		eModelNodeCurrent = g_pModelButeMgr->GetSkeletonNodeRecoilParent(GetCFX()->GetModelSkeleton(), eModelNodeCurrent);
	}
}
Exemplo n.º 19
0
void CAIBrain::GetDodgeStatus(DodgeStatus* peDodgeStatus, Direction* peDirection, DodgeAction* peDodgeAction, uint32* pdwNode)
{
	if ( !GetAI()->HasTarget() || !GetAI()->HasLastVolume() ) 
	{
		*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusOk;
		return;
	}

	if ( g_pLTServer->GetTime() >= m_fDodgeStatusCheckTimeVector )
	{
		m_fDodgeStatusCheckTimeVector = g_pLTServer->GetTime() + LOWER_BY_DIFFICULTY(m_pBrain->fDodgeVectorCheckTime);

		if ( GetRandom(0.0f, 1.0f) <= RAISE_BY_DIFFICULTY(m_pBrain->fDodgeVectorCheckChance) )
		{
			if ( GetAI()->GetTarget()->IsVisiblePartially() )
			{
				CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(GetAI()->GetTarget()->GetObject());
				if ( pCharacter->HasDangerousWeapon() )
				{
					LTRotation rRot;
					LTVector vNull, vForward;
					g_pLTServer->GetObjectRotation(GetAI()->GetTarget()->GetObject(), &rRot);
					g_pMathLT->GetRotationVectors(rRot, vNull, vNull, vForward);

					LTVector vDir;
					vDir = GetAI()->GetPosition() - GetAI()->GetTarget()->GetPosition();
					vDir.y = 0;
					vDir.Norm();

					// TODO: bute this

					const static LTFLOAT fThreshhold = 0.95f;

					if ( (vDir.Dot(vForward) > fThreshhold) && (GetAI()->GetForwardVector().Dot(vForward) < -fThreshhold) )
					{
						LTFLOAT fCheckDistance;

						LTFLOAT fRandom = GetRandom(0.0f, 1.0f);

						if ( fRandom > m_pBrain->fDodgeVectorCoverChance )
						{
							if ( fRandom > (m_pBrain->fDodgeVectorCoverChance + m_pBrain->fDodgeVectorRollChance) )
							{
								*peDodgeAction = eDodgeActionShuffle;
								fCheckDistance = 109.0f;
							}
							else
							{
								*peDodgeAction = eDodgeActionRoll;
								fCheckDistance = 140.0f;
							}

							// MAKE SURE WE WON'T DODGE OUT OF THE VOLUME 
							if ( GetAI()->GetLastVolume()->Inside2d(GetAI()->GetPosition()+GetAI()->GetRightVector()*fCheckDistance, GetAI()->GetRadius()) )
							{
								*peDirection = eDirectionRight;
								*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusVector;
								return;
							}
							else if ( GetAI()->GetLastVolume()->Inside2d(GetAI()->GetPosition()-GetAI()->GetRightVector()*fCheckDistance, GetAI()->GetRadius()) )
							{
								*peDirection = eDirectionLeft;
								*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusVector;
								return;
							}
							else
							{
								*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusOk;
								return;
							}
						}
						else
						{
							CAINode* pNode = g_pAINodeMgr->FindNearestCoverFromThreat(GetAI()->GetPosition(), GetAI()->GetTarget()->GetObject());

							if ( pNode )
							{
								*peDodgeAction = eDodgeActionCover;
								*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusVector;
								*pdwNode = pNode->GetID();
							}
							else
							{
								*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusOk;
							}
							return;
						}
					}
				}
			}
		}
	}

	if ( g_pLTServer->GetTime() >= m_fDodgeStatusCheckTimeProjectile )
	{
		m_fDodgeStatusCheckTimeProjectile = g_pLTServer->GetTime() + RAISE_BY_DIFFICULTY(m_pBrain->fDodgeProjectileCheckTime);

		if ( GetRandom(0.0f, 1.0f) <= RAISE_BY_DIFFICULTY(m_pBrain->fDodgeProjectileCheckChance) )
		{
			CGrenade* pGrenade;
			if ( FindGrenadeDangerPosition(GetAI()->GetPosition(), 40000.0f, &m_vDodgeProjectilePosition, &pGrenade) )
			{
				FREE_HSTRING(m_hstrDodgeProjectileName);
				// $STRING
				m_hstrDodgeProjectileName = g_pLTServer->CreateString(g_pLTServer->GetObjectName(pGrenade->m_hObject));

				*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusProjectile;
				*peDodgeAction = eDodgeActionFlee;

				return;
			}
		}
	}

	*peDodgeStatus = m_eDodgeStatusLast = eDodgeStatusOk;
	return;
}
Exemplo n.º 20
0
bool CLTBBouncyChunkFX::Update(float tmFrameTime)
{
	// Base class update first
	
	if (!CBaseFX::Update(tmFrameTime)) 
		return false;

	if ((m_hImpactSound) && (m_pLTClient->IsDone(m_hImpactSound)))
	{
		m_pLTClient->SoundMgr()->KillSound(m_hImpactSound);
		m_hImpactSound = NULL;
	}

	// Set the object scale

	LTVector vScale(m_scale, m_scale, m_scale);

	m_pLTClient->SetObjectScale(m_hBouncyChunk, &vScale);

	LTVector vCur;
	m_pLTClient->GetObjectPos(m_hBouncyChunk, &vCur);
		
	// Compute the new position of the chunk

	LTVector vNew = vCur;
	vNew += m_vVel * tmFrameTime;
	
	m_vVel += GetProps()->m_vGravity * tmFrameTime;
	
	// Move the object and collide against the world

	ClientIntersectQuery ciq;
	ClientIntersectInfo  cii;

	ciq.m_From  = vCur;
	ciq.m_To    = vNew;

	if (m_pLTClient->IntersectSegment(&ciq, &cii))
	{
		vNew = cii.m_Point + cii.m_Plane.m_Normal;
		vCur = vNew;

		// Compute the reflected velocity

		LTVector N = cii.m_Plane.m_Normal;
		LTVector L = m_vVel;
		L.x = -L.x;
		L.y = -L.y;
		L.z = -L.z;
		
		LTVector vReflected = N * 2.0f;
		vReflected *= (N.Dot(L));
		vReflected -= L;

		vReflected.Norm();
		vReflected *= (m_vVel.Mag() * 0.7f);

		m_vVel = vReflected;

		const char *sImpactSound = GetProps()->m_sImpactSound;
		if (sImpactSound[0] != '.')
		{
			// Play the bounce sound

			PlaySoundInfo psi;
			memset(&psi, 0, sizeof(PlaySoundInfo));

			psi.m_dwFlags = PLAYSOUND_GETHANDLE |
							PLAYSOUND_CTRL_VOL |
							PLAYSOUND_CLIENT |
							PLAYSOUND_TIME |
							PLAYSOUND_3D | 
							PLAYSOUND_REVERB;

			psi.m_nVolume = 50;

			strcpy(psi.m_szSoundName, GetProps()->m_sImpactSound);
			psi.m_nPriority		= 0;
			psi.m_vPosition		= m_vPos;
			psi.m_fInnerRadius	= 100;
			psi.m_fOuterRadius	= 300;

			if (!m_hImpactSound)
			{
				if (m_pLTClient->SoundMgr()->PlaySound(&psi, m_hImpactSound) == LT_OK)
				{
					m_hImpactSound = psi.m_hSound;
				}
			}
		}
	}

	m_pLTClient->SetObjectPos(m_hBouncyChunk, &vNew);
	m_pLTClient->SetObjectColor(m_hBouncyChunk, m_red, m_green, m_blue, m_alpha);
	m_pLTClient->SetObjectPos(m_hObject, &vNew);

	// Success !!

	return true;
}
void CNudge::Update(LTBOOL bMoving)
{
	m_eState = eStateNoNudge;

	// If we're moving or high priority, then we don't need to worry about nudging
	if ( bMoving || (m_ePriority == ePriorityHigh) )
	{
		return;
	}

	LTVector vPos = m_pAI->GetPosition();
	LTFLOAT fRadius = m_pAI->GetRadius();
/*
	// If we're not inside our volume, don't nudge
	if ( !m_pAI->GetLastVolume() || !m_pAI->GetLastVolume()->Inside2d(vPos, fRadius) )
	{
		return;
	}
*/
	HOBJECT hPlayer = LTNULL;
	CAIHuman* apAIs[64];
	uint32 cAIs = 0;

    static HCLASS hClass = g_pLTServer->GetClass("CAIHuman");

    ObjectList* pObjectList = g_pLTServer->FindObjectsTouchingSphere(&vPos, fRadius);
	ObjectLink* pObject = pObjectList ? pObjectList->m_pFirstLink : LTNULL;

	while ( pObject && cAIs < 64 )
	{
		HOBJECT hObject = pObject->m_hObject;
		if ( hObject != m_pAI->m_hObject )
		{
			if ( IsPlayer(hObject) )
			{
				hPlayer = hObject;
			}
            else if ( g_pLTServer->IsKindOf(g_pLTServer->GetObjectClass(hObject), hClass) )
			{
                apAIs[cAIs++] = (CAIHuman*)g_pLTServer->HandleToObject(hObject);
			}
		}

		pObject = pObject->m_pNext;
	}

	if ( pObjectList )
	{
		g_pLTServer->RelinquishList(pObjectList);
	}

	if ( cAIs == 0 ) return;

	m_eState = eStateNudge;
	m_vNudge = LTVector(0,0,0);

	if ( hPlayer )
	{
		LTVector vPlayerPosition;
		g_pLTServer->GetObjectPos(hPlayer, &vPlayerPosition);

		LTVector vNudgeDir = m_pAI->GetPosition()-vPlayerPosition;
		vNudgeDir.y = 0.0f;
		vNudgeDir.Norm();
		m_vNudge += vNudgeDir*64.0f*g_pLTServer->GetFrameTime();
	}

	for ( uint32 iAI = 0 ; iAI < cAIs ; iAI++ )
	{
		CAIHuman* pAI = apAIs[iAI];
		CNudge* pNudge = pAI->GetNudge();

		LTVector vNudgeDir;
		LTFLOAT fNudgeAmount;

		if ( pNudge->GetPriority() == ePriorityLow )
		{
			fNudgeAmount = 24.0f;
			vNudgeDir = m_pAI->GetPosition()-pAI->GetPosition();
			vNudgeDir.y = 0.0f;
			vNudgeDir.Norm();
		}
		else // if ( pNudge->GetPriority() == ePriorityHigh )
		{
			fNudgeAmount = 48.0f;
			vNudgeDir = m_pAI->GetPosition()-pAI->GetPosition();
			vNudgeDir.y = 0.0f;
			vNudgeDir.Norm();
		}

        m_vNudge += vNudgeDir*fNudgeAmount*g_pLTServer->GetFrameTime();
	}

	_ASSERT((LTFLOAT)fabs(m_vNudge.y < MATH_EPSILON));
}