コード例 #1
0
ファイル: AutoTargetMgr.cpp プロジェクト: Arc0re/lithtech
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CAutoTargetMgr::GenerateNodeArray()
//
//	PURPOSE:	Find the nodes closest to the center of view
//
// ----------------------------------------------------------------------- //
void CAutoTargetMgr::GenerateNodeArray()
{
	int cNodes;

	ILTModel *pModelLT = g_pLTClient->GetModelLT();

	//clear our node array
	m_nNodeCount = 0;


	//step through the chars we know about
	CharFXArray::iterator iter = m_Targets.begin();
	while (iter != m_Targets.end())
	{
		CCharacterFX* pChar = (CCharacterFX*)(*iter);
		ModelsDB::HSKELETON hModelSkeleton = pChar->GetModelSkeleton();
		cNodes = g_pModelsDB->GetSkeletonNumNodes(hModelSkeleton);
	
		// Enumerate through the nodez
		for(int iNode = 0; iNode < cNodes && m_nNodeCount < MAX_AUTOTARGET_NODES; iNode++)
		{
			ModelsDB::HNODE hCurNode = g_pModelsDB->GetSkeletonNode( hModelSkeleton, iNode );
			if( g_pModelsDB->GetNodeAutoTarget( hCurNode ))
			{
				// get the nodes position
				LTTransform lTrans;
				HMODELNODE hNode;

				char const* szNodeName = g_pModelsDB->GetNodeName( hCurNode );
				if( LT_OK == pModelLT->GetNode( pChar->GetServerObj(), szNodeName, hNode ) )
				{
					if( LT_OK == pModelLT->GetNodeTransform( pChar->GetServerObj(), hNode, lTrans, true ) )
					{	
						m_NodeArray[m_nNodeCount].vPos = lTrans.m_vPos;
						m_NodeArray[m_nNodeCount].hChar = pChar->GetServerObj();
						m_nNodeCount++;
					}
				}
			}
		}
		iter++;
	}

}
コード例 #2
0
ファイル: SFXMgr.cpp プロジェクト: Arc0re/lithtech
CCharacterFX* CSFXMgr::GetCharacterFX(HOBJECT hObject)
{
	CCharacterFX* pCharacterFX = NULL;
	int cCharacterFX  = m_dynSFXLists[SFX_CHARACTER_ID].GetSize();

	for ( int iCharacterFX = 0 ; iCharacterFX < cCharacterFX ; iCharacterFX++ )
	{
		pCharacterFX = (CCharacterFX*)m_dynSFXLists[SFX_CHARACTER_ID][iCharacterFX];
		if (pCharacterFX && pCharacterFX->GetServerObj() == hObject)
		{
			return pCharacterFX;
		}
	}

	return NULL;
}
コード例 #3
0
ファイル: TargetMgr.cpp プロジェクト: rickyharis39/nolf2
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
ファイル: TargetMgr.cpp プロジェクト: rickyharis39/nolf2
void CTargetMgr::Update()
{
	
	// Do any necessary initialization...

	if (m_bFirstUpdate)
	{
		FirstUpdate();
		m_bFirstUpdate = false;
	}


	if (m_hLockedTarget && m_hTarget == m_hLockedTarget)
	{
		//are we disabling a GadgetTarget?
		if (g_pPlayerMgr->IsDisabling())
		{
			SetGadgetTarget( true );
			return;
		}

		//are we searching something?
		if (g_pPlayerMgr->IsSearching())
		{
			m_bSearchTarget = true;
			SetTargetStringID(IDS_TARGET_SEARCHING);
			
			float fDistAway = 10000.0f;
			CheckForIntersect(fDistAway);
			
			return;
		}
	}

	g_pPlayerStats->UpdateMaxProgress( 0 );
	g_pPlayerStats->UpdateProgress( 0 );
	g_pHUDMgr->QueueUpdate( kHUDProgressBar );


	// If we currently have a target, see if it is a body and if so remove the
	// glow flag (it may be set again below)...
	if (m_hTarget)
	{
		CBodyFX* pBody = g_pGameClientShell->GetSFXMgr()->GetBodyFX(m_hTarget);
		if (pBody) 
		{
			g_pCommonLT->SetObjectFlags(m_hTarget, OFT_User, 0, USRFLG_GLOW);
		}
	}


	// Start fresh
	ClearTargetInfo();


	//see what we've looking at
	float fDistAway = 10000.0f;
	CheckForIntersect(fDistAway);
	if (!m_hTarget) 
	{
		//nothing to see here
		return;
	}

	m_fTargetRange = fDistAway;

	//if its a body's hitbox, check the body instead
	CBodyFX* pBody = g_pGameClientShell->GetSFXMgr()->GetBodyFromHitBox(m_hTarget);
	if (pBody)
	{
		m_hTarget = pBody->GetServerObj();
		m_ActivationData.m_hTarget = m_hTarget;
		if (!m_hTarget) return;
	}

	//if its a Character's hitbox and it is searchable, check the Character instead
	CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromHitBox(m_hTarget);
	if (pCharacter)
	{
		m_hTarget = pCharacter->GetServerObj();
		m_ActivationData.m_hTarget = m_hTarget;
		if (!m_hTarget) return;
	}



	uint32 dwUserFlags = 0;
    g_pCommonLT->GetObjectFlags(m_hTarget, OFT_User, dwUserFlags);

	// If we're on a vehicle (or if we are dead) all we care about is other players in a multiplayer game...
	// Some vehicles (like the PlayerLure) let you activate, so we'll just check if the
	// vehicle will let us show a crosshair to see if we're on a "true" vehicle or not...

	// It would be great if we didn't have to do all these checks, but such is life...

	bool bPlayersOnly = g_pPlayerMgr->IsPlayerDead() || (g_pPlayerMgr->GetMoveMgr()->GetVehicleMgr()->CanShowCrosshair() ? false : true);


	if (!bPlayersOnly)
	{
		//special case handling for bodies
		if (pBody || pCharacter)
		{
			bool bCanSearch = !!(dwUserFlags & USRFLG_CAN_SEARCH);
			if (pBody)
			{
				if (fDistAway <= g_vtActivationDistance.GetFloat())
				{
					// Make target glow, so it stands out more...
					g_pCommonLT->SetObjectFlags(m_hTarget, OFT_User, USRFLG_GLOW, USRFLG_GLOW);
				}
				
				if (pBody->CanBeRevived() && fDistAway <= g_vtReviveDistance.GetFloat() && IsRevivePlayerGameType( ))
				{
					// Get the client information of the body and us.
					uint32 nId = pBody->GetClientId();
					CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr();
					CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId);
					CLIENT_INFO *pLocalCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient();

					// Only allow us to revive people on the same team.  For non-team games,
					// the teamid will be set to the same invalid value anyway.
					if( pCI && pLocalCI )
					{
						if (pCI->nTeamID == pLocalCI->nTeamID)
						{
							m_nString = 0;
							FormatString(IDS_TARGET_REVIVE, m_szString, ARRAY_LEN(m_szString), pCI->sName.c_str());

							LTVector vObjPos, vDims;
							g_pLTClient->GetObjectPos(pBody->GetServerObj(), &vObjPos);
							g_pPhysicsLT->GetObjectDims(pBody->GetServerObj(), &vDims);

							// Players are non-solid to each other so you can revive right on top of them.
							m_bCanActivate = true;  //!CheckForCharacters(vObjPos, vDims, pBody->GetClientId());
							m_bMoveTarget = true;
							m_ActivationData.m_nType = MID_ACTIVATE_REVIVE;
						}
						else
						{
							m_nString = 0;
							m_bCanActivate = false;
							m_bMoveTarget = false;
							LTStrCpy(m_szString, pCI->sName.c_str(), ARRAY_LEN(m_szString));

						}

						return;
					}

				}
				else
				{
					m_bMoveTarget = (pBody->CanBeCarried() && g_pPlayerMgr->CanDropCarriedObject());
				}

			}
			else if (pCharacter)
			{
				if( (pCharacter->m_cs.eCrosshairCharacterClass != BAD) && (pCharacter->CanWake()) && (pCharacter->IsUnconscious() || (pCharacter->Slipped() && !pCharacter->m_cs.bIsPlayer)) ) 
				{
					SetTargetStringID( IDS_TARGET_WAKEUP );
					
					m_bCanActivate	= true;
					m_bMoveTarget	= g_pPlayerMgr->CanDropCarriedObject() && pCharacter->CanBeCarried();

					m_ActivationData.m_nType = MID_ACTIVATE_WAKEUP;
					return;
				}

				m_bMoveTarget = g_pPlayerMgr->CanDropCarriedObject() && pCharacter->CanBeCarried();
			}
			else
			{
				m_bMoveTarget = false;
			}

			if (bCanSearch && fDistAway <= g_vtActivationDistance.GetFloat())
			{
				// we can search this body
				m_bSearchTarget = true;
				m_ActivationData.m_nType = MID_ACTIVATE_SEARCH;
				SetTargetStringID(IDS_TARGET_SEARCH);

				uint8 nProgress = g_pPlayerMgr->GetSearcher()->GetMaxProgress();
				g_pPlayerStats->UpdateMaxProgress( nProgress );
				g_pPlayerStats->UpdateProgress( nProgress );
				g_pHUDMgr->QueueUpdate( kHUDProgressBar );

				return;
			}
			else if (pBody)
			{
				return;
			}

		}
		else
		{
			float fGadgetDistance = g_vtActivationDistance.GetFloat();
			if( dwUserFlags & USRFLG_GADGET_CAMERA )
			{
				fGadgetDistance = g_vtCamZoom1MaxDist.GetFloat();
			}

			// is this a gadget target
			if (IsGadgetActivatable(m_hTarget) && (fDistAway <= fGadgetDistance))
			{
				// looks like we can use a gadget on it...
				SetGadgetTarget( false );
				return;
			}
		}
	}

	//are we aiming at a person?
	if (dwUserFlags & USRFLG_CHARACTER)
	{
		CCharacterFX* const pFX = (CCharacterFX*)g_pGameClientShell->GetSFXMgr()->FindSpecialFX(SFX_CHARACTER_ID, m_hTarget);

		// All we care about if we're on a vehicle (or if we are dead) is the Multiplayer check below...

		if (!bPlayersOnly)
		{
			//display debug info if we have any 
			if( pFX && pFX->GetInfoString() && *pFX->GetInfoString() )
			{
				SAFE_STRCPY(m_szDebugString,pFX->GetInfoString());			
			}
			else
			{
				m_szDebugString[0] = NULL;
			}

			// is this a person we can talk to?
			if (dwUserFlags & USRFLG_CAN_ACTIVATE)
			{
				if (fDistAway <= g_vtActivationDistance.GetFloat())
				{
					SetTargetStringID(IDS_TARGET_TALK);
					return;
				}
			}
		}

		// This is the only thing we care about if we're dead or on a vehicle...(we care
		// if we're off a vehicle too)

		if (IsMultiplayerGame() && pFX && pFX->m_cs.bIsPlayer )
		{
			uint32 nId = pFX->m_cs.nClientID;
			CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr();
			CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId);

			if (pCI)
			{
				m_nString = 0;
				SAFE_STRCPY(m_szString,pCI->sName.c_str());

				if (IsTeamGameType())
				{
					m_nTargetTeam = pCI->nTeamID;
				}
			}
			return;
		}
	
		// All we care about if we're dead or on a vehicle is the Multiplayer check above...

		if (!bPlayersOnly)
		{
			if( (fDistAway <= g_vtTargetDistance.GetFloat()) && pFX )
			{
				// If a nameid was specified for the model display the name...

				uint16 nNameId = g_pModelButeMgr->GetModelNameId( pFX->m_cs.eModelId );
				if( nNameId != (uint16)-1 )
				{
					if( nNameId > 0 )
					{
						SetTargetStringID( nNameId );
						return;
					}

					// warn the player if we are pointing at a friend...
					if( pFX->m_cs.eCrosshairCharacterClass != BAD )
					{
						SetTargetStringID( IDS_TARGET_INNOCENT );
						return;
					}
				}
			}
		}
	}

	// All we care about if we're dead or on a vehicle is the above Multiplayer check...
	if (bPlayersOnly)
	{
		// Didn't see another player in Multiplayer, so we have no target...
		ClearTargetInfo();
		return;
	}


	//is this a searchable object?
	if (dwUserFlags & USRFLG_CAN_SEARCH && (fDistAway <= g_vtActivationDistance.GetFloat()))
	{
		m_bSearchTarget = true;
		m_ActivationData.m_nType = MID_ACTIVATE_SEARCH;
		SetTargetStringID(IDS_TARGET_SEARCH);
		
		uint8 nProgress = g_pPlayerMgr->GetSearcher()->GetMaxProgress();
		g_pPlayerStats->UpdateMaxProgress( nProgress );
		g_pPlayerStats->UpdateProgress( nProgress );
		g_pHUDMgr->QueueUpdate( kHUDProgressBar );

		return;

	}
	
	// See if this object is part of the activate object list with it's own string ID's...

	if( fDistAway <= g_vtActivationDistance.GetFloat() )
	{
		CActivateObjectHandler *pActivateObj = LTNULL;
		CActivateObjectHandler::ActivateObjList::const_iterator iter = CActivateObjectHandler::GetActivateObjectList().begin();
		while( iter != CActivateObjectHandler::GetActivateObjectList().end() )
		{
			pActivateObj = *iter;
			
			if( pActivateObj->GetHOBJECT() == m_hTarget )
			{
				ACTIVATETYPE *pType = g_pActivateTypeMgr->GetActivateType( pActivateObj->m_nId );
				if( pType )
				{
					// Set whether or not it's disabled and set the string based on the state...

					m_bCanActivate = !pActivateObj->m_bDisabled;
					uint32 dwStringID = pType->dwStateID[pActivateObj->m_eState];
					
					if( dwStringID != (uint32)-1 )
					{
						SetTargetStringID( dwStringID );
					}

					return;
				}
			}

			++iter;
		}
	}

	//can we pick up or activate it?
	if (dwUserFlags & USRFLG_CAN_ACTIVATE && (fDistAway <= g_vtActivationDistance.GetFloat()))
	{
		//special case for bombs to defuse
		CGadgetTargetFX* const pGTFX = (CGadgetTargetFX*)g_pGameClientShell->GetSFXMgr()->FindSpecialFX(SFX_GADGETTARGET_ID, m_hTarget);
		if (pGTFX)
		{
			GadgetTargetType eGadgetType = pGTFX->GetType();
			if (eBombable == eGadgetType)
			{
				// Can only defuse a bomb that doesn't belong to your team...
				
				if( IsTeamGameType() )
				{
					CLIENT_INFO *pLocalCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient();
					if( !pLocalCI )
						return;

					if( pGTFX->GetTeamID() != INVALID_TEAM )
					{
						if( pLocalCI->nTeamID == pGTFX->GetTeamID() )
						{
							m_bCanActivate = false;
						}
					}
				}

				SetTargetStringID(IDS_TARGET_DEFUSE);
				return;
			}
		}

		CPickupItemFX* const pFX = (CPickupItemFX*)g_pGameClientShell->GetSFXMgr()->FindSpecialFX(SFX_PICKUPITEM_ID, m_hTarget);

		// If this is a pickupitem, then display any team association it has.
		if( IsTeamGameType() && pFX )
		{
			m_nTargetTeam = pFX->GetTeamId( );
		}
		
		// If we're looking at a pickup, use the take string, otherwise it's just something to interact with.
		SetTargetStringID(pFX ? IDS_TARGET_TAKE : IDS_TARGET_USE);
		return;
	}

	// Are we looking at a doomsday piece...
	
	CDoomsdayPieceFX *pDDPiece = dynamic_cast<CDoomsdayPieceFX*>(g_pGameClientShell->GetSFXMgr()->FindSpecialFX( SFX_DOOMSDAYPIECE_ID, m_hTarget ));
	if( pDDPiece && (fDistAway <= g_vtActivationDistance.GetFloat()) )
	{
		m_bCanActivate = false;
		m_bMoveTarget = true;
	}
}
コード例 #5
0
ファイル: AutoTargetMgr.cpp プロジェクト: Arc0re/lithtech
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CAutoTargetMgr::GenerateCharArray()
//
//	PURPOSE:	Fill array with list of chars sorted by distance
//
// ----------------------------------------------------------------------- //
void CAutoTargetMgr::GenerateCharArray()
{
	//clear our target array
	m_Targets.resize(0);

	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();

	//step through the chars
	CSpecialFXList* const pCharList = psfxMgr->GetFXList(SFX_CHARACTER_ID);	
	int nNumSFX  = pCharList->GetSize();
	
	for (int nChar=0; nChar < nNumSFX; nChar++)
	{
		CCharacterFX* pChar = (CCharacterFX*)(*pCharList)[nChar];
		if (pChar)
		{
			if (pChar->m_cs.bIsPlayer)
			{
				//filter out local player
			    HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject();
			    if (hPlayerObj == pChar->GetServerObj())
					continue;
				if(pChar->IsPlayerDead())
					continue;

				//if this is a team game filter out our teammates
				if (GameModeMgr::Instance( ).m_grbUseTeams )
				{
					// Get the client information of the body and us.
					uint32 nId = pChar->m_cs.nClientID;
					CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr();
					CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId);
					CLIENT_INFO *pLocalCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient();

					// Only allow us to auto-target people on the other team.
					if( pCI && pLocalCI )
					{
						if (pCI->nTeamID == pLocalCI->nTeamID)
							continue;
					}

				}
			}
			else
			{
				// Check alignment of non-players
				if(pChar->m_cs.eCrosshairPlayerStance != kCharStance_Hate)
					continue;
			}

			//filter out anyone outside the cone
			LTVector vTargetPos;
			g_pLTClient->GetObjectPos(pChar->GetServerObj(), &vTargetPos);
			LTVector vOffset(0.0f,32.0f,0.0f);

			// we check both upper and lower parts of the body and if either is in the cone, we're good
			if (IsPointInCone( vTargetPos - vOffset) || IsPointInCone( vTargetPos + vOffset) )
			{
				// we only care about the n closest characters, so...
				// if the new one farther away than the n-th one, drop it, 
				//	otherwise drop the n-th one and insert the new one
			
				//step through the chars we already know about...
				CharFXArray::iterator iter = m_Targets.begin();
				bool bInserted = false;
				while (iter != m_Targets.end() && !bInserted)
				{
					//figure out how far away this one is
					CCharacterFX* pTestChar = (CCharacterFX*)(*iter);
					LTVector vTestPos;
					g_pLTClient->GetObjectPos(pTestChar->GetServerObj(), &vTestPos);
					float fTestDistSqr = m_vFirePos.DistSqr(vTestPos);

					//if this char is farther away than the one we're inserting
					if (fTestDistSqr > m_fRangeSqr)
					{
						//if our list is full, pop off the last one...
						if (m_Targets.size() >= MAX_AUTOTARGET_CHARACTERS)
							m_Targets.pop_back();

						m_Targets.insert(iter,pChar);
						bInserted = true;
					}

					iter++;
				}

				//if we haven't inseted it yet, and we have room, add it to the back
				if (!bInserted && m_Targets.size() < MAX_AUTOTARGET_CHARACTERS)
					m_Targets.push_back(pChar);
			}
		}

	}

}
コード例 #6
0
ファイル: TargetMgr.cpp プロジェクト: Arc0re/lithtech
void CTargetMgr::Update()
{
	// Do any necessary initialization...

	if (m_bFirstUpdate)
	{
		FirstUpdate();
		m_bFirstUpdate = false;
	}

	g_pPlayerStats->UpdateMaxProgress( 0 );
	g_pPlayerStats->UpdateProgress( 0 );

	// Start fresh
	ClearTargetInfo();

	//see what we've looking at
	float fDistAway = kMaxDistance;
	CheckForIntersect(fDistAway);
	m_fTargetRange = fDistAway;

	if (!m_hTarget) 
	{
		//nothing to see here
		SpecialMoveMgr::Instance().HandleLookedAt(NULL);
		return;
	}

	// If its a Character's hitbox, check the Character instead...
	CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromHitBox(m_hTarget);
	if (pCharacter)
	{
		m_hTarget = pCharacter->GetServerObj();
		m_ActivationData.m_hTarget = m_hTarget;
		if (!m_hTarget) return;
	}

	CLadderFX *pLadder = g_pGameClientShell->GetSFXMgr()->GetLadderFX(m_hTarget);
	if (pLadder && LadderMgr::Instance().CanReachLadder(pLadder))
	{
		m_ActivationData.m_hTarget = m_hTarget;
		m_ActivationData.m_nType = MID_ACTIVATE_LADDER;
		return;
	}

	CTurretFX *pTurret = g_pGameClientShell->GetSFXMgr( )->GetTurretFX( m_hTarget );
	if( pTurret && pTurret->CanActivate( ))
	{
		m_ActivationData.m_hTarget = m_hTarget;
		m_ActivationData.m_nType = MID_ACTIVATE_TURRET;
		return;
	}

	CSpecialMoveFX *pSpecialMove = g_pGameClientShell->GetSFXMgr()->GetSpecialMoveFX(m_hTarget);
	if (pSpecialMove)
	{
		SpecialMoveMgr::Instance().HandleLookedAt(pSpecialMove);
		if (SpecialMoveMgr::Instance().CanReach(pSpecialMove))
		{
			m_ActivationData.m_hTarget = m_hTarget;
			m_ActivationData.m_nType = MID_ACTIVATE_SPECIALMOVE;
			return;
		}
	}
	else
	{
		SpecialMoveMgr::Instance().HandleLookedAt(NULL);
	}

	if( m_ActivationData.m_hActivateSnd )
	{
		m_ActivationData.m_nType = MID_ACTIVATE_SURFACESND;
	}

	CClientWeapon* pCurrentWeapon = g_pPlayerMgr->GetClientWeaponMgr()->GetCurrentClientWeapon();

	uint32 dwUserFlags = 0;
	g_pCommonLT->GetObjectFlags(m_hTarget, OFT_User, dwUserFlags);

	// is this a person we can talk to?
	if(( !(dwUserFlags & USRFLG_CAN_ACTIVATE) && m_ActivationData.m_nType != MID_ACTIVATE_SURFACESND ) || (fDistAway > g_vtActivationDistance.GetFloat()) )
	{
		m_ActivationData.m_hTarget = NULL;
	}


	// If we're on a vehicle (or if we are dead) all we care about is other players in a multiplayer game...
	// Some vehicles (like the PlayerLure) let you activate, so we'll just check if the
	// vehicle will let us show a crosshair to see if we're on a "true" vehicle or not...

	// It would be great if we didn't have to do all these checks, but such is life...

	bool bPlayersOnly = !g_pPlayerMgr->IsPlayerAlive() || (g_pPlayerMgr->GetMoveMgr()->GetVehicleMgr()->CanShowCrosshair() ? false : true);

	//are we aiming at a person?
	if (dwUserFlags & USRFLG_CHARACTER)
	{
		CCharacterFX* const pFX = (CCharacterFX*)g_pGameClientShell->GetSFXMgr()->FindSpecialFX(SFX_CHARACTER_ID, m_hTarget);

		// All we care about if we're on a vehicle (or if we are dead) is the Multiplayer check below...

		if (!bPlayersOnly)
		{
			//display debug info if we have any 
			if( pFX && pFX->GetInfoString() && *pFX->GetInfoString() )
			{
				g_pHUDDebug->SetTargetDebugString(pFX->GetInfoString());
			}
			else
			{
				g_pHUDDebug->SetTargetDebugString(L"");
			}

			// is this a person we can talk to?
			if (dwUserFlags & USRFLG_CAN_ACTIVATE)
			{
				if (fDistAway <= g_vtActivationDistance.GetFloat())
				{
					// SetTargetStringID(IDS_TARGET_TALK);
					return;
				}
			}
		}

		// This is the only thing we care about if we're dead or on a vehicle...(we care
		// if we're off a vehicle too)

		if (IsMultiplayerGameClient() && pFX && pFX->m_cs.bIsPlayer )
		{
			uint32 nId = pFX->m_cs.nClientID;
			CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr();
			CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId);

			if (pCI)
			{
				m_szStringID = NULL;
				LTStrCpy(m_wszString, pCI->sName.c_str(), LTARRAYSIZE(m_wszString));

				if (GameModeMgr::Instance( ).m_grbUseTeams)
				{
					m_nTargetTeam = pCI->nTeamID;
				}
			}
			return;
		}

		// All we care about if we're dead or on a vehicle is the Multiplayer check above...

		if (!bPlayersOnly)
		{
			if(pFX)
			{
				if (fDistAway <= g_vtTargetDistance.GetFloat()) 
				{
					// If a nameid was specified for the model display the name...
					const char* szNameId = g_pModelsDB->GetModelNameId( pFX->m_cs.hModel );
					if( szNameId && (szNameId[0] != '\0') )
					{
						//SetTargetStringID( nNameId );
						return;
					}
				}
			}
		}
	}

	// See if this object is part of the activate object list with it's own string ID's...
	if( fDistAway <= g_vtActivationDistance.GetFloat() )
	{
		const CActivateObjectHandler *pActivateObj = CActivateObjectHandler::FindActivateObject( m_hTarget );
		if( pActivateObj )
		{
			// See whether or not it's disabled
			m_bCanActivate = !pActivateObj->m_bDisabled;

			// Fetch the proper string from the database depending on the state...
			HRECORD hRecord = DATABASE_CATEGORY( Activate ).GetRecordByIndex( pActivateObj->m_nId );
			HATTRIBUTE hStates = DATABASE_CATEGORY( Activate ).GETRECORDSTRUCT( hRecord, States );
			const char* pszStringID = DATABASE_CATEGORY( Activate ).GETSTRUCTATTRIB( States, hStates, pActivateObj->m_eState, HudText );
			if( !LTStrEmpty( pszStringID ) )
			{
				SetTargetStringID( pszStringID );
			}
			return;
		}
	}


	// All we care about if we're dead or on a vehicle is the above Multiplayer check...
	if (bPlayersOnly)
	{
		// Didn't see another player in Multiplayer, so we have no target...
		ClearTargetInfo();
		return;
	}

}
コード例 #7
0
ファイル: TriggerFX.cpp プロジェクト: Arc0re/lithtech
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 );	
			}
		}
	}
}