diff --git a/MTA10/core/CChat.cpp b/MTA10/core/CChat.cpp index f2e067a1925..8d7a886ca0e 100644 --- a/MTA10/core/CChat.cpp +++ b/MTA10/core/CChat.cpp @@ -124,6 +124,7 @@ void CChat::LoadCVars ( void ) CVARS_GET ( "chat_line_life", (unsigned int &)m_ulChatLineLife ); CVARS_GET ( "chat_line_fade_out", (unsigned int &)m_ulChatLineFadeOut ); CVARS_GET ( "chat_font", (unsigned int &)Font ); SetChatFont ( (eChatFont)Font ); + CVARS_GET ( "chat_autocomplete", m_bAutocomplete ); // Modify default chat box to be like 'Transparent' preset SString strFlags; @@ -596,9 +597,94 @@ bool CChat::CharacterKeyHandler ( CGUIKeyEventArgs KeyboardArgs ) m_fSmoothScrollResetTime = GetSecondCount (); break; } + case VK_TAB: + { + + if ( m_bAutocomplete && m_strInputText.size () > 0 ) + { + bool bSuccess = false; + + SString strCurrentInput = GetInputText (); + size_t iFound; + iFound = strCurrentInput.find_last_of ( " " ); + if ( iFound == std::string::npos ) + iFound = 0; + else + ++iFound; + + SString strPlayerNamePart = strCurrentInput.substr ( iFound ); + + CModManager* pModManager = CModManager::GetSingletonPtr (); + if ( pModManager && pModManager->GetCurrentMod () ) + { + //Create vector and get playernames from deathmatch module + std::vector vPlayerNames; + pModManager->GetCurrentMod ()->GetPlayerNames ( vPlayerNames ); + + for ( std::vector::iterator iter = vPlayerNames.begin (); + iter != vPlayerNames.end (); + ++iter ) + { + SString strPlayerName = *iter; + + // Check if there is another player after our last result + if ( m_strLastPlayerName.size () != 0 ) + { + if ( strPlayerName.CompareI ( m_strLastPlayerName ) ) { + m_strLastPlayerName.clear (); + if ( *iter == vPlayerNames.back () ) + { + CharacterKeyHandler ( KeyboardArgs ); + return true; + } + } + continue; + } + + // Already a part? + if ( m_strLastPlayerNamePart.size () != 0 ) + { + strPlayerNamePart = m_strLastPlayerNamePart; + } + + // Check namepart + if ( !strPlayerName.BeginsWith ( strPlayerNamePart ) ) + continue; + else + { + //Check size if it's ok, then output + SString strOutput = strCurrentInput.replace ( iFound, std::string::npos, strPlayerName ); + if ( MbUTF8ToUTF16 ( strOutput ).size () < CHAT_MAX_CHAT_LENGTH ) + { + bSuccess = true; + m_strLastPlayerNamePart = strPlayerNamePart; + m_strLastPlayerName = strPlayerName; + SetInputText ( strOutput ); + } + + break; + } + } + + // No success? Try again! + if ( !bSuccess ) + m_strLastPlayerName.clear (); + } + + } + break; + } default: { + // Clear last namepart when pressing letter + if (m_strLastPlayerNamePart.size() != 0) + m_strLastPlayerNamePart.clear(); + + // Clear last name when pressing letter + if (m_strLastPlayerName.size() != 0) + m_strLastPlayerName.clear(); + // If we haven't exceeded the maximum number of characters per chat message, append the char to the message and update the input control if ( MbUTF8ToUTF16(m_strInputText).size () < CHAT_MAX_CHAT_LENGTH ) { diff --git a/MTA10/core/CChat.h b/MTA10/core/CChat.h index 4a9ef8c2475..647d57ddeef 100644 --- a/MTA10/core/CChat.h +++ b/MTA10/core/CChat.h @@ -246,6 +246,8 @@ class CChat float m_fSmoothScrollResetTime; float m_fSmoothRepeatTimer; CChatInputLine m_InputLine; + SString m_strLastPlayerNamePart; + SString m_strLastPlayerName; CGUI* m_pManager; CGUIFont* m_pFont; @@ -295,6 +297,8 @@ class CChat CVector2D m_RenderTargetChatSize; int m_iReportCount; CTickCount m_lastRenderTargetCreationFail; + + bool m_bAutocomplete; }; #endif diff --git a/MTA10/core/CClientVariables.cpp b/MTA10/core/CClientVariables.cpp index eddc0cfb2d1..1a857b32272 100644 --- a/MTA10/core/CClientVariables.cpp +++ b/MTA10/core/CClientVariables.cpp @@ -285,6 +285,7 @@ void CClientVariables::LoadDefaults ( void ) DEFAULT ( "chat_line_life", 12000 ); // chatbox line life time DEFAULT ( "chat_line_fade_out", 3000 ); // chatbox line fade out time DEFAULT ( "chat_use_cegui", false ); // chatbox uses cegui + DEFAULT ( "chat_autocomplete", true ); // Enable autocomplete for nicknames in chatbox? DEFAULT ( "text_scale", 1.0f ); // text scale DEFAULT ( "invert_mouse", false ); // mouse inverting DEFAULT ( "fly_with_mouse", false ); // flying with mouse controls diff --git a/MTA10/core/CSettings.cpp b/MTA10/core/CSettings.cpp index 2b1ca53fc76..d8533faea92 100644 --- a/MTA10/core/CSettings.cpp +++ b/MTA10/core/CSettings.cpp @@ -1151,6 +1151,11 @@ void CSettings::CreateGUI ( void ) m_pChatCssBackground->SetPosition ( CVector2D ( 10.0f, 350.0f ) ); m_pChatCssBackground->GetPosition ( vecTemp ); m_pChatCssBackground->AutoSize ( NULL, 20.0f ); + + m_pChatAutocomplete = reinterpret_cast < CGUICheckBox* > ( pManager->CreateCheckBox ( pTabInterface, _( "Nickname autocomplete with TAB" ) ) ); + m_pChatAutocomplete->SetPosition ( CVector2D ( vecTemp.fX, vecTemp.fY + 20.0f ) ); + m_pChatAutocomplete->GetPosition ( vecTemp ); + m_pChatAutocomplete->AutoSize ( NULL, 20.0f ); } /** @@ -2976,6 +2981,7 @@ void CSettings::LoadData ( void ) CVARS_GET ( "chat_width", strVar ); m_pChatWidth->SetText ( strVar.c_str () ); CVARS_GET ( "chat_css_style_text", bVar ); m_pChatCssText->SetSelected ( bVar ); CVARS_GET ( "chat_css_style_background", bVar ); m_pChatCssBackground->SetSelected ( bVar ); + CVARS_GET ( "chat_autocomplete", bVar ); m_pChatAutocomplete->SetSelected ( bVar ); { int iVar; @@ -3276,6 +3282,7 @@ void CSettings::SaveData ( void ) CVARS_SET ( "chat_width", m_pChatWidth->GetText () ); CVARS_SET ( "chat_css_style_text", m_pChatCssText->GetSelected () ); CVARS_SET ( "chat_css_style_background", m_pChatCssBackground->GetSelected () ); + CVARS_SET ( "chat_autocomplete", m_pChatAutocomplete->GetSelected () ); CVARS_SET ( "chat_line_life", GetMilliseconds ( m_pChatLineLife ) ); CVARS_SET ( "chat_line_fade_out", GetMilliseconds ( m_pChatLineFadeout ) ); diff --git a/MTA10/core/CSettings.h b/MTA10/core/CSettings.h index 39395b1478b..0ed56fc9cda 100644 --- a/MTA10/core/CSettings.h +++ b/MTA10/core/CSettings.h @@ -321,6 +321,7 @@ class CSettings CGUIEdit* m_pChatWidth; CGUICheckBox* m_pChatCssBackground; + CGUICheckBox* m_pChatAutocomplete; CGUICheckBox* m_pChatCssText; CGUIEdit* m_pChatLineLife; CGUIEdit* m_pChatLineFadeout; diff --git a/MTA10/mods/deathmatch/CClient.cpp b/MTA10/mods/deathmatch/CClient.cpp index c5b9cec2de6..822eb0e59ba 100644 --- a/MTA10/mods/deathmatch/CClient.cpp +++ b/MTA10/mods/deathmatch/CClient.cpp @@ -297,3 +297,18 @@ bool CClient::HandleException ( CExceptionInformation* pExceptionInformation ) return true; #endif } + +void CClient::GetPlayerNames ( std::vector &vPlayerNames ) +{ + if ( g_pClientGame ) { + vPlayerNames.clear (); + for ( std::vector::const_iterator iter = g_pClientGame->GetPlayerManager ()->IterBegin (); + iter != g_pClientGame->GetPlayerManager ()->IterEnd (); + ++iter ) + { + CClientPlayer* pClient = *iter; + SString strPlayerName = pClient->GetNametagText (); + vPlayerNames.push_back ( strPlayerName ); + } + } +}; \ No newline at end of file diff --git a/MTA10/mods/deathmatch/CClient.h b/MTA10/mods/deathmatch/CClient.h index 009863140e3..a5938c839b8 100644 --- a/MTA10/mods/deathmatch/CClient.h +++ b/MTA10/mods/deathmatch/CClient.h @@ -37,6 +37,7 @@ class CClient : public CClientBase //bool ProcessInput ( CInputMessage* pInputMessage ); bool HandleException ( CExceptionInformation* pExceptionInformation ); + void GetPlayerNames ( std::vector &vPlayerNames ); }; #endif \ No newline at end of file diff --git a/MTA10/mods/shared_logic/CClientEntity.h b/MTA10/mods/shared_logic/CClientEntity.h index 600cd4b451a..2364a2906ed 100644 --- a/MTA10/mods/shared_logic/CClientEntity.h +++ b/MTA10/mods/shared_logic/CClientEntity.h @@ -187,7 +187,7 @@ class CClientEntity : public CClientEntityBase }; bool CanUpdateSync ( unsigned char ucRemote ); - inline const char* GetName ( void ) { return m_strName; } + inline SString GetName ( void ) { return m_strName; } inline void SetName ( const char* szName ) { m_strName.AssignLeft ( szName, MAX_ELEMENT_NAME_LENGTH ); } inline const char* GetTypeName ( void ) { return m_strTypeName; }; diff --git a/MTA10/sdk/core/CClientBase.h b/MTA10/sdk/core/CClientBase.h index c01988843cb..af5ed096862 100644 --- a/MTA10/sdk/core/CClientBase.h +++ b/MTA10/sdk/core/CClientBase.h @@ -32,6 +32,7 @@ class CClientBase //virtual bool ProcessInput ( CInputMessage* pInputMessage ) = 0 *TODO* virtual bool HandleException ( CExceptionInformation* pExceptionInformation ) = 0; + virtual void GetPlayerNames ( std::vector &vPlayerNames ) = 0; }; -#endif +#endif \ No newline at end of file