示例#1
0
void CSFXMgr::DirtyVisibleRenderTargets()
{
	//run through all of our render targets and tell them to update
	CSpecialFXList* pRenderTargetList = GetFXList(SFX_RENDERTARGET_ID);
	if(pRenderTargetList && (pRenderTargetList->GetNumItems() > 0))
	{
		//run through the list finding those that are initialized
		for(uint32 nCurrRenderTarget = 0; nCurrRenderTarget < (uint32)pRenderTargetList->GetSize(); nCurrRenderTarget++)
		{
			CSpecialFX* pEffect = (*pRenderTargetList)[nCurrRenderTarget];
			if(pEffect)
			{
				//and now that we have found one, tell it to dirty
				((CRenderTargetFX*)pEffect)->DirtyIfVisible();
			}
		}
	}
}
示例#2
0
void CSFXMgr::UpdateRenderTargets(const LTRigidTransform& tCamera, const LTVector2& vCameraFOV)
{
	//run through all of our render targets and tell them to update
	CSpecialFXList* pRenderTargetList = GetFXList(SFX_RENDERTARGET_ID);
	if(pRenderTargetList && (pRenderTargetList->GetNumItems() > 0))
	{
		//run through the list finding those that are initialized
		for(uint32 nCurrRenderTarget = 0; nCurrRenderTarget < (uint32)pRenderTargetList->GetSize(); nCurrRenderTarget++)
		{
			CSpecialFX* pEffect = (*pRenderTargetList)[nCurrRenderTarget];
			if(pEffect)
			{
				//and now that we have found one, tell it to update
				((CRenderTargetFX*)pEffect)->UpdateRenderTarget(tCamera, vCameraFOV);
			}
		}
	}
}
示例#3
0
bool CTargetMgr::CheckForCharacters(LTVector vObjPos,LTVector vDims, uint8 nId)
{
	float fLeashLen = GetConsoleFloat("LeashLen",0.0f);
	//give 'em some room
	vDims.x += fLeashLen;
	vDims.y += fLeashLen;
	vDims.z += fLeashLen;
	vDims *= 2.0f;

	CSpecialFXList* pList = g_pGameClientShell->GetSFXMgr()->GetFXList(SFX_CHARACTER_ID);
	if (!pList) return false;

	int nNumChars = pList->GetSize();

	LTVector vCharPos, vCharDims;
	for (int i=0; i < nNumChars; i++)
	{
		if ((*pList)[i])
		{
			CCharacterFX* pChar = (CCharacterFX*)(*pList)[i];

			if (pChar->m_cs.bIsPlayer && pChar->m_cs.nClientID == nId)
				continue;

			g_pLTClient->GetObjectPos(pChar->GetServerObj(), &vCharPos);

			if (vObjPos.x - vDims.x < vCharPos.x && vCharPos.x < vObjPos.x + vDims.x &&
				vObjPos.y - vDims.y < vCharPos.y && vCharPos.y < vObjPos.y + vDims.y &&
				vObjPos.z - vDims.z < vCharPos.z && vCharPos.z < vObjPos.z + vDims.z)
			{
				return true;
			}

		}
	}

	return false;
}
示例#4
0
DBOOL CMarkSFX::CreateObject(CClientDE *pClientDE)
{
	if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;

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


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

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

	int nNumBulletHoles = pList->GetSize();

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

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

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

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


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

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

	m_hObject = pClientDE->CreateObject(&createStruct);

	m_pClientDE->SetObjectScale(m_hObject, &m_vScale);


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

	ClientIntersectQuery iq;
	ClientIntersectInfo  ii;

	iq.m_Flags = INTERSECT_OBJECTS | INTERSECT_HPOLY;

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

	// Hit something!  try to clip against it. (since this is only being used for bullet marks,
	if (pClientDE->IntersectSegment(&iq, &ii))
	{
		HPOLY hPoly = ii.m_hPoly;
		pClientDE->ClipSprite(m_hObject, hPoly);
	}
	m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f);
	
	return DTRUE;
}
示例#5
0
void CPolyGridFX::CreateModelWaves(uint32 nKernalSize, uint32 nBuffer, float fFrameTime)
{
	//maximum number of objects to find intersecting the grid
	static const uint32 knMaxObjToFind = 32;

	//find the radius of our polygrid
	float fPolyRad = m_vDims.Mag();

	//amount to displace for a model
	float fDisplaceAmount = m_fModelDisplace * fFrameTime;

	//just bail if the models aren't going to displace at all
	if(fDisplaceAmount < 0.01f)
		return;

	HLOCALOBJ hFound[knMaxObjToFind];
	uint32 nFound = 0;

	LTVector vPGPos;
	m_pClientDE->GetObjectPos(m_hObject, &vPGPos);

	LTVector vPGDims;
	m_pClientDE->Physics()->GetObjectDims(m_hObject, &vPGDims);

	//now run through all the characters and see which ones intersect
	CSpecialFXList* pCharacterList = g_pGameClientShell->GetSFXMgr()->GetFXList(SFX_CHARACTER_ID);

	LTVector vPGMin = vPGPos - vPGDims;
	LTVector vPGMax = vPGPos + vPGDims;

	for(uint32 nCurrChar = 0; nCurrChar < (uint32)pCharacterList->GetNumItems(); nCurrChar++)
	{
		if(!(*pCharacterList)[nCurrChar])
			continue;

		//determine the HOBJECT of this character
		HOBJECT hChar = (*pCharacterList)[nCurrChar]->GetServerObj();

		if(!hChar)
			continue;

		//get the object position and dimensions
		LTVector vCharPos, vCharDims;
		m_pClientDE->GetObjectPos(hChar, &vCharPos);
		m_pClientDE->Physics()->GetObjectDims(hChar, &vCharDims);

		LTVector vCharMin = vCharPos - vCharDims;
		LTVector vCharMax = vCharPos + vCharDims;

		//if it overlaps, add it to our list
		if( (vPGMin.x < vCharMax.x) && (vPGMax.x > vCharMin.x) &&
			(vPGMin.y < vCharMax.y) && (vPGMax.y > vCharMin.y) &&
			(vPGMin.z < vCharMax.z) && (vPGMax.z > vCharMin.z))
		{
			//they intersect, add it to the list
			hFound[nFound] = hChar;
			nFound++;

			//see if we need to stop looking for objects
			if(nFound >= knMaxObjToFind)
				break;
		}
	}

	//bail if none
	if(nFound == 0)
	{
		//make sure all objects are cleared from the list
		for(uint32 nCurrRemove = 0; nCurrRemove < MAX_MODELS_TO_TRACK; nCurrRemove++)
		{
			m_hTrackedModels[nCurrRemove] = NULL;
		}
		return;
	}

	//precalc info

	//find the orienation of the polygrid
	LTRotation rRot;
	m_pClientDE->GetObjectRotation(m_hObject, &rRot);

	//now get the basis vectors of the object space
	LTVector vRight		= rRot.Right();
	LTVector vForward	= rRot.Forward();

	//make sure the polygrid is valid
	if((m_dwNumPoliesX == 0) || (m_dwNumPoliesY == 0))
		return;

	//find the dimensions of the polygons of the polygrid
	float fXPolySize = (m_vDims.x * 2.0f) / (float)m_dwNumPoliesX;
	float fYPolySize = (m_vDims.z * 2.0f) / (float)m_dwNumPoliesY;

	//bail if not a valid size
	if((fXPolySize < 0.01f) || (fYPolySize < 0.01f))
		return;

	//flag indicating which tracked models should be kept around
	bool bTouchedTrackedModels[MAX_MODELS_TO_TRACK];

	for(uint32 nCurrTrack = 0; nCurrTrack < MAX_MODELS_TO_TRACK; nCurrTrack++)
	{
		bTouchedTrackedModels[nCurrTrack] = false;
	}

	//ok, now we run through all the objects we found and update our grid accordingly
	for(uint32 nCurrObj = 0; nCurrObj < nFound; nCurrObj++)
	{
		//the object we are checking
		HLOCALOBJ hObj = hFound[nCurrObj];

		//now lets see if this is a tracked model, if it is, we know where it was last
		//update and we can create a wave line, otherwise we have no clue, and should
		//track it for the next update
		bool bTracked = false;
		LTVector vPrevPos;

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

		//if we aren't currently tracking it, this is where to put it
		uint32 nInsertPos = MAX_MODELS_TO_TRACK - 1;

		for(uint32 nCurrModel = 0; nCurrModel < MAX_MODELS_TO_TRACK; nCurrModel++)
		{
			if(m_hTrackedModels[nCurrModel] == hObj)
			{
				//we found a match, we need to save this value, move
				//it to the front of the list, and update it
				vPrevPos = m_vTrackedModelsPos[nCurrModel];

				//move all the items back so that this will be in the first slot
				for(uint32 nCurrMove = nCurrModel; nCurrMove > 0; nCurrMove--)
				{
					m_hTrackedModels[nCurrMove] = m_hTrackedModels[nCurrMove - 1];
					m_vTrackedModelsPos[nCurrMove] = m_vTrackedModelsPos[nCurrMove - 1];
					bTouchedTrackedModels[nCurrMove] = bTouchedTrackedModels[nCurrMove - 1];
				}

				//update the first element
				m_hTrackedModels[0] = hObj;
				m_vTrackedModelsPos[0] = vPos;
				bTouchedTrackedModels[0] = true;

				//all done
				bTracked = true;
				break;
			}

			//also bail if one of the slots is NULL
			if(m_hTrackedModels[nCurrModel] == NULL)
			{
				nInsertPos = nCurrModel;
			}
		}

		//see if this was tracked or not
		if(!bTracked)
		{
			//was not! We need to add it to the list
			m_hTrackedModels[nInsertPos] = hObj;
			m_vTrackedModelsPos[nInsertPos] = vPos;
			bTouchedTrackedModels[nInsertPos] = true;

			continue;
		}

		//make sure that the model is actually moving
		if((vPrevPos - vPos).MagSqr() < 0.5f)
			continue;

		//ok, we have a model that intersects our polygrid, let us create some waves

		//find out the endpoints of the line that will displace
		float fX1 = vRight.Dot(vPrevPos - vPGPos) + m_vDims.x;
		float fY1 = vForward.Dot(vPrevPos - vPGPos) + m_vDims.z;
		float fX2 = vRight.Dot(vPos - vPGPos) + m_vDims.x;
		float fY2 = vForward.Dot(vPos - vPGPos) + m_vDims.z;

		//now find the greater delta in polygon units
		float fXDelta = (float)fabs(fX1 - fX2) / fXPolySize;
		float fYDelta = (float)fabs(fY1 - fY2) / fYPolySize;

		//increments for the X and Y directions
		float fXInc, fYInc;
		float fCurrX, fCurrY;

		//the variable to use for threshold comparisons
		float *pfCompare;

		//the threshold
		float fThreshold;

		//now scan convert accordingly
		if(fYDelta > fXDelta)
		{
			//make sure Y1 is smaller
			if(fY2 < fY1)
			{
				Swap(fY1, fY2);
				Swap(fX1, fX2);
			}

			fYInc = fYPolySize;
			fXInc = (fX2 - fX1) / (fY2 - fY1) * fYInc;

			fThreshold = fY2 / fYPolySize;
			pfCompare = &fCurrY;
		}
		else
		{
			//make sure Y1 is smaller
			if(fX2 < fX1)
			{
				Swap(fY1, fY2);
				Swap(fX1, fX2);
			}
			fXInc = fXPolySize;
			fYInc = (fY2 - fY1) / (fX2 - fX1) * fXInc;

			fThreshold = fX2 / fXPolySize;
			pfCompare = &fCurrX;
		}

		//start out at the first point
		fCurrY = fY1 / fYPolySize;
		fCurrX = fX1 / fXPolySize;
		fXInc /= fXPolySize;
		fYInc /= fXPolySize;

		float fXFrac;
		float fYFrac;

		uint32 nPrevBuffer = (nBuffer + 1) % 2;

		//we need to scale the displacement amount by the speed at which we are moving
		fDisplaceAmount *= (vPrevPos - vPos).Mag() / (fFrameTime * g_cvarPGDisplaceMoveScale.GetFloat());

		//now scan convert!
		while(*pfCompare < fThreshold)
		{
			//convert this to an integer position
			int32 nXPos = (int32)(fCurrX);
			int32 nYPos = (int32)(fCurrY);

			//handle clipping
			if((nXPos >= (int32)nKernalSize) && (nYPos >= (int32)nKernalSize) &&
				(nXPos < (int32)m_dwNumPoliesX - (int32)nKernalSize - 1) &&
				(nYPos < (int32)m_dwNumPoliesY - (int32)nKernalSize - 1))
			{
				fXFrac = fCurrX - nXPos;
				fYFrac = fCurrY - nYPos;

				m_WaveBuffer[nBuffer].Get(nXPos, nYPos)  += fDisplaceAmount * (1.0f - fXFrac) * (1.0f - fYFrac);
				m_WaveBuffer[nBuffer].Get(nXPos + 1, nYPos) += fDisplaceAmount * fXFrac * (1.0f - fYFrac);
				m_WaveBuffer[nBuffer].Get(nXPos, nYPos + 1) += fDisplaceAmount * (1.0f - fXFrac) * fYFrac;
				m_WaveBuffer[nBuffer].Get(nXPos + 1, nYPos + 1) += fDisplaceAmount * fXFrac * fYFrac;
				
				m_WaveBuffer[nPrevBuffer].Get(nXPos, nYPos)  += fDisplaceAmount * (1.0f - fXFrac) * (1.0f - fYFrac);
				m_WaveBuffer[nPrevBuffer].Get(nXPos + 1, nYPos) += fDisplaceAmount * fXFrac * (1.0f - fYFrac);
				m_WaveBuffer[nPrevBuffer].Get(nXPos, nYPos + 1) += fDisplaceAmount * (1.0f - fXFrac) * fYFrac;
				m_WaveBuffer[nPrevBuffer].Get(nXPos + 1, nYPos + 1) += fDisplaceAmount * fXFrac * fYFrac;
			}

			//move along
			fCurrX += fXInc;
			fCurrY += fYInc;
		}
	}

	//now that we are done, clear out any models that were not touched
	for(uint32 nCurrRemove = 0; nCurrRemove < MAX_MODELS_TO_TRACK; nCurrRemove++)
	{
		if(!bTouchedTrackedModels[nCurrRemove])
			m_hTrackedModels[nCurrRemove] = NULL;
	}
}
示例#6
0
void CTriggerFX::CheckPlayersWithinTrigger()
{
	if( m_cs.bLocked )
		return;

	// Get a list of all the characters...

	CSpecialFXList *pList = g_pGameClientShell->GetSFXMgr()->GetFXList( SFX_CHARACTER_ID );
	if( !pList )
		return;

	int nListSize = pList->GetSize();
	int nNumChars = pList->GetNumItems();
	int nNumFoundChars = 0;
	int nNumPlayersFound = 0;
	uint32 dwLocalId = 0;

	g_pLTClient->GetLocalClientID( &dwLocalId );

	LTVector vTrigPos, vPlayerPos, vPlayerDims, vPlayerMin, vPlayerMax;
	g_pLTClient->GetObjectPos( m_hServerObject, &vTrigPos );

	// Setup the triggers box...
	
	LTVector vTrigMin = vTrigPos - m_cs.vDims;
	LTVector vTrigMax = vTrigPos + m_cs.vDims;

	bool bLocalPlayerIn = false;
	
	// Initialize our containers to zero.  Don't call clear, since we'll be using
	// these vectors every frame and most likely they will have the same
	// number of elements across multiple frames.
	m_lstPlayersNotInTrigger.resize( 0 );
	m_lstNewPlayersInTrigger.resize( 0 );

	for( int i = 0; i < nListSize; ++i )
	{
		// Try not to go through the entire list...

		if( nNumFoundChars == nNumChars )
			break;

		if( (*pList)[i] )
		{
			CCharacterFX *pChar = (CCharacterFX*)(*pList)[i];
			if( !pChar )
				continue;

			// Found another char..
			++nNumFoundChars;

			if( pChar->m_cs.bIsPlayer && pChar->m_cs.nClientID != ( uint8 )-1 )
			{
				++nNumPlayersFound;
				
				HOBJECT hPlayer = pChar->GetServerObj();

				g_pLTClient->GetObjectPos( hPlayer, &vPlayerPos );
				g_pPhysicsLT->GetObjectDims( hPlayer, &vPlayerDims );

				vPlayerMin = vPlayerPos - vPlayerDims;
				vPlayerMax = vPlayerPos + vPlayerDims;

				// Check the current list of players in the trigger for this player...
					
				CharFXList::iterator iter;
				for( iter = m_lstCurPlayersInTrigger.begin(); iter != m_lstCurPlayersInTrigger.end(); ++iter )
				{
					if( pChar == (*iter) )
						break;
				}

				// Check if we are within the height of the trigger...

				bool bWithinHeight = false;
				if( vPlayerMax.y > vTrigMin.y && vPlayerMin.y < vTrigMax.y )
					bWithinHeight = true;

				if( bWithinHeight && BoxesIntersect( vTrigMin, vTrigMax, vPlayerMin, vPlayerMax ) && !pChar->IsPlayerDead())
				{
					if( dwLocalId == pChar->m_cs.nClientID )
						bLocalPlayerIn = true;

					// If it wasn't in the list add it...

					if( iter == m_lstCurPlayersInTrigger.end() )
					{
						m_lstCurPlayersInTrigger.push_back( pChar );
						m_lstNewPlayersInTrigger.push_back( pChar );
					}

				}
				else
				{
					if( iter != m_lstCurPlayersInTrigger.end() )
						m_lstCurPlayersInTrigger.erase( iter );

					m_lstPlayersNotInTrigger.push_back( pChar );
				}
			}
		}
	}

	wchar_t wszBuffer[256];

	if( (m_lstNewPlayersInTrigger.size() > 0) && (nNumPlayersFound > 1) )
	{
		CClientInfoMgr *pInfoMgr = g_pInterfaceMgr->GetClientInfoMgr();
		if( !pInfoMgr )
			return;

		if( bLocalPlayerIn )
		{
			// Display a general transmission and messages for each player you are waiting for...

			int nPlayersNotInTrig = m_lstPlayersNotInTrigger.size();

			if( m_cs.nPlayerInsideID != (uint32)-1 )
			{
				g_pTransmission->Show( StringIDFromIndex(m_cs.nPlayerInsideID) );
			}
			else if( nPlayersNotInTrig > 1 )
			{
				//sTransmission.Format( "You are waiting for %i players.", nPlayersNotInTrig );
				FormatString( "IDS_EXIT_PLAYER_WAITING", wszBuffer, LTARRAYSIZE(wszBuffer), nPlayersNotInTrig );
				g_pTransmission->Show( wszBuffer );
			}
			else
			{
				//sTransmission.Format( "You are waiting for 1 player." );
				FormatString( "IDS_EXIT_PLAYER_WAITING_1", wszBuffer, LTARRAYSIZE(wszBuffer) );
				g_pTransmission->Show( wszBuffer );
			}		
			
			
			CharFXList::iterator iter;
			for( iter = m_lstPlayersNotInTrigger.begin(); iter != m_lstPlayersNotInTrigger.end(); ++iter )
			{
				//sMessage.Format( "You are waiting for %s.", pInfoMgr->GetPlayerName( (*iter)->m_cs.nClientID ));
				FormatString( "IDS_EXIT_PLAYER_WAITING_NAME", wszBuffer, LTARRAYSIZE(wszBuffer), pInfoMgr->GetPlayerName( (*iter)->m_cs.nClientID) );
				g_pGameMsgs->AddMessage( wszBuffer );
			}
		}
		else
		{
			// Display a general transmission and messages for each player waiting for you...

			int nPlayersInTrig = m_lstCurPlayersInTrigger.size();
			
			if( m_cs.nPlayerOutsideID != (uint32)-1 )
			{
				g_pTransmission->Show( LoadString(m_cs.nPlayerOutsideID) );
			}
			else if( nPlayersInTrig > 1 )
			{
//				sTransmission.Format( "%i players are waiting for you",nPlayersInTrig  );
				FormatString( "IDS_EXIT_WAITING", wszBuffer, LTARRAYSIZE(wszBuffer), nPlayersInTrig );
				g_pTransmission->Show( wszBuffer );
			}
			else
			{
//				sTransmission.Format( "1 player is waiting for you." );
				FormatString( "IDS_EXIT_WAITING_1", wszBuffer, LTARRAYSIZE(wszBuffer) );
				g_pTransmission->Show( wszBuffer );
			}
			

			CharFXList::iterator iter;
			for( iter = m_lstCurPlayersInTrigger.begin(); iter != m_lstCurPlayersInTrigger.end(); ++iter )
			{
				FormatString( "IDS_EXIT_WAITING_NAME", wszBuffer, LTARRAYSIZE(wszBuffer), pInfoMgr->GetPlayerName( (*iter)->m_cs.nClientID) );
				g_pGameMsgs->AddMessage( wszBuffer );	
			}
		}
	}
}