示例#1
0
DBOOL Prophet::Fire(DBOOL bAltFire)
{
    DBOOL bFire = DFALSE;
    CWeapon* pW = m_InventoryMgr.GetCurrentWeapon();

    if(pW == DNULL)
    {
        SetNewState(STATE_Idle);
        return DFALSE;
    }

    DVector vTargetVel, vVel;
    m_pServerDE->GetVelocity(m_hTarget, &vTargetVel);
    m_pServerDE->GetVelocity(m_hObject, &vVel);

    DFLOAT fTargetVel = VEC_MAG(vTargetVel);
    DFLOAT fVel = VEC_MAG(vVel);

    if(fTargetVel <= 5.0f && fVel <= 5.0f && pW->GetType() != WEAP_ASSAULTRIFLE
            && pW->GetType() != WEAP_NAPALMCANNON && pW->GetType() != WEAP_SNIPERRIFLE)
    {
        if(m_InventoryMgr.GetAmmoCount(pW->GetAmmoType(DFALSE)) >= pW->GetAltAmmoUse())
            bFire = DTRUE;
    }

//	DDWORD m_nFiredWeapon = m_InventoryMgr.FireCurrentWeapon(&m_MoveObj.GetPos(), &m_MoveObj.GetRotation(), bFire);

    return AI_Mgr::Fire(bFire);
}
示例#2
0
void CDeathFX::CreateVehicleDeathFX()
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	GIBCREATESTRUCT gib;

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

    LTFLOAT fDamage = VEC_MAG(m_vDir);

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

	SetupGibTypes(gib);

	psfxMgr->CreateSFX(SFX_GIB_ID, &gib);
}
示例#3
0
DBOOL CSmokeTrailFX::Update()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr || !m_pClientDE || !m_hServerObject) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	// Check to see if we should go away...

	if (m_bWantRemove)
	{
		return DFALSE;
	}


	// See if it is time to create a new trail segment...
	if ((m_fStartTime < 0) || (fTime > m_fStartTime + m_fSegmentTime))
	{
		STSCREATESTRUCT sts;

		sts.hServerObj = m_hServerObject;
		VEC_COPY(sts.vVel, m_vVel);
		VEC_COPY(sts.vColor1, m_vColor1);
		VEC_COPY(sts.vColor2, m_vColor2);
		sts.bSmall			= m_bSmall;
		sts.fLifeTime		= m_fLifeTime;
		sts.fFadeTime		= m_fFadeTime;
		sts.fOffsetTime		= m_fOffsetTime;
		sts.fRadius			= 1000.0f;
		sts.fGravity		= 15.0f;
		sts.nNumPerPuff		= m_nNumPerPuff;

		if(VEC_MAG(sts.vVel) < 1.0f)
		{
			sts.fGravity = 25.0f;
			sts.fOffsetTime = 0.1f;
			sts.fRadius = 500.0f;
			sts.nNumPerPuff = 1;
			sts.fLifeTime = 1.0f;
		}

 		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_SMOKETRAILSEG_ID, &sts, DFALSE, this);

		// Let each smoke segment do its initial update...
		if (pFX) pFX->Update();

		m_fStartTime = fTime;
	}

	return DTRUE;
}
示例#4
0
DBOOL CLaserBeamFX::UpdateBeam()
{
	if(!m_pClientDE)	return DFALSE;

	DVector		vDist, vUp;
	DRotation	rRot;

	VEC_SET(vUp, 0.0f, 1.0f, 0.0f);
	VEC_SUB(vDist, m_vDest, m_vSource);

	m_pClientDE->AlignRotation(&rRot, &vDist, &vUp);
	m_pClientDE->SetObjectPos(m_hObject, &m_vSource);
	m_pClientDE->SetObjectRotation(m_hObject, &rRot);

	VEC_SET(m_vScale, m_fMinScale, m_fMinScale, VEC_MAG(vDist));
	return	DTRUE;
}
示例#5
0
DBOOL CFlashlightFX::Update()
{
	if (!m_pClientDE || m_bWantRemove || !m_hServerObject || !m_hObject) return DFALSE;

	DDWORD dwUsrFlags;
	m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwUsrFlags);

	// Hidden
	if (!(dwUsrFlags & USRFLG_VISIBLE))
	{
		m_pClientDE->SetObjectFlags(m_hObject, 0);
	}
	else
	{
		DRotation rRot;
		DVector vPos, vF, vR, vU;
		m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
		m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);

		// Cast a line to see where to put the light..
		ClientIntersectQuery iQuery;
		ClientIntersectInfo  iInfo;
	
		VEC_COPY(iQuery.m_From, vPos);
		VEC_COPY(iQuery.m_Direction, vF);
		iQuery.m_Flags = INTERSECT_OBJECTS;

		DFLOAT fDistance = 1000.0f;  // Far, far, away...

		if (m_pClientDE->CastRay(&iQuery, &iInfo))
		{		
			// Place the light
			m_pClientDE->SetObjectPos(m_hObject, &iInfo.m_Point);
			// Calculate the distance
			VEC_SUB(vPos, vPos, iInfo.m_Point);
			fDistance = VEC_MAG(vPos); 
			if (fDistance < 10.0f) fDistance = 10.0f;

			// The farther away, the brighter and bigger the light
			DFLOAT fRadius = fDistance * 0.40f;
			m_pClientDE->SetLightRadius(m_hObject, fRadius);

			// Determine the minimum intensity based on the current light level
			// (so we don't end up casting a dark light instead).
			DFLOAT fMinIntensity = 100.0f;
			DVector vColor;
			if (m_pClientDE->Common()->GetPointShade(&vPos, &vColor))
			{
				if (vColor.x > fMinIntensity) fMinIntensity = vColor.x;
				if (vColor.y > fMinIntensity) fMinIntensity = vColor.y;
				if (vColor.z > fMinIntensity) fMinIntensity = vColor.z;
			}
			fMinIntensity = DCLAMP((fMinIntensity + 32), 0, 255);
			fMinIntensity /= 255.0f;

			DFLOAT fIntensity = (1000.0f - (fDistance/2.0f)) / 1000.0f;
			if (fIntensity < fMinIntensity) fIntensity = fMinIntensity;

			m_pClientDE->SetLightColor(m_hObject, fIntensity, fIntensity, fIntensity);

			m_pClientDE->SetObjectFlags(m_hObject, FLAG_VISIBLE);
		}
		else
		{
			m_pClientDE->SetObjectFlags(m_hObject, 0);
		}
	}

	return DTRUE;
}
示例#6
0
LTBOOL CBulletTrailFX::Update()
{
    if (!m_hObject || !m_pClientDE) return LTFALSE;

    LTFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
		// See if we can figure out what color bubbles to make, based on the
		// container we start in...

		HLOCALOBJ objList[1];
        uint32 dwNum = m_pClientDE->GetPointContainers(&m_vStartPos, objList, 1);

		if (dwNum > 0 && objList[0])
		{
            uint32 dwUserFlags;
			m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);

			if (dwUserFlags & USRFLG_VISIBLE)
			{
                uint16 dwCode;
				if (m_pClientDE->GetContainerCode(objList[0], &dwCode))
				{
					GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2);
				}
			}
		}


		// Move the particle system to the correct position...

		m_pClientDE->SetObjectPos(m_hObject, &m_vStartPos);

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

		VEC_INIT(m_vLastPos);

		// Find the end position...

		ClientIntersectQuery iQuery;
		ClientIntersectInfo  iInfo;

        LTVector vTemp, vEndPoint;

		VEC_MULSCALAR(vTemp, m_vDir, MAX_TRAIL_LENGTH);
		VEC_ADD(vEndPoint, m_vStartPos, vTemp);

		VEC_COPY(iQuery.m_From, m_vStartPos);
		VEC_COPY(iQuery.m_To, vEndPoint);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vEndPoint, iInfo.m_Point, m_vStartPos);
			m_fDistance = VEC_MAG(vEndPoint);
		}

        if (m_fDistance <= 0.0f || m_fFadeTime <= 0.0f) return LTFALSE;

		// Calculate the trail velocity...

		m_fTrailVel = m_fDistance / m_fFadeTime;

		VEC_MULSCALAR(m_vDir, m_vDir, m_fTrailVel);
	}



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

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

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

		// m_pClientDE->SetParticleSystemColorScale(m_hObject, fScale);
        LTFLOAT r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale);

        return LTTRUE;
	}


	// Create the necessary particles...


    LTFLOAT fTimeOffset = g_pGameClientShell->GetFrameTime();



	// Calculate distance traveled this frame...

    LTFLOAT fDist = m_fTrailVel * fTimeOffset;
	if (fDist > m_fDistance) fDist = m_fDistance;

	m_fDistTraveled += fDist;
	if (m_fDistTraveled > m_fDistance)
	{
		fDist = m_fDistance - (m_fDistTraveled - fDist);
        if (fDist <= 0.0f) return LTTRUE;
	}


	// Calculate number of particles to create...

    LTFLOAT fNumParticles = fDist * m_fNumParticles / m_fDistance;


	// Calculate starting bubble position...

    LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor;

	VEC_MULSCALAR(vTemp, m_vDir, fTimeOffset);
	VEC_ADD(vCurPos, m_vLastPos, vTemp);


	// What is the range of colors?

    LTFLOAT fRange = m_vColor2.x - m_vColor1.x;


	// Fill the distance between the last projectile position, and it's
	// current position with bubbles...

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

	VEC_COPY(vPos, m_vLastPos);

    LTFLOAT fLifeTime = 100.0f;

    LTFLOAT fOffset = 0.0f;
    LTVector vDriftOffset;
	VEC_SET(vDriftOffset, 0.0f, 0.0f, 0.0f);

	int nNumParticles = GetNumParticles((int)fNumParticles);

	for (int i=0; i < nNumParticles; i++)
	{
		// Build the individual bubbless...

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

			VEC_SET(vDriftVel, 0.0f, GetRandom(5.0f, 6.0f), 0.0f);

			vTemp.x += GetRandom(-fOffset, fOffset);
			vTemp.y += GetRandom(-fOffset, fOffset);
			vTemp.z += GetRandom(-fOffset, fOffset);

			GetRandomColorInRange(vColor);

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

		VEC_ADD(vPos, vPos, vDelta);
	}

	VEC_COPY(m_vLastPos, vCurPos);
	m_fLastTime = fTime;

    return LTTRUE;
}
示例#7
0
LTBOOL AISpatialNeighbor::Init(AISpatialRepresentation* pThis, AISpatialRepresentation* pNeighbor)
{
	m_pVolume = pNeighbor;

	// 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->InsideMasked(pNeighbor->GetFrontTopLeft(), eAxisAll) || pThis->InsideMasked(pNeighbor->GetBackTopRight(), eAxisAll) ||
		 pThis->InsideMasked(pNeighbor->GetFrontBottomLeft(), eAxisAll) || pThis->InsideMasked(pNeighbor->GetBackBottomRight(), eAxisAll) )
	{
        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.Normalize();
	}
	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.Normalize();
	}

	m_vConnectionMidpoint = m_avConnectionEndpoints[0] + ( m_vConnectionDir * ( m_fConnectionLength * 0.5f ) );

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

	// Ensure that perp dir is axis-aligned.

	RoundVector( m_vConnectionPerpDir );

	// Make sure it points into this volume

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

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

	m_cGates = (uint32)(m_fConnectionLength/48.0f);


	// Check for invalid neighbors.

	if(m_cGates == 0)
	{
		AIError("Volume has Invalid Neighbor %s -> %s. Connection < 48 units!",
			pThis->GetName(), pNeighbor->GetName() );

		return LTFALSE;
	}

	m_vecfGateOccupancy.resize(m_cGates);

	for ( uint32 iGate = 0 ; iGate < m_cGates ; iGate++ )
	{
		m_vecfGateOccupancy[iGate] = 0.0f;
	}

	if(	m_avConnectionEndpoints[0].z == m_avConnectionEndpoints[1].z )
	{
		m_eVolumeConnectionType = eVolumeConnectionTypeHorizontal;

		if( m_pVolume->GetCenter().z < m_vConnectionPos.z )
		{
			m_eVolumeConnectionLocation = eVolumeConnectionLocationFront;
		}
		else {
			m_eVolumeConnectionLocation = eVolumeConnectionLocationBack;
		}
	}
	else
	{
		m_eVolumeConnectionType = eVolumeConnectionTypeVertical;

		if( m_pVolume->GetCenter().x < m_vConnectionPos.x )
		{
			m_eVolumeConnectionLocation = eVolumeConnectionLocationRight;
		}
		else {
			m_eVolumeConnectionLocation = eVolumeConnectionLocationLeft;
		}
	}

	//g_pLTServer->CPrint("cxn @ %f,%f,%f in %f,%f,%f : %f,%f,%f",
	//	EXPANDVEC(m_vConnectionPos), EXPANDVEC(vThisCenter), EXPANDVEC(m_vConnectionPerpDir));

	return LTTRUE;
}
示例#8
0
DVector	CPlayerCamera::FindOptimalCameraPosition()
{
	DVector pos;
	VEC_INIT(pos);

	if (!m_pClientDE || !m_hTarget) return pos;

	DVector		up, right, forward, dir;
	DFLOAT		distToOptimal;
	DVector		TargetPlusOffset;
	
	DVector vTargetPos;
	m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);

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

	if (Equal(vTargetPos, m_vLastTargetPos) && Equal(rRot, m_rLastTargetRot) && m_eCameraMode != DEATH)
	{
		return m_vLastOptPos;
	}
	else
	{
		VEC_COPY(m_vLastTargetPos, vTargetPos);
		ROT_COPY(m_rLastTargetRot, rRot);
	}
		
	DVector vTemp;

	if (m_eCameraMode == DEATH)
	{
		VEC_COPY(vTemp, m_TargetDeathOffset);
	}
	else
	{
		VEC_COPY(vTemp, m_TargetChaseOffset);
	}
	VEC_ADD(vTemp, vTargetPos, vTemp);
	VEC_COPY(TargetPlusOffset, vTemp);

	m_pClientDE->GetRotationVectors(&rRot, &up, &right, &forward);

	//	pos = TargetPlusOffset + right*m_OptX + up*m_OptY + forward*m_OptZ;
	
	DVector vTemp1, vTemp2;
	if (m_eCameraMode == DEATH)
	{
		VEC_MULSCALAR(vTemp, right, m_DeathOptX);
		VEC_MULSCALAR(vTemp2, forward, m_DeathOptZ);
	}
	else
	{
		VEC_MULSCALAR(vTemp, right, m_OptX);
		VEC_MULSCALAR(vTemp2, forward, m_OptZ);
	}
	VEC_MULSCALAR(vTemp1, up, m_OptY);

	ClientIntersectQuery iQuery;
	ClientIntersectInfo  iInfo;

	VEC_ADD(vTemp, vTemp, vTemp1);
	VEC_ADD(vTemp, vTemp, vTemp2);
	VEC_ADD(pos, TargetPlusOffset, vTemp);

	VEC_SUB(vTemp, TargetPlusOffset, pos);
	distToOptimal = VEC_MAG(vTemp);

	VEC_SUB(dir, pos, TargetPlusOffset);
	VEC_NORM(dir);

	VEC_COPY(iQuery.m_From, TargetPlusOffset);
	VEC_COPY(iQuery.m_To, pos);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{		
		VEC_SUB(vTemp, iInfo.m_Point, TargetPlusOffset);

		// If there was something in the way, move in front of that thing.
		if (VEC_MAG(vTemp) < distToOptimal)
		{
			VEC_ADD(pos, iInfo.m_Point, iInfo.m_Plane.m_Normal);
		}
	}

#ifdef DOING_EXTRA_CHECKS

	// Make sure we aren't clipping into walls...
	
	DFLOAT fClipDistance	= 100.0f; // 15.0f;
	DBOOL bClipRightIssues	= DTRUE;
	DBOOL bClipUpIssues		= DTRUE;


	// Check for walls to the right...

	VEC_MULSCALAR(vTemp, right, fClipDistance);
	VEC_ADD(vTemp, pos, vTemp);

	VEC_COPY(iQuery.m_From, pos);
	VEC_COPY(iQuery.m_To, vTemp);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{
		VEC_SUB(vTemp, iInfo.m_Point, pos);
		DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

		VEC_MULSCALAR(vTemp, right, -fDist)
		VEC_ADD(pos, pos, vTemp);
	}
	else
	{
		bClipRightIssues = DFALSE;
	}


	// If we didn't adjust for a wall to the right, check walls to the left...

	if (!bClipRightIssues)
	{
		VEC_MULSCALAR(vTemp, right, -fClipDistance);
		VEC_ADD(vTemp, pos, vTemp);

		VEC_COPY(iQuery.m_From, pos);
		VEC_COPY(iQuery.m_To, vTemp);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vTemp, iInfo.m_Point, pos);
			DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

			VEC_MULSCALAR(vTemp, right, fDist)
			VEC_ADD(pos, pos, vTemp);
		}
	}
			

	// Check for ceilings...

	VEC_MULSCALAR(vTemp, up, fClipDistance);
	VEC_ADD(vTemp, pos, vTemp);

	VEC_COPY(iQuery.m_From, pos);
	VEC_COPY(iQuery.m_To, vTemp);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{
		VEC_SUB(vTemp, iInfo.m_Point, pos);
		DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

		VEC_MULSCALAR(vTemp, up, -fDist)
		VEC_ADD(pos, pos, vTemp);
	}
	else
	{
		bClipUpIssues = DFALSE;
	}


	// If we didn't hit any ceilings, check for floors...

	if (!bClipUpIssues)
	{
		VEC_MULSCALAR(vTemp, up, -fClipDistance);
		VEC_ADD(vTemp, pos, vTemp);

		VEC_COPY(iQuery.m_From, pos);
		VEC_COPY(iQuery.m_To, vTemp);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vTemp, iInfo.m_Point, pos);
			DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

			VEC_MULSCALAR(vTemp, up, fDist)
			VEC_ADD(pos, pos, vTemp);
		}
	}
#endif  // DOING_EXTRA_CHECKS 

	VEC_COPY(m_vLastOptPos, pos);
	return pos;
}
示例#9
0
void CPlayerCamera::MoveCameraToPosition(DVector pos, DVector vStartPos, DFLOAT deltaTime)
{
	if (!m_pClientDE || !m_hTarget) return;

	DFLOAT nCurrentTime = m_pClientDE->GetTime();

	// Handle transition
	if (m_eCameraMode == GOINGFIRSTPERSON || m_eCameraMode == GOINGCHASE || m_eCameraMode == DEATH)
	{

		if (nCurrentTime > m_fTransitionStart + m_fTransitionTime)
		{
			switch (m_eCameraMode)
			{
				case GOINGFIRSTPERSON:
					m_eCameraMode = FIRSTPERSON;
					break;
				case GOINGCHASE:
					m_eCameraMode = CHASE;
					break;
			}
		}
		else
		{
			// vStartPos is starting pos, pos is the position we want
			DFLOAT percentage = (nCurrentTime - m_fTransitionStart) / (m_fTransitionTime);

			DVector vMagnitude;
			VEC_SUB (vMagnitude, pos, vStartPos);
			VEC_MULSCALAR (vMagnitude, vMagnitude, percentage);
			VEC_ADD (pos, vStartPos, vMagnitude);
		}
	}

	DVector	dir;
	VEC_SUB(dir, pos, m_vPos);

	DFLOAT multiplier = 1.0f; // 0.5f;
	
	DVector	toMove;
	VEC_MULSCALAR(toMove, dir, multiplier);
	
	DFLOAT moveMag;

	if(m_bSlide)
	{
		moveMag = VEC_MAG(toMove);
		if(moveMag > VEC_MAG(dir))
			moveMag = VEC_MAG(dir);

		if (toMove.x != 0.0f || toMove.y != 0.0f || toMove.z != 0.0f)
		{
			VEC_NORM(toMove);
		}
		VEC_MULSCALAR(toMove, toMove, moveMag);

		VEC_ADD(m_vPos, m_vPos, toMove);
	}
	else
	{
		VEC_COPY(m_vPos, pos);
	}
}
示例#10
0
DBOOL Equal(DVector & v1, DVector & v2)
{
	DVector v;
	VEC_SUB(v, v1, v2);
	return DBOOL(VEC_MAG(v) < 1.0f);
}
示例#11
0
void SoccerBall::OnTouchNotify( HOBJECT hObj, float fForce )
{
	CollisionInfo colInfo;
	DVector vVel, vOtherVel, vEffectiveVel, vPos, vNewVel;
	DVector vNormal;
	float fEffectiveVelMag, fMultiplier, fVelMag;
	DRotation rRot;
	DVector vUp, vRight;
	DBOOL bIsPlayer;
	
	g_pServerDE->GetVelocity( m_hObject, &vVel );
	g_pServerDE->GetVelocity( hObj, &vOtherVel );

	g_pServerDE->GetObjectPos( m_hObject, &vPos );

	if( hObj == g_pServerDE->GetWorldObject( ))
	{
		VEC_SUB( vEffectiveVel, vOtherVel, vVel );
		fEffectiveVelMag = VEC_MAG( vEffectiveVel );
	
		g_pServerDE->GetLastCollision( &colInfo );

		// Compute new velocity reflected off of the surface.
		if( VEC_MAGSQR( colInfo.m_Plane.m_Normal ) > 0.0f )
		{
			VEC_COPY( vNormal, colInfo.m_Plane.m_Normal );
			if( fEffectiveVelMag > MAXBALLVEL )
				fMultiplier = MAXBOUNCEFACTOR;
			else
				fMultiplier = MINBOUNCEFACTOR + ( MAXBOUNCEFACTOR - MINBOUNCEFACTOR ) * fEffectiveVelMag / MAXBALLVEL;
			VEC_MULSCALAR( vNormal, vNormal, fEffectiveVelMag * fMultiplier );
			VEC_ADD( vNewVel, vVel, vNormal );
			if( fabs( vNewVel.y + vVel.y ) < 100.0f )
				vNewVel.y = vVel.y;
			g_pServerDE->SetVelocity( m_hObject, &vNewVel );
		}

		if( fabs( fForce ) > MINFORCESOUND )
			m_bBounced = DTRUE;
	}
	else
	{
		// Ignore non-solid objects
		if( !( g_pServerDE->GetObjectFlags( hObj ) & FLAG_SOLID ))
			return;

		bIsPlayer = IsPlayer( hObj );
		if( bIsPlayer )
		{
			if( m_hLastPlayer && hObj != m_hLastPlayer )
			{
				g_pServerDE->BreakInterObjectLink( m_hObject, m_hLastPlayer );
			}

			m_hLastPlayer = hObj;
			g_pServerDE->CreateInterObjectLink( m_hObject, m_hLastPlayer );

			m_fRespawnTime = g_pServerDE->GetTime( ) + BALLRESPAWNTIME;
		}

		VEC_ADD( vVel, vVel, vOtherVel );
		if( m_bOnGround && vVel.y < 0.0f )
			vVel.y = 0.0f;
		if( bIsPlayer )
			vVel.y += g_pServerDE->Random( 150.0f, 300.0f );
		fVelMag = VEC_MAG( vVel );
		g_pServerDE->AlignRotation( &rRot, &vVel, DNULL );
		g_pServerDE->EulerRotateX( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->EulerRotateY( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->EulerRotateZ( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->GetRotationVectors( &rRot, &vUp, &vRight, &vVel );
		VEC_MULSCALAR( vVel, vVel, fVelMag );
		g_pServerDE->SetVelocity( m_hObject, &vVel );

		if( fabs( fForce ) > MINFORCESOUND || bIsPlayer )
			m_bBounced = DTRUE;
	}
}
示例#12
0
void SoccerBall::Update( )
{
	DVector vVel, vAccel, vAccelAdd, vPos, vForward, vCross, vTemp, vTemp2;
	CollisionInfo collInfo;
	float fVelMag, fDistTraveled, fTime, fRotAmount, fExp;
	DRotation rRot;

	g_pServerDE->GetObjectPos( m_hObject, &vPos );
	g_pServerDE->GetVelocity( m_hObject, &vVel );
	fVelMag = VEC_MAG( vVel );
	fTime = g_pServerDE->GetTime( );

	// Remove the ball if it's been sitting around for a while.
	if( fTime > m_fRespawnTime )
	{
		g_pServerDE->RemoveObject( m_hObject );
		return;
	}

	// Update the on ground info
	g_pServerDE->GetStandingOn( m_hObject, &collInfo );
	m_bOnGround = ( collInfo.m_hObject ) ? DTRUE : DFALSE;
	if( m_bOnGround )
	{
		m_fLastTimeOnGround = fTime;
	}

	// Get how far we've traveled.
	VEC_SUB( vForward, vPos, m_vLastPos );
	fDistTraveled = VEC_MAG( vForward );
	VEC_COPY( m_vLastPos, vPos );

	// Rotate the ball
	if( fDistTraveled > 0.0f )
	{
		VEC_MULSCALAR( vForward, vForward, 1.0f / fDistTraveled );

		if( m_bOnGround )
		{
			VEC_COPY( m_vLastNormal, collInfo.m_Plane.m_Normal );
			VEC_CROSS( vCross, vForward, m_vLastNormal );
			fRotAmount = VEC_MAG( vCross ) * fDistTraveled / m_fRadius;
		}
		else
		{
			VEC_CROSS( vCross, vForward, m_vLastNormal );
			fRotAmount = VEC_MAG( vCross ) * fDistTraveled / m_fRadius;
		}

		if( fRotAmount > 0.0f )
		{
			VEC_NORM( vCross );
			g_pServerDE->GetObjectRotation( m_hObject, &rRot );
			g_pServerDE->RotateAroundAxis( &rRot, &vCross, fRotAmount );
			g_pServerDE->SetObjectRotation( m_hObject, &rRot );
		}
	}

	// Adjust the velocity and accel
	if( fVelMag < MINBALLVEL )
	{
		VEC_INIT( vVel );
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}
	else if( fVelMag > MAXBALLVEL )
	{
		VEC_MULSCALAR( vVel, vVel, MAXBALLVEL / fVelMag );				
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}
	else
	{
		// new velocity is given by:		v = ( a / k ) + ( v_0 - a / k ) * exp( -k * t )
		g_pServerDE->GetAcceleration( m_hObject, &vAccel );
		fExp = ( float )exp( -BALLDRAG * g_pServerDE->GetFrameTime( ));
		VEC_DIVSCALAR( vTemp, vAccel, BALLDRAG );
		VEC_SUB( vTemp2, vVel, vTemp );
		VEC_MULSCALAR( vTemp2, vTemp2, fExp );
		VEC_ADD( vVel, vTemp2, vTemp );
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}

	// Make sure we're rolling if we're on a slope.  This counteracts the way the
	// engine stops objects on slopes.
	if( m_bOnGround )
	{
		if( collInfo.m_Plane.m_Normal.y < 0.9f && fabs( vVel.y ) < 50.0f )
		{
			g_pServerDE->GetGlobalForce( &vAccelAdd );
			vAccel.y += vAccelAdd.y * 0.5f;
			g_pServerDE->SetAcceleration( m_hObject, &vAccel );
		}
	}

	// Play a bounce sound if enough time has elapsed
	if( m_bBounced )
	{
		if( fTime > m_fLastBounceTime + TIMEBETWEENBOUNCESOUNDS )
		{
			// Play a bounce sound...
			PlaySoundFromPos( &vPos, "Sounds_ao\\events\\soccerball.wav", 750, SOUNDPRIORITY_MISC_MEDIUM );
		}

		m_bBounced = DFALSE;
	}

	g_pServerDE->SetNextUpdate( m_hObject, 0.001f );
}
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));
}
示例#14
0
DBOOL CCastLineFX::Update()
{
	if(!m_hObject || !m_pClientDE || !m_hServerObject) return DFALSE;

	if (m_bWantRemove)
	{
		return DFALSE;
	}

	DRotation rRot;
	m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
	m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	
	DVector vPos;
	m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
	m_pClientDE->SetObjectPos(m_hObject, &vPos);


	if (m_bFirstUpdate)
	{
		m_bFirstUpdate = DFALSE;

		DELine line;

		// Set first vertex...	

		VEC_SET(line.m_Points[0].m_Pos, 0.0f, 0.0f, 0.0f);
		line.m_Points[0].r = m_vStartColor.x;
		line.m_Points[0].g = m_vStartColor.y;
		line.m_Points[0].b = m_vStartColor.z;
		line.m_Points[0].a = m_fStartAlpha;

		// Set second vertex (cast a ray to find it)...

		DVector vEndPoint, vU, vR, vF;
		m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		VEC_NORM(vF);

		DFLOAT fDistance = 10000.0f;  // Far, far, away...

		if (!m_hCastTo)
		{
			ClientIntersectQuery iQuery;
			ClientIntersectInfo  iInfo;

			VEC_COPY(iQuery.m_From, vPos);
			VEC_COPY(iQuery.m_Direction, vF);
			iQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;

			if (m_pClientDE->CastRay(&iQuery, &iInfo))
			{		
				VEC_COPY(vEndPoint, iInfo.m_Point);

				fDistance = VEC_MAG(vEndPoint);
			}
		}
		else
		{
			m_pClientDE->GetObjectPos(m_hCastTo, &vEndPoint);
			VEC_SUB(vEndPoint, vEndPoint, vPos);
			fDistance = VEC_MAG(vEndPoint);
		}

		VEC_SET(vEndPoint, 0.0f, 0.0f, 1.0f);
		VEC_MULSCALAR(vEndPoint, vEndPoint, fDistance);

		VEC_COPY(line.m_Points[1].m_Pos, vEndPoint);
		line.m_Points[1].r = m_vEndColor.x;
		line.m_Points[1].g = m_vEndColor.y;
		line.m_Points[1].b = m_vEndColor.z;
		line.m_Points[1].a = m_fEndAlpha;

		m_pClientDE->AddLine(m_hObject, &line);
	}

	return DTRUE;
}
示例#15
0
void VolumeBrush::UpdatePhysics(ContainerPhysics* pCPStruct)
{
	if (m_bHidden || !pCPStruct || !pCPStruct->m_hObject) return;

    LTFLOAT fUpdateDelta = g_pLTServer->GetFrameTime();


	// Let the character know if they are in liquid...

	if (IsLiquid(m_eContainerCode) && IsCharacter(pCPStruct->m_hObject))
	{
        CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(pCPStruct->m_hObject);
		if (pCharacter)
		{
			pCharacter->UpdateInLiquid(this, pCPStruct);
		}
	}


	// Player container physics is done on the client...

	if (!IsPlayer(pCPStruct->m_hObject))
	{
		// Dampen velocity based on the viscosity of the container...

        LTVector vVel, vCurVel;
		vVel = vCurVel = pCPStruct->m_Velocity;

		if (m_fViscosity > 0.0f && VEC_MAG(vCurVel) > 1.0f)
		{
            LTVector vDir;
			VEC_COPY(vDir, vCurVel);
			VEC_NORM(vDir);

            LTFLOAT fAdjust = MAX_CONTAINER_VISCOSITY * m_fViscosity * fUpdateDelta;

			vVel = (vDir * fAdjust);

			if (VEC_MAG(vVel) < VEC_MAG(vCurVel))
			{
				VEC_SUB(vVel, vCurVel, vVel);
			}
			else
			{
				VEC_INIT(vVel);
			}

			vVel += (m_vCurrent * fUpdateDelta);

			pCPStruct->m_Velocity = vVel;
		}


		// Do special liquid handling...

		if (IsLiquid(m_eContainerCode))
		{
			UpdateLiquidPhysics(pCPStruct);
		}
	}


	// Update damage...

	// Make damage relative to update delta...

    LTFLOAT fDamage = 0.0f;
	if (m_fDamage > 0.0f)
	{
		fDamage = m_fDamage * fUpdateDelta;
	}

	// Damage using progressive damage.  This insures that the correct
	// damage effect is shown on the client...

	if (fDamage)
	{
		DamageStruct damage;

		damage.eType	  = m_eDamageType;
		damage.fDamage	  = fDamage;
		damage.hDamager   = m_hObject;

		// Use progressive damage...
		damage.fDuration  = 0.25f;
		damage.hContainer = m_hObject;

		damage.DoDamage(this, pCPStruct->m_hObject);
	}
}