void Fire::InitialUpdate(int nInfo) { if (nInfo == INITIALUPDATE_SAVEGAME) return; LTVector vPos; g_pLTServer->GetObjectPos(m_hObject, &vPos); g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, m_bOn ? USRFLG_VISIBLE : 0, FLAGMASK_ALL); // Tell the clients about the Fire... CAutoMessage cMsg; cMsg.Writeuint8(SFX_FIRE_ID); cMsg.Writefloat(m_fRadius); cMsg.Writefloat(m_fSoundRadius); cMsg.Writefloat(m_fLightRadius); cMsg.Writefloat(m_fLightPhase); cMsg.Writefloat(m_fLightFreq); cMsg.WriteLTVector(m_vLightOffset); cMsg.WriteLTVector(m_vLightColor); cMsg.Writeuint8(m_bSmoke); cMsg.Writeuint8(m_bLight); cMsg.Writeuint8(m_bSparks); cMsg.Writeuint8(m_bSound); cMsg.Writeuint8(m_bBlackSmoke); cMsg.Writeuint8(m_bSmokeOnly); g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read()); }
void Camera::HandleFOVMsg( HOBJECT hSender, const CParsedMsg &crParsedMsg ) { if( crParsedMsg.GetArgCount() >= 3 ) { m_fFovY = (float)atof( crParsedMsg.GetArg(1) ); m_fFovAspectScale = (float)atof( crParsedMsg.GetArg(2) ); float fT = 0.0f; if( crParsedMsg.GetArgCount() >= 4 ) { fT = (float)atof( crParsedMsg.GetArg(3) ); } CAutoMessage cMsg; cMsg.Writeuint8(MID_SFX_MESSAGE); cMsg.Writeuint8(SFX_CAMERA_ID); cMsg.WriteObject(m_hObject); cMsg.Writeuint8(CAMFX_FOV); cMsg.Writefloat(m_fFovY); cMsg.Writefloat(m_fFovAspectScale); cMsg.Writefloat(fT); // Send the message to all connected clients g_pLTServer->SendToClient(cMsg.Read(), NULL, MESSAGE_GUARANTEED); // Update the SpecialFX Message... CreateSFXMsg(); } }
void DisplayTimer::UpdateClients() { // Send message to clients telling them about the DisplayTimer... float fGameTimeEnd = g_pLTServer->GetTime( ) + m_Timer.GetCountdownTime( ); { // Set up the update message CAutoMessage cMsg; cMsg.Writeuint8(MID_SFX_MESSAGE); cMsg.Writeuint8(SFX_DISPLAYTIMER_ID); cMsg.WriteObject(m_hObject); cMsg.Writefloat(fGameTimeEnd); cMsg.Writeuint8((uint8)m_Timer.Paused()); cMsg.Writeuint8( m_nTeamId ); // Send the message to all connected clients g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED); } { CAutoMessage cMsg; cMsg.Writeuint8(SFX_DISPLAYTIMER_ID); cMsg.Writefloat( fGameTimeEnd ); cMsg.Writeuint8((uint8)m_Timer.Paused()); cMsg.Writeuint8( m_nTeamId ); // Make sure new clients will get the message g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read()); } }
void Camera::CreateSFXMsg() { CAutoMessage cMsg; cMsg.Writeuint8(SFX_CAMERA_ID); cMsg.Writeuint8((uint8)m_bAllowPlayerMovement); cMsg.Writeuint8((uint8)m_nCameraType); cMsg.Writeuint8((uint8)m_bIsListener); cMsg.Writefloat(m_fFovY); cMsg.Writefloat(m_fFovAspectScale); g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read()); }
void DecisionObject::Show(bool bShow, bool bForceShow) { if( m_bLock ) return; // Send message to clients telling them about the DecisionObject... CAutoMessage cMsg; cMsg.Writeuint8(MID_DECISION); m_bVisible = bShow; if (bShow) { cMsg.Writeuint8(LTTRUE); cMsg.Writeuint8( (bForceShow ? LTTRUE : LTFALSE) ); for (int i=0; i < MAX_DECISION_CHOICES; i++) { cMsg.Writeuint32(m_ChoiceData[i].nStringID); } cMsg.WriteObject(m_hObject); cMsg.Writefloat(m_fRadius); } else { cMsg.Writeuint8(LTFALSE); cMsg.WriteObject(m_hObject); } g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED); }
void CTronPlayerObj::HandleDamage(const DamageStruct& damage) { if ( WMGR_INVALID_ID != damage.nAmmoId ) { // hit by a weapon of some sort if ( IsDefending() ) { // send a message to the player detailing a successful block CAutoMessage cMsg; LTRESULT ltResult; cMsg.Writeuint8( MID_PROJECTILE ); // write the projectile message subtype cMsg.Writeuint8( MPROJ_BLOCKED ); // write the defense type cMsg.Writeuint8( m_cDefendType ); // write the defense percentage cMsg.Writefloat( GetDefensePercentage( &damage.vDir ) ); ltResult = g_pLTServer->SendToClient( cMsg.Read(), m_hClient, MESSAGE_GUARANTEED ); ASSERT( LT_OK == ltResult ); } } CPlayerObj::HandleDamage( damage ); }
bool ScmdServer_Impl::HandleListGameOptions( HCLIENT hClient, ILTMessage_Read& msg ) { ServerMissionSettings sms = g_pServerMissionMgr->GetServerSettings(); CAutoMessage cMsg; cMsg.Writeuint8( MID_SCMD ); cMsg.Writeuint8( kScmdCommandListGameOptions ); cMsg.Writeuint8( kScmdCommandStatusOk ); cMsg.Writeuint8( g_pGameServerShell->GetGameType( )); switch( g_pGameServerShell->GetGameType( )) { case eGameTypeDeathmatch: { cMsg.Writeuint8( sms.m_nRunSpeed ); cMsg.Writeuint8( sms.m_nScoreLimit ); cMsg.Writeuint8( sms.m_nTimeLimit ); cMsg.Writeuint8( sms.m_nRounds ); } break; case eGameTypeTeamDeathmatch: { cMsg.Writeuint8( sms.m_nRunSpeed ); cMsg.Writeuint8( sms.m_nScoreLimit ); cMsg.Writeuint8( sms.m_nTimeLimit ); cMsg.Writeuint8( sms.m_nRounds ); cMsg.Writebool( sms.m_bFriendlyFire) ; } break; case eGameTypeDoomsDay: { cMsg.Writeuint8( sms.m_nRunSpeed ); cMsg.Writeuint8( sms.m_nTimeLimit ); cMsg.Writeuint8( sms.m_nRounds ); cMsg.Writebool( sms.m_bFriendlyFire ); } break; case eGameTypeCooperative: { cMsg.Writebool( sms.m_bFriendlyFire) ; cMsg.Writeuint8( sms.m_nMPDifficulty ); cMsg.Writefloat( sms.m_fPlayerDiffFactor ); } break; default: { } break; } // Send the message. SendMessage( hClient, *cMsg ); return true; }
void SpecialMove::WriteSFXMsg(CAutoMessage& cMsg) { // Set our special effect message. cMsg.Writeuint8(GetSFXID()); cMsg.Writeuint32(m_eAnimation); cMsg.Writefloat(m_fActivateDist); cMsg.Writebool(m_bOn); cMsg.Writebool(m_bRadial); // Piggyback our Activate data. m_ActivateTypeHandler.WriteActivateTypeMsg(cMsg); }
// ----------------------------------------------------------------------- // // // ROUTINE: CTronPlayerObj::UpdateInterface // // PURPOSE: Tell the client of about any changes // // ----------------------------------------------------------------------- // void CTronPlayerObj::UpdateInterface( bool bForceUpdate ) { if ( !m_pPlayerAttachments ) return; if (!m_hClient || !g_pWeaponMgr) return; // See if the psets have changed... if(m_byPSets != m_byOldPSets) { m_byOldPSets = m_byPSets; CAutoMessage cMsg; cMsg.Writeuint8(MID_PLAYER_INFOCHANGE); cMsg.Writeuint8(IC_PSETS_ID); cMsg.Writeuint8(0); cMsg.Writeuint8(0); cMsg.Writefloat(m_byPSets); g_pLTServer->SendToClient(cMsg.Read(), m_hClient, MESSAGE_GUARANTEED); } // See if the build points have changed if(m_nBuildPoints != m_nOldBuildPoints) { m_nOldBuildPoints = m_nBuildPoints; CAutoMessage cMsg; cMsg.Writeuint8(MID_PLAYER_INFOCHANGE); cMsg.Writeuint8(IC_BUILD_POINTS_ID); cMsg.Writeuint8(0); cMsg.Writeuint8(0); cMsg.Writefloat((LTFLOAT)m_nBuildPoints); g_pLTServer->SendToClient(cMsg.Read(), m_hClient, MESSAGE_GUARANTEED); } // Call the base class CPlayerObj::UpdateInterface(bForceUpdate); }
bool ServerPhysicsCollisionMgr::HandleRigidBodyCollision( CollisionData& collisionData ) { if( !PhysicsCollisionMgr::HandleRigidBodyCollision( collisionData )) return false; // Check if this event needs to get sent to the client. if( collisionData.bSendToClient ) { CAutoMessage cMsg; cMsg.Writeuint8( MID_PHYSICSCOLLISION ); // We send the rigidbody values down to the client, even though // they can't be dereferenced. They will be used to // uniquely identify this collision event on the client. cMsg.Writeuint32(( uint32 )collisionData.hBodyA ); cMsg.Writeuint32(( uint32 )collisionData.hBodyB ); // Send the objects down if we had rigid bodies. We // can't get the objects without the rigid bodies, so // only sending them when we have non-null rigid bodies saves bandwidth. if( collisionData.hBodyA != INVALID_PHYSICS_RIGID_BODY ) cMsg.WriteObject( collisionData.hObjectA ); if( collisionData.hBodyB != INVALID_PHYSICS_RIGID_BODY ) cMsg.WriteObject( collisionData.hObjectB ); // We can write out 8bits of index here because we already // have a 255 limit on collisionproperties, since they must fit in the userflags. cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyA )); cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyB )); // Super fine resolution of the impulse isn't necessary // since the data tables are defined with integers. cMsg.Writefloat(collisionData.fImpulse); cMsg.WriteLTVector( collisionData.vCollisionPt ); cMsg.WriteLTVector( collisionData.vCollisionNormal ); // We're sending unguaranteed, since it's not essential the client is informed, // since it's just sounds and clientfx. g_pLTServer->SendToClient( cMsg.Read(), NULL, 0 ); } return true; }
void CTO2GameServerShell::Update(LTFLOAT timeElapsed) { // Update the main server first CGameServerShell::Update(timeElapsed); m_VersionMgr.Update(); if (!GetServerDir()) return; //if we're hosting LANOnly game, don't publish the server if( m_ServerGameOptions.m_bLANOnly ) return; // Are we still waiting? static std::string status; switch (GetServerDir()->GetCurStatus()) { case IServerDirectory::eStatus_Processing : status =""; break; case IServerDirectory::eStatus_Waiting : if (status.empty()) status = GetServerDir()->GetLastRequestResultString(); break; case IServerDirectory::eStatus_Error : { IServerDirectory::ERequest eErrorRequest = GetServerDir()->GetLastErrorRequest(); status = GetServerDir()->GetLastRequestResultString(); GetServerDir()->ProcessRequestList(); } break; }; // Publish the server if we've waited long enough since the last directory update uint32 nCurTime = (uint32)GetTickCount(); if ((m_nLastPublishTime == 0) || ((nCurTime - m_nLastPublishTime) > k_nRepublishDelay)) { status = ""; m_nLastPublishTime = nCurTime; uint32 nMax = 0; g_pLTServer->GetMaxConnections(nMax); // If not run by a dedicated server, we need to add one connection // for the local host. if( !m_ServerGameOptions.m_bDedicated ) nMax++; GetServerDir()->SetActivePeer(0); CAutoMessage cMsg; // Update the summary info cMsg.WriteString(GetHostName()); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Name, *cMsg.Read()); char fname[_MAX_FNAME] = ""; _splitpath( GetCurLevel(), NULL, NULL, fname, NULL ); // Update the summary info cMsg.WriteString(g_pVersionMgr->GetBuild()); cMsg.WriteString( fname ); cMsg.Writeuint8(GetNumPlayers()); cMsg.Writeuint8(nMax); cMsg.Writebool(m_ServerGameOptions.m_bUsePassword); cMsg.Writeuint8((uint8)GetGameType()); cMsg.WriteString( m_ServerGameOptions.m_sModName.c_str() ); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Summary, *cMsg.Read()); // Update the details ServerMissionSettings sms = g_pServerMissionMgr->GetServerSettings(); cMsg.Writebool(sms.m_bUseSkills); cMsg.Writebool(sms.m_bFriendlyFire); cMsg.Writeuint8(sms.m_nMPDifficulty); cMsg.Writefloat(sms.m_fPlayerDiffFactor); CPlayerObj* pPlayer = GetFirstNetPlayer(); while (pPlayer) { //has player info cMsg.Writebool(true); cMsg.WriteString(pPlayer->GetNetUniqueName()); cMsg.Writeuint16( Min( GetPlayerPing(pPlayer), ( uint32 )65535 )); pPlayer = GetNextNetPlayer(); }; //end of player info cMsg.Writebool(false); cMsg.Writeuint8(sms.m_nRunSpeed); cMsg.Writeuint8(sms.m_nScoreLimit); cMsg.Writeuint8(sms.m_nTimeLimit); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Details, *cMsg.Read()); // Update the port char aHostAddr[16]; uint16 nHostPort; g_pLTServer->GetTcpIpAddress(aHostAddr, sizeof(aHostAddr), nHostPort); cMsg.Writeuint16(nHostPort); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Port, *cMsg.Read()); // Tell serverdir again about info, but in service specific manner. PeerInfo_Service_Titan peerInfo; peerInfo.m_sHostName = GetHostName( ); peerInfo.m_sCurWorld = fname; peerInfo.m_nCurNumPlayers = GetNumPlayers( ); peerInfo.m_nMaxNumPlayers = nMax; peerInfo.m_bUsePassword = m_ServerGameOptions.m_bUsePassword; peerInfo.m_sGameType = GameTypeToString( GetGameType( )); peerInfo.m_nScoreLimit = sms.m_nScoreLimit; peerInfo.m_nTimeLimit = sms.m_nTimeLimit; PeerInfo_Service_Titan::Player player; CPlayerObj::PlayerObjList::const_iterator iter = CPlayerObj::GetPlayerObjList( ).begin( ); while( iter != CPlayerObj::GetPlayerObjList( ).end( )) { CPlayerObj* pPlayerObj = *iter; player.m_sName = pPlayerObj->GetNetUniqueName( ); player.m_nScore = pPlayerObj->GetPlayerScore()->GetScore( ); float fPing; g_pLTServer->GetClientPing( pPlayerObj->GetClient( ), fPing ); player.m_nPing = ( uint16 )( fPing + 0.5f ); peerInfo.m_PlayerList.push_back( player ); iter++; } cMsg.Writeuint32(( uint32 )&peerInfo ); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Service, *cMsg.Read()); // Tell the world about me... GetServerDir()->QueueRequest(IServerDirectory::eRequest_Publish_Server); } }
void ModItem::PickedUp(ILTMessage_Read *pMsg) { // Did we really pick it up? bool bPickedUp = (pMsg ? pMsg->Readbool() : true); bool bDisplaMsg = (pMsg ? pMsg->Readbool() : true); // If we were touched by a player, our m_hPlayerObj data member will be // set. Send a message to that player's client letting it know that an // item has been picked up... if (m_hPlayerObj) { CPlayerObj* pPlayer = (CPlayerObj*) g_pLTServer->HandleToObject(m_hPlayerObj); if (pPlayer && !pPlayer->IsDead()) { HCLIENT hClient = pPlayer->GetClient(); if (hClient) { CAutoMessage cMsg; cMsg.Writeuint8(MID_PLAYER_INFOCHANGE); cMsg.Writeuint8(IC_MOD_PICKUP_ID); cMsg.Writeuint8((uint8)bPickedUp); cMsg.Writeuint8(m_nModId); cMsg.Writefloat(bDisplaMsg ? 1.0f : 0.0f); g_pLTServer->SendToClient(cMsg.Read(), hClient, MESSAGE_GUARANTEED); } } } if (bPickedUp) { PickupItem::PickedUp(pMsg); if( m_bRespawn ) { MOD const *pMod = g_pWeaponMgr->GetMod( m_nModId ); if( !pMod ) return; // Change the skins and renderstyles to the waiting to respawn files... ObjectCreateStruct ocs; pMod->blrRespawnWaitSkins.CopyList( 0, ocs.m_SkinNames[0], MAX_CS_FILENAME_LEN + 1 ); pMod->blrRespawnWaitRenderStyles.CopyList( 0, ocs.m_RenderStyleNames[0], MAX_CS_FILENAME_LEN + 1 ); if( pMod->blrRespawnWaitRenderStyles.GetNumItems() < 1 ) LTStrCpy( ocs.m_RenderStyleNames[0], s_szDefaultRS, ARRAY_LEN( s_szDefaultRS )); g_pCommonLT->SetObjectFilenames( m_hObject, &ocs ); // Stop playing PowerupFX and play RespawnWaitFX... SetClientFX( pMod->szRespawnWaitFX ); // Set our visibility... g_pCommonLT->SetObjectFlags( m_hObject, OFT_Flags, pMod->bRespawnWaitVisible ? FLAG_VISIBLE : 0, FLAG_VISIBLE ); g_pCommonLT->SetObjectFlags( m_hObject, OFT_Flags2, pMod->bRespawnWaitTranslucent ? FLAG2_FORCETRANSLUCENT : 0, FLAG2_FORCETRANSLUCENT ); } } }
bool ScmdServer_Impl::HandleSetGameOption( HCLIENT hClient, ILTMessage_Read& msg ) { bool bOk = true; // Get the game option they are setting. uint8 nGameOption = msg.Readuint8( ); // Read in the value. char szVal[256]; msg.ReadString( szVal, ARRAY_LEN( szVal )); ServerMissionSettings sms = g_pServerMissionMgr->GetServerSettings(); switch( g_pGameServerShell->GetGameType( )) { case eGameTypeDeathmatch: { switch( nGameOption ) { // Runspeed. case 0: { SetGameOption( sms.m_nRunSpeed, atoi( szVal ), 100, 150 ); } break; // Score limit. case 1: { SetGameOption( sms.m_nScoreLimit, atoi( szVal ), 0, 255 ); } break; // Time limit. case 2: { SetGameOption( sms.m_nTimeLimit, atoi( szVal ), 0, 255 ); } break; // Rounds. case 3: { SetGameOption( sms.m_nRounds, atoi( szVal ), 1, 255 ); } break; default: { bOk = false; } break; } } break; case eGameTypeTeamDeathmatch: { switch( nGameOption ) { // Runspeed. case 0: { SetGameOption( sms.m_nRunSpeed, atoi( szVal ), 100, 150 ); } break; // Score limit. case 1: { SetGameOption( sms.m_nScoreLimit, atoi( szVal ), 0, 255 ); } break; // Time limit. case 2: { SetGameOption( sms.m_nTimeLimit, atoi( szVal ), 0, 255 ); } break; // Rounds. case 3: { SetGameOption( sms.m_nRounds, atoi( szVal ), 1, 255 ); } break; // Friendly fire. case 4: { SetGameOption( sms.m_bFriendlyFire, ( bool )( !!atoi( szVal )), false, true ); } break; default: { bOk = false; } break; } } break; case eGameTypeDoomsDay: { switch( nGameOption ) { // Runspeed. case 0: { SetGameOption( sms.m_nRunSpeed, atoi( szVal ), 100, 150 ); } break; // Time limit. case 1: { SetGameOption( sms.m_nTimeLimit, atoi( szVal ), 0, 255 ); } break; // Rounds. case 2: { SetGameOption( sms.m_nRounds, atoi( szVal ), 1, 255 ); } break; // Friendly fire. case 3: { SetGameOption( sms.m_bFriendlyFire, ( bool )( !!atoi( szVal )), false, true ); } break; default: { bOk = false; } break; } } break; case eGameTypeCooperative: { switch( nGameOption ) { // Friendly fire. case 0: { SetGameOption( sms.m_bFriendlyFire, ( bool )( !!atoi( szVal )), false, true ); } break; // mp difficulty. case 1: { SetGameOption( sms.m_nMPDifficulty, atoi( szVal ), 0, 255 ); } break; // player diff factor. case 2: { SetGameOption( sms.m_fPlayerDiffFactor, ( float )atof( szVal ), 0.0f, 20.0f ); } break; default: { bOk = false; } break; } } break; default: { bOk = false; } break; } // We need to tell the host client about the new settings. if( bOk ) { // Record any changes. g_pServerMissionMgr->SetServerSettings(sms); // Try to find a local host if one exists. HCLIENT hHost = g_pLTServer->GetNextClient( NULL ); while( hHost ) { uint32 nClientInfoFlags = g_pLTServer->GetClientInfoFlags( hHost ); if( nClientInfoFlags & CIF_LOCAL ) { break; } hHost = g_pLTServer->GetNextClient( hHost ); } // If we have a host, tell them about the new settings. if( hHost ) { CAutoMessage cMsg; cMsg.Writeuint8( MID_MULTIPLAYER_OPTIONS ); cMsg.Writeuint8( sms.m_nRunSpeed); cMsg.Writeuint8( sms.m_nScoreLimit); cMsg.Writeuint8( sms.m_nTimeLimit); cMsg.Writeuint8( sms.m_nRounds); cMsg.Writebool( sms.m_bFriendlyFire); cMsg.Writeuint8( sms.m_nMPDifficulty); cMsg.Writefloat( sms.m_fPlayerDiffFactor); g_pLTServer->SendToClient( cMsg.Read( ), hHost, MESSAGE_GUARANTEED ); } } SendStatusMessage( hClient, kScmdCommandSetGameOption, ( bOk ) ? kScmdCommandStatusOk : kScmdCommandStatusFailed ); return true; }
void CSearcher::Update( ) { // Are we actually searching something if( !m_bSearching || !m_hTargetObj ) { return; } HOBJECT hTarget = m_hTargetObj; if (m_hTargetHitBox) hTarget = m_hTargetHitBox; HOBJECT hObj = g_pPlayerMgr->GetTargetMgr()->GetLockedTarget(); bool bLookingAtTarget = (hObj == hTarget); bool bInRange = (g_pPlayerMgr->GetTargetMgr()->IsTargetInRange()); float fSearchSkillEffect = g_pPlayerStats->GetSkillModifier(SKL_SEARCH,SearchModifiers::eSearchSpeed); m_fTimer -= g_pLTClient->GetFrameTime() * fSearchSkillEffect; if (m_fTimer < 0.0f) m_fTimer = 0.0f; bool bButtonDown = !!g_pLTClient->IsCommandOn( COMMAND_ID_ACTIVATE); // Do we still meet the requirements for searching? if( m_fTimer <= 0.0f || !bButtonDown || !bLookingAtTarget || !bInRange ) { // Send message to target with the amount of time left... CAutoMessage cMsg; cMsg.Writeuint8( MID_SEARCH ); cMsg.WriteObject( m_hTargetObj ); cMsg.Writefloat( m_fTimer); g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED ); // Stop searching... m_bSearching = false; m_hTargetObj = LTNULL; m_hTargetHitBox = LTNULL; g_pPlayerMgr->GetTargetMgr()->LockTarget(NULL); // Let the progress bar hide it's self... if( !bButtonDown || !bLookingAtTarget || !bInRange ) { m_bShowTimeBar = false; g_pPlayerStats->UpdateProgress( 0 ); g_pHUDMgr->QueueUpdate( kHUDProgressBar ); } } // Get the percentage of searching we have done uint8 nMaxProgress = GetMaxProgress(); uint8 nVal = uint8( ((m_fRemainingTime+m_fTimer) / m_fTotalTime) * nMaxProgress ); // Update the meter... if( m_bShowTimeBar ) { // Show the progress bar... g_pPlayerStats->UpdateMaxProgress( g_vtProgressBarScaleToSkills.GetFloat() > 1.0f ? 100 : nMaxProgress ); g_pPlayerStats->UpdateProgress( nVal ); g_pHUDMgr->QueueUpdate( kHUDProgressBar ); } if (!nVal) { g_pClientSoundMgr->PlaySoundLocal("interface\\snd\\SearchComplete.wav", SOUNDPRIORITY_MISC_MEDIUM); } }