void CWeaponFX::PlayImpactDing() { if (!IsMultiplayerGame()) return; CCharacterFX* pCharFX = g_pGameClientShell->GetMoveMgr()->GetCharacterFX(); if (pCharFX) { pCharFX->PlayDingSound(); } }
void CPlayerViewAttachmentMgr::CreatePVAttachments( HOBJECT hPVObject ) { ASSERT( g_pPlayerMgr->GetMoveMgr() ); ASSERT( g_pModelButeMgr ); // No need to recrete the attachments if it's just being added to the same model... if( (m_hObject == hPVObject) && !m_lstPVAttachments.empty() ) return; // Start with an empty list... RemovePVAttachments(); // Get the clients CharacterFX so we know which model we are using... CCharacterFX* pCharFX = g_pPlayerMgr->GetMoveMgr()->GetCharacterFX(); if( !pCharFX ) return; // Check how many player view attachments we need to create... ModelId eModelId = pCharFX->GetModelId(); uint8 nNumPVAttachments = g_pModelButeMgr->GetNumPlayerViewAttachments( eModelId ); if( nNumPVAttachments == 0 ) return; uint32 dwFlags = 0; g_pCommonLT->GetObjectFlags( hPVObject, OFT_Flags, dwFlags ); // It must be a player view model... if( !(dwFlags & FLAG_REALLYCLOSE) ) return; // We need to create attachments so assign the model we are attaching to... m_hObject = hPVObject; const char *pszPVAttachmentPosition = LTNULL; const char *pszPVAttachment = LTNULL; for( uint8 i = 0; i < nNumPVAttachments; ++i ) { g_pModelButeMgr->GetPlayerViewAttachment( eModelId, i, pszPVAttachmentPosition, pszPVAttachment ); CreatePVAttachment( pszPVAttachmentPosition, pszPVAttachment ); } }
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; }
// ----------------------------------------------------------------------- // // // 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++; } }
CCharacterFX* CSFXMgr::GetCharacterFromHitBox(HOBJECT hHitBox) { 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) { if (pCharacterFX->GetHitBox() == hHitBox) { return pCharacterFX; } } } return NULL; }
static bool AutoTargetFilterFn(HOBJECT hTest, void *pUserData) { // Ignore objects that are invisible uint32 dwFlags; g_pCommonLT->GetObjectFlags(hTest, OFT_Flags, dwFlags); if (!(dwFlags & FLAG_VISIBLE)) { return false; } if(!(dwFlags & FLAG_RAYHIT)) { return false; } HOBJECT hClientHitBox = NULL; CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(g_pLTClient->GetClientObject()); if (pCharacter) { hClientHitBox = pCharacter->GetHitBox(); } // Okay, do normal tests... HOBJECT hFilterList[] = { g_pLTClient->GetClientObject(), g_pPlayerMgr->GetMoveMgr()->GetObject(), hClientHitBox, NULL }; if (!ObjListFilterFn(hTest, (void*) hFilterList)) { return false; } return true; }
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; }
void CClientMeleeCollisionController::HandleCollision(HOBJECT hTarget, HMODELNODE hNodeHit, EPhysicsGroup eHitPhysics, const LTVector& vPos, const LTVector& vDir) { // Check if the attack has been blocked via rigidbody... if (eHitPhysics == PhysicsUtilities::ePhysicsGroup_UserBlockMelee) { HandleBlocked(hTarget, vPos, vDir); return; } // Check if the attack has been blocked via forced blocking (what the AI does)... CCharacterFX* pTargetFX = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hTarget); if (pTargetFX && pTargetFX->IsBlocking()) { HandleBlocked(hTarget, vPos, vDir); return; } // Handle normal damage... CAutoMessage cMsg; cMsg.Writeuint8(MID_OBJECT_MESSAGE); cMsg.WriteObject(m_hObject); cMsg.Writeuint32(MID_MELEEATTACK); cMsg.WriteObject(hTarget); cMsg.Writeuint32(hNodeHit); cMsg.WriteLTVector(vPos); cMsg.WriteLTVector(vDir); cMsg.Writeint32(g_pGameClientShell->GetServerRealTimeMS()); g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED); //!!ARL: Maybe DisableCollisions for hTarget if they are blocking? // (to avoid the weirdness of taking damage but still blocking the attack) // For local player targets, send an AttackRecoil stimulus so a proper animation can be played. if (hTarget == g_pPlayerMgr->GetMoveMgr()->GetObject()) { CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromAttack"); } }
static bool ActivateFilterFn(HOBJECT hTest, void *pUserData) { // [KLS 6/26/02] - Make sure we filter out client related objects first... HOBJECT hClientHitBox = LTNULL; CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(g_pLTClient->GetClientObject()); if (pCharacter) { hClientHitBox = pCharacter->GetHitBox(); } HOBJECT hFilterList[] = { g_pLTClient->GetClientObject(), g_pPlayerMgr->GetMoveMgr()->GetObject(), hClientHitBox, LTNULL }; if (!ObjListFilterFn(hTest, (void*) hFilterList)) { return false; } // Always keep gadget targets... if (g_pPlayerMgr->GetTargetMgr()->IsGadgetActivatable(hTest)) { return true; } // Always keep our locked target... if (g_pPlayerMgr->GetTargetMgr()->GetLockedTarget() == hTest) { return true; } // Look to see if it is a DoomsDayPiece. This should take precedence over characters and bodies... CDoomsdayPieceFX *pDDPiece = dynamic_cast<CDoomsdayPieceFX*>(g_pGameClientShell->GetSFXMgr()->FindSpecialFX( SFX_DOOMSDAYPIECE_ID, hTest )); if( pDDPiece ) { // If the piece is planted on our teams bse we no longer care about it... if( pDDPiece->IsPlanted() && (pDDPiece->GetTeam() != INVALID_TEAM) ) { CLIENT_INFO *pLocalCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient(); if( !pLocalCI ) return false; if( pLocalCI->nTeamID == pDDPiece->GetTeam() ) { return false; } } return true; } // If it's a body, ignore it (we only care about its hit box) CBodyFX* pBody = g_pGameClientShell->GetSFXMgr()->GetBodyFX(hTest); if (pBody) { return false; } // If it's a hitbox associated with a body we care. pBody = g_pGameClientShell->GetSFXMgr()->GetBodyFromHitBox(hTest); if (pBody) { // Save body for later since it may overlap a higher priority object SetFallbackActivationObject(hTest, (IntersectQuery*)pUserData); return false; } // If it's a Character and it has a hitbox, ignore it (we only care about its hit box) pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hTest); if (pCharacter) { if (pCharacter->GetHitBox()) { return false; } // Save character for later if unconscious since it may overlap a // higher priority object if (pCharacter->IsUnconscious()) { SetFallbackActivationObject(hTest, (IntersectQuery*)pUserData); return false; } return true; // "Solid" object so we're done } // If it's a hitbox associated with a Character we care about it... pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromHitBox(hTest); if (pCharacter) { if (pCharacter->IsUnconscious()) { // Save character for later since it may overlap a higher priority object SetFallbackActivationObject(hTest, (IntersectQuery*)pUserData); return false; } return true; // "Solid" object so we're done } // Ignore non-solid objects that can't be activated... uint32 dwFlags; g_pCommonLT->GetObjectFlags(hTest, OFT_Flags, dwFlags); if (!(dwFlags & FLAG_SOLID)) { // This object is most likely a pickup of some type and it should // take priority over all the above objects types...however, since all // we can test are its flags we have to filter out the above objects // first (instead of testing for this type of object at the top of // the function ;) return IsUserFlagSet(hTest, (USRFLG_CAN_ACTIVATE | USRFLG_CAN_SEARCH)); } // Hit something solid, so we're done... return true; }
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; } }
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 ); } } } }
void CHUDScoreDiff::Update() { if (!IsMultiplayerGameClient()) return; if (GameModeMgr::Instance( ).m_grbEliminationWin) { CClientInfoMgr *pCIMgr = g_pGameClientShell->GetInterfaceMgr( )->GetClientInfoMgr(); if (!pCIMgr) return; CLIENT_INFO* pCI = pCIMgr->GetFirstClient(); int32 nEnemiesLeft = 0; while (pCI) { if (pCI && pCI != g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient()) { CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromClientID(pCI->nID); if (pCharacter && !pCharacter->IsPlayerDead() && !pCharacter->m_cs.bIsSpectating ) { if (GameModeMgr::Instance( ).m_grbUseTeams) { if (!pCIMgr->IsLocalTeam(pCI->nTeamID)) { ++nEnemiesLeft; } } else { ++nEnemiesLeft; } } } pCI = pCI->pNext; } wchar_t wsScore[16] = L""; FormatString("HUD_Score_Format",wsScore,LTARRAYSIZE(wsScore),nEnemiesLeft); m_Text.SetText(wsScore); m_Text.SetColor(m_cTextColor); } else { int32 nLocalScore = 0; int32 nOtherScore = 0; if (GameModeMgr::Instance( ).m_grbUseTeams) { uint8 nTeam = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalTeam(); CTeam* pTeam = CTeamMgr::Instance().GetTeam(nTeam); if (pTeam) { nLocalScore = pTeam->GetScore(); } nTeam = 1-nTeam; pTeam = CTeamMgr::Instance().GetTeam(nTeam); if (pTeam) { nOtherScore = pTeam->GetScore(); } } else { CLIENT_INFO* pCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient(); if (pCI) { nLocalScore = pCI->sScore.GetScore(); } pCI = g_pInterfaceMgr->GetClientInfoMgr()->GetFirstClient(); if (pCI && pCI == g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient()) { pCI = pCI->pNext; } if (pCI) { nOtherScore = pCI->sScore.GetScore(); } } wchar_t wsScore[16] = L""; int32 nDiff = (nLocalScore-nOtherScore); FormatString("HUD_Score_Format",wsScore,LTARRAYSIZE(wsScore),nDiff); if (nDiff > 0) { m_Text.SetColor(m_cWinningTextColor); FormatString("HUD_Score_Format_Advantage",wsScore,LTARRAYSIZE(wsScore),nDiff); } else if (nDiff == 0) { m_Text.SetColor(m_cTextColor); } else { m_Text.SetColor(m_cLosingTextColor); } m_Text.SetText(wsScore); } }
static bool ActivateFilterFn(HOBJECT hTest, void *pUserData) { // [KLS 6/26/02] - Make sure we filter out client related objects first... HOBJECT hClientHitBox = NULL; CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(g_pLTClient->GetClientObject()); if (pCharacter) { hClientHitBox = pCharacter->GetHitBox(); } HOBJECT hFilterList[] = { g_pLTClient->GetClientObject(), g_pPlayerMgr->GetMoveMgr()->GetObject(), hClientHitBox, NULL }; if (!ObjListFilterFn(hTest, (void*) hFilterList)) { return false; } // Always keep our locked target... if (g_pPlayerMgr->GetTargetMgr()->GetLockedTarget() == hTest) { return true; } // If it's a Character and it has a hitbox, ignore it (we only care about its hit box) pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hTest); if (pCharacter) { if (pCharacter->GetHitBox()) { return false; } /* // Save character for later if unconscious since it may overlap a // higher priority object if (pCharacter->IsUnconscious()) { SetFallbackActivationObject(hTest, (IntersectQuery*)pUserData); return false; } */ return true; // "Solid" object so we're done } // If it's a hitbox associated with a Character we care about it... pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromHitBox(hTest); if (pCharacter) { /* if (pCharacter->IsUnconscious()) { // Save character for later since it may overlap a higher priority object SetFallbackActivationObject(hTest, (IntersectQuery*)pUserData); return false; } */ return true; // "Solid" object so we're done } CLadderFX *pLadder = g_pGameClientShell->GetSFXMgr()->GetLadderFX(hTest); if (pLadder) { return true; } CTurretFX *pTurret = g_pGameClientShell->GetSFXMgr( )->GetTurretFX( hTest ); if( pTurret ) { return true; } CSpecialMoveFX *pSpecialMove = g_pGameClientShell->GetSFXMgr()->GetSpecialMoveFX(hTest); if (pSpecialMove) { return true; } // Ignore non-solid objects that can't be activated... uint32 dwFlags; g_pCommonLT->GetObjectFlags(hTest, OFT_Flags, dwFlags); if (!(dwFlags & FLAG_SOLID)) { // This object is most likely a pickup of some type and it should // take priority over all the above objects types...however, since all // we can test are its flags we have to filter out the above objects // first (instead of testing for this type of object at the top of // the function ;) return IsUserFlagSet(hTest, USRFLG_CAN_ACTIVATE ); } // Hit something solid, so we're done... return true; }
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; } }
void CHeadBobMgr::UpdateHeadBob() { CMoveMgr* pMoveMgr = g_pPlayerMgr->GetMoveMgr(); if (!pMoveMgr) return; LTBOOL bZoomed = g_pPlayerMgr->IsZoomed(); uint32 dwPlayerFlags = g_pPlayerMgr->GetPlayerFlags(); // This frame time is used since unlike ClientDE::GetFrameTime() the // max value is controlled by the game... LTFLOAT fFrameTime = g_pGameClientShell->GetFrameTime(); LTFLOAT fTime = g_pLTClient->GetTime(); LTBOOL bRunning = (LTBOOL) !!(dwPlayerFlags & BC_CFLG_RUN); LTFLOAT fMoveDist = pMoveMgr->GetVelocity().Mag() * fFrameTime; LTBOOL bFootstep = LTFALSE; LTBOOL bLeftFoot = LTFALSE; LTFLOAT fPace = 0.0f; if (pMoveMgr->GetVehicleMgr()->IsVehiclePhysics()) { fPace = MATH_CIRCLE * g_vtVehiclePaceAdjust.GetFloat(); } else if (bRunning) { fPace = MATH_CIRCLE * g_vtRunPaceAdjust.GetFloat(); } else { fPace = MATH_CIRCLE * g_vtWalkPaceAdjust.GetFloat(); } // Make sure bob phase and sway phase start at the right values... if (m_fBobAmp == 0.0f) { m_fBobPhase = 0.0f; m_fSwayPhase = 0.0f; } else // Normal processing... { // Bob phase should be between MATH_PI and MATH_CIRCLE so that the // sin(m_fBobPhase) is always between -1 and 0... m_fBobPhase += (fFrameTime * fPace); if (m_fBobPhase > MATH_CIRCLE) { m_fBobPhase -= MATH_PI; } else if (m_fBobPhase < MATH_PI) { m_fBobPhase += MATH_PI; } m_fSwayPhase += (fFrameTime * fPace); if (m_fSwayPhase > MATH_CIRCLE) { m_fSwayPhase -= MATH_CIRCLE; } } // See if it is time to play a footstep sound... if ((m_fSwayPhase > MATH_CIRCLE * 0.25f) && (m_fSwayPhase <= MATH_CIRCLE * 0.75f)) { if (s_bCanDoLeftFootstep) { bLeftFoot = LTFALSE; bFootstep = LTTRUE; s_bCanDoLeftFootstep = LTFALSE; s_bCanDoRightFootstep = LTTRUE; } } else if (m_fSwayPhase > MATH_CIRCLE * 0.75f) { if (s_bCanDoRightFootstep) { bLeftFoot = LTTRUE; bFootstep = LTTRUE; s_bCanDoLeftFootstep = LTTRUE; s_bCanDoRightFootstep = LTFALSE; } } LTBOOL bMoving = LTFALSE; LTFLOAT t; uint32 dwTestFlags = (BC_CFLG_MOVING); // | BC_CFLG_DUCK); if (fMoveDist > 0.1f) { bMoving = !!(dwPlayerFlags & dwTestFlags); } // If we're not moving, decay the head bob... if (!bMoving) { s_fBobStartTime = -1.0f; if (s_fBobDecayStartTime < 0.0f) { // Calculate what the current bobamp percent is... t = (1.0f - m_fBobAmp / g_vtMaxBobAmp.GetFloat()); s_fBobDecayStartTime = fTime - (g_vtBobDecayTime.GetFloat() * t); } LTFLOAT fDur = (fTime - s_fBobDecayStartTime); if (fDur <= g_vtBobDecayTime.GetFloat()) { t = fDur / g_vtBobDecayTime.GetFloat(); // 0 to 1 t = WaveFn_SlowOff(t); t = 1.0f - t; // 1 to 0 m_fBobAmp = t * g_vtMaxBobAmp.GetFloat(); if (m_fBobAmp < 0.0f) { m_fBobAmp = 0.0f; } } else { m_fBobAmp = 0.0f; } } else // We're moving... { s_fBobDecayStartTime = -1.0f; // If we just started bobing, ramp up the bob... if (s_fBobStartTime < 0.0f) { // Calculate what the current bobamp percent is... t = m_fBobAmp / g_vtMaxBobAmp.GetFloat(); s_fBobStartTime = fTime - (g_vtBobDecayTime.GetFloat() * t); } LTFLOAT fDur = (fTime - s_fBobStartTime); if (fDur <= g_vtBobDecayTime.GetFloat()) { t = fDur / g_vtBobDecayTime.GetFloat(); // 0 to 1 t = WaveFn_SlowOn(t); m_fBobAmp = t * g_vtMaxBobAmp.GetFloat(); if (m_fBobAmp > g_vtMaxBobAmp.GetFloat()) { m_fBobAmp = g_vtMaxBobAmp.GetFloat(); } } else { m_fBobAmp = g_vtMaxBobAmp.GetFloat(); } } // Update the bob... if (!bZoomed) { m_fBobHeight = g_vtBobV.GetFloat() * m_fBobAmp * (float)sin(m_fBobPhase); } // Update the weapon model bobbing... IClientWeaponBase *pClientWeapon = g_pPlayerMgr->GetCurrentClientWeapon(); if ( pClientWeapon && !bZoomed ) { LTFLOAT fSwayHeight = g_vtSwayV.GetFloat() * m_fBobAmp * (float)sin(m_fSwayPhase * 2); LTFLOAT fSwayWidth = g_vtSwayH.GetFloat() * m_fBobAmp * (float)sin(m_fSwayPhase - (MATH_PI/3)); // No weapon bob if vehicle mode... if (pMoveMgr->GetVehicleMgr()->IsVehiclePhysics()) { fSwayWidth = fSwayHeight = 0.0f; } fSwayHeight *= g_vtWeaponSway.GetFloat(); fSwayWidth *= g_vtWeaponSway.GetFloat(); pClientWeapon->UpdateBob(fSwayWidth, fSwayHeight); } // Update the head cant... if (!bZoomed && !pMoveMgr->GetVehicleMgr()->IsVehiclePhysics()) { LTFLOAT fRollAdjust = g_vtRollAdjust.GetFloat() * (float)sin(m_fSwayPhase); // Turn head bob up/down... fRollAdjust *= g_vtHeadBobAdjust.GetFloat(); if (m_fBobAmp == 0.0f) { fRollAdjust = 0.0f; } g_pPlayerMgr->SetRoll(fRollAdjust); } // Play foot step sounds at the appropriate time... if (bMoving && bFootstep) { CCharacterFX* pCharFX = pMoveMgr->GetCharacterFX(); if (pCharFX) { SurfaceType eSurf = pMoveMgr->GetStandingOnSurface(); eSurf = (eSurf == ST_UNKNOWN ? pCharFX->GetLastSurface() : eSurf); LTVector vPos; g_pLTClient->GetObjectPos(pMoveMgr->GetObject(), &vPos); pCharFX->PlayMovementSound(vPos, eSurf, bLeftFoot); } } }
// ----------------------------------------------------------------------- // // // 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); } } } }
void CHUDRadar::AddPlayer(HOBJECT hObj, uint32 nId) { if (!hObj) return; CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr(); CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId); HOBJECT hLocalObj = g_pLTClient->GetClientObject(); uint8 nTeamID = INVALID_TEAM; // Check for teams and only display players of the same team... if( IsTeamGameType() && hLocalObj != hObj) { CLIENT_INFO *pLocalCI = pCIMgr->GetLocalClient(); if( !pLocalCI || !pCI ) return; if( pLocalCI->nTeamID != pCI->nTeamID ) return; nTeamID = pCI->nTeamID; } bool bDead = false; if (hLocalObj != hObj) { AddObject( hObj, RADAR_PLAYER_ALIVE_TYPE, nTeamID ); } CCharacterFX *pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hObj); if (pCharacter && pCharacter->IsPlayerDead()) { bDead = true; } RadarPlayerList::iterator iter = m_Players.begin(); while (iter != m_Players.end() && ( (*iter)->hObj != hObj ) ) { iter++; } RADAR_PLAYER_OBJ* pPlayer = NULL; //new player... if (iter == m_Players.end()) { pPlayer = debug_new(RADAR_PLAYER_OBJ); m_Players.push_back(pPlayer); } else { pPlayer = (*iter); } pPlayer->nID = nId; pPlayer->hObj = hObj; if (!pPlayer->pName) { uint8 nFont = 0; CUIFont* pFont = g_pInterfaceResMgr->GetFont(nFont); pPlayer->pName = g_pFontManager->CreateFormattedPolyString(pFont,"",0.0f,0.0f); pPlayer->pName->SetAlignmentH(CUI_HALIGN_RIGHT); } if (pCI) { pPlayer->pName->SetText(pCI->sName.c_str()); } SetPlayerDead(hObj,bDead); UpdateNamePositions(); }
void CHUDScores::Update() { if( !m_bInitialized ) return; if( !m_bDraw ) return; // uint32 textCol = (m_bScreen ? m_cScreenTextColor : m_cTextColor); // uint32 playerTextCol = (m_bScreen ? m_cScreenPlayerTextColor : m_cPlayerTextColor); //for the screen mode scoreboard, don't update the text once we've drawn it if (m_bScreen && !m_bFirstScreenUpdate) return; m_bFirstScreenUpdate = false; if (GameModeMgr::Instance( ).m_grbUseTeams) { for( uint8 nTeamNum = 0; nTeamNum < kNumTeams; ++nTeamNum ) { uint8 team; if (g_pInterfaceMgr->GetClientInfoMgr()->IsLocalTeam(nTeamNum)) team = 0; else team = 1; CTeam* pTeam = CTeamMgr::Instance().GetTeam(nTeamNum); if (!pTeam) continue; wchar_t wszTmp[128]; LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%s : %d",pTeam->GetName(),pTeam->GetScore()); m_Team[team].SetString(wszTmp); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%s : %d", LoadString("IDS_ROUNDS"), pTeam->GetRoundScore( )); m_Rounds[team].SetString(wszTmp); m_Header[team].Show(true); } } else { m_Team[0].SetString(L""); m_Rounds[0].SetString(L""); m_Header[1].Show(false); } m_Server.SetColor(m_cTextColor); if ( !GameModeMgr::Instance( ).m_grwsSessionName.GetValue().empty()) { std::wstring wstr = GameModeMgr::Instance( ).m_grwsSessionName; if ( g_pClientConnectionMgr->IsConnectedToRemoteServer( )) { wstr += L" : "; wstr += MPA2W(g_pClientConnectionMgr->GetStartGameRequest( ).m_TCPAddress).c_str(); } m_Server.SetString(wstr.c_str()); } else { m_Server.SetString(L""); } // Update the round counter. m_RoundInfo.SetColor(m_cTextColor); wchar_t wszRound[32]; uint8 nCurrentRound = g_pClientConnectionMgr ? g_pClientConnectionMgr->GetCurrentRound() : 0; uint8 nNumRounds = GameModeMgr::Instance( ).m_grnNumRounds; FormatString( "HUD_SCORES_ROUNDINFO", wszRound, LTARRAYSIZE( wszRound ), nCurrentRound + 1, nNumRounds ); m_RoundInfo.SetString( wszRound ); CClientInfoMgr *pCIMgr = g_pGameClientShell->GetInterfaceMgr( )->GetClientInfoMgr(); if (!pCIMgr) return; CLIENT_INFO* pCI = pCIMgr->GetFirstClient(); int nTotal = 0; int count[kNumTeams] = {0,0}; wchar_t wszTmp[64] = L""; uint32 nHeight[kNumTeams]; nHeight[0] = m_Server.GetBaseHeight() + m_Header[0].GetBaseHeight() + m_Team[0].GetBaseHeight() + 24; nHeight[1] = m_Team[1].GetBaseHeight() + m_Header[1].GetBaseHeight() + 16; uint32 nLocalID = 0; g_pLTClient->GetLocalClientID (&nLocalID); while (pCI && (nTotal < kMaxPlayers)) { uint8 nTeam = 0; CCharacterFX* pCharacter = g_pGameClientShell->GetSFXMgr()->GetCharacterFromClientID(pCI->nID); if (GameModeMgr::Instance( ).m_grbUseTeams) { if (g_pInterfaceMgr->GetClientInfoMgr()->IsLocalTeam(pCI->nTeamID)) nTeam = 0; else nTeam = 1; } int ndx = count[nTeam]; if (nTeam < kNumTeams) { LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%s%s",pCI->sName.c_str( ), pCI->bIsAdmin ? L"[*]" : L"" ); m_Columns[nTeam][ndx].SetString( eColumnName, wszTmp ); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetScore()); m_Columns[nTeam][ndx].SetString( eColumnScore, wszTmp ); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetEventCount(CPlayerScore::eKill)); m_Columns[nTeam][ndx].SetString( eColumnKill, wszTmp ); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetEventCount(CPlayerScore::eDeath)); m_Columns[nTeam][ndx].SetString( eColumnDeath, wszTmp ); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetEventCount(CPlayerScore::eObjective)); m_Columns[nTeam][ndx].SetString( eColumnObjective, wszTmp ); if (GameModeMgr::Instance( ).m_grbUseTeams) { LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetEventCount(CPlayerScore::eTeamKill)); m_Columns[nTeam][ndx].SetString( eColumnTK, wszTmp ); m_Columns[nTeam][ndx].ShowColumn(eColumnTK, true); } else { m_Columns[nTeam][ndx].ShowColumn(eColumnTK, false); } LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->sScore.GetEventCount(CPlayerScore::eSuicide)); m_Columns[nTeam][ndx].SetString( eColumnSuicide, wszTmp ); LTSNPrintF(wszTmp,LTARRAYSIZE(wszTmp),L"%d",pCI->nPing); m_Columns[nTeam][ndx].SetString( eColumnPing, wszTmp ); if (nLocalID == pCI->nID) { if (!pCharacter || pCharacter->IsPlayerDead() || pCharacter->m_cs.bIsSpectating ) m_Columns[nTeam][ndx].SetColor(m_cPlayerDeadColor); else m_Columns[nTeam][ndx].SetColor(m_cPlayerTextColor); } else { if (!pCharacter || pCharacter->IsPlayerDead() || pCharacter->m_cs.bIsSpectating ) m_Columns[nTeam][ndx].SetColor(m_cDeadColor); else m_Columns[nTeam][ndx].SetColor(m_cTextColor); } m_Columns[nTeam][ndx].Show(true); nHeight[nTeam] += m_Columns[nTeam][ndx].GetBaseHeight(); } pCI = pCI->pNext; ++count[nTeam]; } for (uint8 team = 0; team < kNumTeams; team++) { m_Team[team].SetColor(m_cTextColor); m_Rounds[team].SetColor(m_cTextColor); m_Header[team].SetColor(m_cTextColor); nHeight[team] += 16; m_Frame[team].SetSize(LTVector2n(m_nFrameWidth,nHeight[team])); while (count[team] < kMaxPlayers) { m_Columns[team][count[team]].Show(false); ++count[team]; } LTVector2n pos = m_vBasePos; g_pInterfaceResMgr->ScaleScreenPos(pos); if (GameModeMgr::Instance( ).m_grbUseTeams && team > 0) { pos.y += nHeight[team-1] + 8; } UpdateTeamPos(team,pos); } m_SingleFrame.SetSize(LTVector2n(m_nFrameWidth,nHeight[0]+8)); }