From da2ff32c72c7b7572a3918e8047d2e62113082c1 Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Thu, 10 Sep 2026 00:50:18 +0300 Subject: [PATCH 1/4] Add chat preview in settings --- Client/core/CChat.cpp | 20 +++- Client/core/CChat.h | 3 + Client/core/CGUI.cpp | 57 ++++++++- Client/core/CGUI.h | 17 +-- Client/core/CSettings.cpp | 240 ++++++++++++++++++++++++++++++-------- Client/core/CSettings.h | 54 +++++++-- 6 files changed, 321 insertions(+), 70 deletions(-) diff --git a/Client/core/CChat.cpp b/Client/core/CChat.cpp index 4182d279469..8150427d886 100644 --- a/Client/core/CChat.cpp +++ b/Client/core/CChat.cpp @@ -45,6 +45,7 @@ CChat::CChat(CGUI* pManager, const CVector2D& vecPosition) m_bVisible = false; m_bInputBlocked = false; m_bInputVisible = false; + m_bInputPreview = false; m_pFont = m_pManager->GetClearFont(); m_pDXFont = NULL; SetDxFont(g_pCore->GetGraphics()->GetFont()); @@ -146,6 +147,9 @@ void CChat::LoadCVars() CVARS_GET("chat_position_horizontal", (unsigned int&)m_ePositionHorizontal); CVARS_GET("chat_position_vertical", (unsigned int&)m_ePositionVertical); CVARS_GET("chat_text_alignment", (unsigned int&)m_eTextAlign); + + if (m_bInputPreview) + SetInputText(m_strInputText.c_str()); } // @@ -381,7 +385,7 @@ void CChat::DrawInputLine(bool bUsingOutline) } } - if (m_bInputVisible) + if (m_bInputVisible || m_bInputPreview) { float fLineDifference = CChat::GetFontHeight(m_vecScale.fY); bool bInputShadow = (m_InputColor.A * m_fInputBackgroundAlpha == 0.f) && !bUsingOutline; @@ -479,7 +483,7 @@ void CChat::UpdateSmoothScroll(float* pfPixelScroll, int* piLineScroll) // // Also update input background alpha // - fTarget = (m_bInputVisible) ? 1.0f : 0.0f; + fTarget = (m_bInputVisible || m_bInputPreview) ? 1.0f : 0.0f; fMaxAmount = fDeltaSeconds * 5.0f; // 0.2 seconds fade time m_fInputBackgroundAlpha += Clamp(-fMaxAmount, fTarget - m_fInputBackgroundAlpha, fMaxAmount); } @@ -857,6 +861,15 @@ void CChat::SetInputVisible(bool bVisible) m_bInputVisible = bVisible; } +void CChat::SetInputPreview(const char* szText) +{ + m_bInputPreview = (szText != nullptr); + if (m_bInputPreview) + SetInputText(szText); + else + ClearInput(); +} + void CChat::SetNumLines(unsigned int uiNumLines) { if (uiNumLines <= CHAT_MAX_LINES) @@ -1318,6 +1331,9 @@ void CChatInputLine::Draw(CVector2D& position, unsigned char alpha, bool shadow, if (g_pChat->m_InputTextColor.A > 0 && m_Sections.size() > 0) { + for (auto& section : m_Sections) + section.SetColor(g_pChat->m_InputTextColor); + m_Sections[0].Draw(CVector2D(position.fX + m_Prefix.GetWidth(), position.fY), g_pChat->m_InputTextColor.A, shadow, outline, renderBounds); float lineDifference = CChat::GetFontHeight(g_pChat->m_vecScale.fY); diff --git a/Client/core/CChat.h b/Client/core/CChat.h index 1aa79c2a834..a3f22147fa5 100644 --- a/Client/core/CChat.h +++ b/Client/core/CChat.h @@ -173,6 +173,8 @@ class CChat bool IsInputVisible() const { return !m_bInputBlocked && m_bInputVisible; } void SetInputVisible(bool bVisible); + void SetInputPreview(const char* szText); + bool CanTakeInput() { return !CLocalGUI::GetSingleton().GetConsole()->IsVisible() && IsInputVisible(); }; void ResetHistoryChanges(); @@ -270,6 +272,7 @@ class CChat bool m_bVisible; bool m_bInputBlocked; bool m_bInputVisible; + bool m_bInputPreview; int m_iScrollingBack; // Non zero if currently scrolling back float m_fCssStyleOverrideAlpha; // For fading out 'CssStyle' effect. (When entering text or scrolling back) float m_fBackgroundAlpha; diff --git a/Client/core/CGUI.cpp b/Client/core/CGUI.cpp index e007e24fca6..5e99819f26e 100644 --- a/Client/core/CGUI.cpp +++ b/Client/core/CGUI.cpp @@ -482,11 +482,52 @@ void CLocalGUI::Draw() // Update mainmenu stuff m_pMainMenu->Update(); - // If we're ingame, make sure the chatbox is drawn - bool bChatVisible = - (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_bChatboxVisible && !CCore::GetSingleton().IsOfflineMod()); - if (m_pChat->IsVisible() != bChatVisible) - m_pChat->SetVisible(bChatVisible, !bChatVisible); + // If we're ingame, make sure the chatbox is drawn. Also show it as a preview while the chatbox settings are open (Interface tab), both in the main menu and in-game, so its appearance can be adjusted without having to join a server. + bool bIsIngame = systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && !CCore::GetSingleton().IsOfflineMod(); + bool bChatPreview = m_pMainMenu->GetSettingsWindow()->IsChatTabVisible(); + bool bChatVisible = (bIsIngame && m_bChatboxVisible) || bChatPreview; + + bool bChatInputBlocked = !bChatVisible || bChatPreview; + if (m_pChat->IsVisible() != bChatVisible || m_pChat->IsInputBlocked() != bChatInputBlocked) + m_pChat->SetVisible(bChatVisible, bChatInputBlocked); + + if (bChatPreview && !bIsIngame) + { + const unsigned int uiRevision = CCore::GetSingleton().GetCVars()->GetRevision(); + if (!m_bChatPreviewActive || uiRevision != m_uiChatPreviewRevision) + { + m_uiChatPreviewRevision = uiRevision; + m_pChat->Clear(); + m_pChat->Output("Multi Theft Auto: What more could you want? Multi Theft Auto provides the best online Grand Theft Auto experience there is."); + m_pChat->Output( + "Multi Theft Auto: If you've played Grand Theft Auto online in the past, you'll know that the accuracy of the reproduction of other player's " + "actions often leaves a lot to be desired. This is a hard thing to get perfect, but Multi Theft Auto has the best GTA synchronization out " + "there " + "and it's getting better all the time! Want to shoot someone's limbs one by one? MTA makes that possible!"); + m_pChat->Output( + "Multi Theft Auto: Online games are all about their community, and Multi Theft Auto has a great community! We've got a great forum where you " + "can " + "get support for any problems you have playing MTA, get help with scripting problems or just hang out and chat. We also run a special site for " + "downloading game modes and maps that members of the community have created."); + m_bChatPreviewActive = true; + } + } + else if (!bChatPreview && m_bChatPreviewActive) + { + m_pChat->Clear(); + m_bChatPreviewActive = false; + } + + if (bChatPreview && !m_bChatInputPreviewActive) + { + m_pChat->SetInputPreview("Your message here..."); + m_bChatInputPreviewActive = true; + } + else if (!bChatPreview && m_bChatInputPreviewActive) + { + m_pChat->SetInputPreview(nullptr); + m_bChatInputPreviewActive = false; + } bool bDebugVisible = (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_pDebugViewVisible && !CCore::GetSingleton().IsOfflineMod()); if (m_pDebugView->IsVisible() != bDebugVisible) @@ -496,7 +537,8 @@ void CLocalGUI::Draw() UpdateCursor(); // Draw the chat - m_pChat->Draw(true, true); + if (!bChatPreview) + m_pChat->Draw(true, true); // Draw the debugger m_pDebugView->Draw(true, false); @@ -516,6 +558,9 @@ void CLocalGUI::Draw() bDelayedFrame = true; } } + + if (bChatPreview) + m_pChat->Draw(true, true); } void CLocalGUI::Invalidate() diff --git a/Client/core/CGUI.h b/Client/core/CGUI.h index 11ab607d958..cfdc3f3495a 100644 --- a/Client/core/CGUI.h +++ b/Client/core/CGUI.h @@ -121,13 +121,16 @@ class CLocalGUI : public CSingleton CGUILabel* m_pLabelVersionTag; - bool m_bForceCursorVisible; - bool m_bChatboxVisible; - bool m_bChatboxInputBlocked; - bool m_pDebugViewVisible; - bool m_bGUIHasInput; - int m_uiActiveCompositionSize; - POINT m_StoredMousePosition; + bool m_bForceCursorVisible; + bool m_bChatboxVisible; + bool m_bChatPreviewActive = false; + bool m_bChatInputPreviewActive = false; + unsigned int m_uiChatPreviewRevision = 0; + bool m_bChatboxInputBlocked; + bool m_pDebugViewVisible; + bool m_bGUIHasInput; + int m_uiActiveCompositionSize; + POINT m_StoredMousePosition; int m_LastSettingsRevision; // the revision number the last time we saw the skin change SString m_LastSkinName; diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index d956181d5ca..047ac38ee06 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -2168,6 +2168,9 @@ void CSettings::Update() m_dwFrameCount++; UpdateCaptureAxis(); + + if (IsChatTabVisible()) + LiveUpdateChatSettings(); } void CSettings::UpdateAudioTab() @@ -3199,6 +3202,7 @@ void CSettings::CreateInterfaceTabGUI() m_pChatHorizontalCombo->AddItem(_("Right"))->SetData((void*)Chat::Position::Horizontal::RIGHT); m_pChatHorizontalCombo->SetReadOnly(true); m_pChatHorizontalCombo->SetSelectedItemByIndex(0); + m_pChatHorizontalCombo->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnChatHorizontalComboChanged, this)); pLabel = reinterpret_cast(pManager->CreateLabel(pTabLayout, strVertical)); pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); @@ -3213,6 +3217,7 @@ void CSettings::CreateInterfaceTabGUI() m_pChatVerticalCombo->AddItem(_("Bottom"))->SetData((void*)Chat::Position::Vertical::BOTTOM); m_pChatVerticalCombo->SetReadOnly(true); m_pChatVerticalCombo->SetSelectedItemByIndex(0); + m_pChatVerticalCombo->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnChatVerticalComboChanged, this)); pLabel = reinterpret_cast(pManager->CreateLabel(pTabLayout, strTextAlign)); pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); @@ -3226,6 +3231,7 @@ void CSettings::CreateInterfaceTabGUI() m_pChatTextAlignCombo->AddItem(_("Right"))->SetData((void*)Chat::Text::Align::RIGHT); m_pChatTextAlignCombo->SetReadOnly(true); m_pChatTextAlignCombo->SetSelectedItemByIndex(0); + m_pChatTextAlignCombo->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnChatTextAlignComboChanged, this)); pLabel = reinterpret_cast(pManager->CreateLabel(pTabLayout, strXOffset)); pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); @@ -3879,6 +3885,11 @@ bool CSettings::IsVisible() return m_pWindow->IsVisible(); } +bool CSettings::IsChatTabVisible() +{ + return IsVisible() && m_pTabs->IsTabSelected(m_pTabInterface); +} + void CSettings::SetIsModLoaded(bool bLoaded) { m_bIsModLoaded = bLoaded; @@ -3929,6 +3940,8 @@ bool CSettings::OnCancelButtonClick(CGUIElement* pElement) CVARS_SET("mtavolume", m_fOldMTAVolume); CVARS_SET("voicevolume", m_fOldVoiceVolume); + RestoreChatSettings(); + // restore old audio mute settings CVARS_SET("mute_master_when_minimized", m_bOldMuteMaster); CVARS_SET("mute_radio_when_minimized", m_bOldMuteRadio); @@ -4248,21 +4261,26 @@ void CSettings::LoadData() if (iVar > Chat::Position::Horizontal::RIGHT) iVar = Chat::Position::Horizontal::LEFT; m_pChatHorizontalCombo->SetSelectedItemByIndex(iVar); + m_iChatHorizontalValue = iVar; CVARS_GET("chat_position_vertical", iVar); if (iVar > Chat::Position::Vertical::BOTTOM) iVar = Chat::Position::Vertical::TOP; m_pChatVerticalCombo->SetSelectedItemByIndex(iVar); + m_iChatVerticalValue = iVar; CVARS_GET("chat_text_alignment", iVar); if (iVar > Chat::Text::Align::RIGHT) iVar = Chat::Text::Align::LEFT; m_pChatTextAlignCombo->SetSelectedItemByIndex(iVar); + m_iChatTextAlignValue = iVar; CVARS_GET("chat_position_offset_x", strVar); m_pChatOffsetX->SetText(strVar.c_str()); CVARS_GET("chat_position_offset_y", strVar); m_pChatOffsetY->SetText(strVar.c_str()); + SnapshotChatSettings(); + // Interface CVARS_GET("server_can_flash_window", bVar); m_pFlashWindow->SetSelected(bVar); @@ -4675,47 +4693,7 @@ void CSettings::SaveData() } // Chat - SaveChatColor(Chat::ColorType::BG, "chat_color"); - SaveChatColor(Chat::ColorType::TEXT, "chat_text_color"); - SaveChatColor(Chat::ColorType::INPUT_BG, "chat_input_color"); - SaveChatColor(Chat::ColorType::INPUT_TEXT, "chat_input_text_color"); - for (int iFont = 0; iFont < Chat::ColorType::MAX; iFont++) - { - if (m_pRadioChatFont[iFont]->GetSelected()) - { - CVARS_SET("chat_font", iFont); - break; - } - } - - strVar = m_pChatScaleX->GetText() + " " + m_pChatScaleY->GetText(); - CVARS_SET("chat_scale", strVar); - CVARS_SET("chat_lines", m_pChatLines->GetText()); - 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_nickcompletion", m_pChatNickCompletion->GetSelected()); - CVARS_SET("chat_text_outline", m_pChatTextBlackOutline->GetSelected()); - CVARS_SET("chat_line_life", GetMilliseconds(m_pChatLineLife)); - CVARS_SET("chat_line_fade_out", GetMilliseconds(m_pChatLineFadeout)); - - CVARS_SET("chat_position_offset_x", m_pChatOffsetX->GetText()); - CVARS_SET("chat_position_offset_y", m_pChatOffsetY->GetText()); - if (CGUIListItem* pSelected = m_pChatHorizontalCombo->GetSelectedItem()) - { - int iSelected = (int)pSelected->GetData(); - CVARS_SET("chat_position_horizontal", iSelected); - } - if (CGUIListItem* pSelected = m_pChatVerticalCombo->GetSelectedItem()) - { - int iSelected = (int)pSelected->GetData(); - CVARS_SET("chat_position_vertical", iSelected); - } - if (CGUIListItem* pSelected = m_pChatTextAlignCombo->GetSelectedItem()) - { - int iSelected = (int)pSelected->GetData(); - CVARS_SET("chat_text_alignment", iSelected); - } + SaveChatSettings(); // Interface CVARS_SET("server_can_flash_window", m_pFlashWindow->GetSelected()); @@ -5014,12 +4992,13 @@ void CSettings::SaveChatColor(eChatColorType eType, const char* szCVar) CColor CSettings::GetChatColorValues(eChatColorType eType) { - // Retrieve the color according to the scrollbar values + // Retrieve the color according to the scrollbar values (rounded, so saving an unchanged + // colour round-trips exactly instead of drifting by one step each time) CColor pColor; - pColor.R = m_pChatRed[eType]->GetScrollPosition() * 255; - pColor.G = m_pChatGreen[eType]->GetScrollPosition() * 255; - pColor.B = m_pChatBlue[eType]->GetScrollPosition() * 255; - pColor.A = m_pChatAlpha[eType]->GetScrollPosition() * 255; + pColor.R = static_cast(m_pChatRed[eType]->GetScrollPosition() * 255.0f + 0.5f); + pColor.G = static_cast(m_pChatGreen[eType]->GetScrollPosition() * 255.0f + 0.5f); + pColor.B = static_cast(m_pChatBlue[eType]->GetScrollPosition() * 255.0f + 0.5f); + pColor.A = static_cast(m_pChatAlpha[eType]->GetScrollPosition() * 255.0f + 0.5f); return pColor; } @@ -5032,6 +5011,175 @@ void CSettings::SetChatColorValues(eChatColorType eType, CColor pColor) m_pChatAlpha[eType]->SetScrollPosition((float)pColor.A / 255.0f); } +void CSettings::SaveChatSettings() +{ + SaveChatColor(Chat::ColorType::BG, "chat_color"); + SaveChatColor(Chat::ColorType::TEXT, "chat_text_color"); + SaveChatColor(Chat::ColorType::INPUT_BG, "chat_input_color"); + SaveChatColor(Chat::ColorType::INPUT_TEXT, "chat_input_text_color"); + for (int iFont = 0; iFont < Chat::Font::MAX; iFont++) + { + if (m_pRadioChatFont[iFont]->GetSelected()) + { + CVARS_SET("chat_font", iFont); + break; + } + } + + SString strVar = m_pChatScaleX->GetText() + " " + m_pChatScaleY->GetText(); + CVARS_SET("chat_scale", strVar); + CVARS_SET("chat_lines", m_pChatLines->GetText()); + 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_nickcompletion", m_pChatNickCompletion->GetSelected()); + CVARS_SET("chat_text_outline", m_pChatTextBlackOutline->GetSelected()); + CVARS_SET("chat_line_life", GetMilliseconds(m_pChatLineLife)); + CVARS_SET("chat_line_fade_out", GetMilliseconds(m_pChatLineFadeout)); + + CVARS_SET("chat_position_offset_x", m_pChatOffsetX->GetText()); + CVARS_SET("chat_position_offset_y", m_pChatOffsetY->GetText()); + + CVARS_SET("chat_position_horizontal", m_iChatHorizontalValue); + CVARS_SET("chat_position_vertical", m_iChatVerticalValue); + CVARS_SET("chat_text_alignment", m_iChatTextAlignValue); +} + +SString CSettings::GetChatSettingsSignature() +{ + SString strSignature; + + for (int iColor = 0; iColor < Chat::ColorType::MAX; iColor++) + { + const CColor color = GetChatColorValues(static_cast(iColor)); + strSignature += SString("%d,%d,%d,%d|", color.R, color.G, color.B, color.A); + } + + for (int iFont = 0; iFont < Chat::Font::MAX; iFont++) + strSignature += m_pRadioChatFont[iFont]->GetSelected() ? "1" : "0"; + + strSignature += "|" + m_pChatLines->GetText(); + strSignature += "|" + m_pChatScaleX->GetText(); + strSignature += "|" + m_pChatScaleY->GetText(); + strSignature += "|" + m_pChatWidth->GetText(); + + strSignature += SString("|%d|%d|%d|%d", m_pChatCssText->GetSelected(), m_pChatCssBackground->GetSelected(), m_pChatNickCompletion->GetSelected(), + m_pChatTextBlackOutline->GetSelected()); + + strSignature += "|" + m_pChatLineLife->GetText(); + strSignature += "|" + m_pChatLineFadeout->GetText(); + strSignature += "|" + m_pChatOffsetX->GetText(); + strSignature += "|" + m_pChatOffsetY->GetText(); + + strSignature += SString("|%d", m_iChatHorizontalValue); + strSignature += SString("|%d", m_iChatVerticalValue); + strSignature += SString("|%d", m_iChatTextAlignValue); + + return strSignature; +} + +bool CSettings::OnChatHorizontalComboChanged(CGUIElement* pElement) +{ + if (CGUIListItem* pSelected = m_pChatHorizontalCombo->GetSelectedItem()) + m_iChatHorizontalValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; +} + +bool CSettings::OnChatVerticalComboChanged(CGUIElement* pElement) +{ + if (CGUIListItem* pSelected = m_pChatVerticalCombo->GetSelectedItem()) + m_iChatVerticalValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; +} + +bool CSettings::OnChatTextAlignComboChanged(CGUIElement* pElement) +{ + if (CGUIListItem* pSelected = m_pChatTextAlignCombo->GetSelectedItem()) + m_iChatTextAlignValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; +} + +void CSettings::LiveUpdateChatSettings() +{ + SString strSignature = GetChatSettingsSignature(); + if (strSignature != m_strChatSettingsSignature) + { + m_strChatSettingsSignature = strSignature; + SaveChatSettings(); + } +} + +void CSettings::SnapshotChatSettings() +{ + std::string strVar; + CVARS_GET("chat_color", strVar); + m_strOldChatColor = strVar; + CVARS_GET("chat_text_color", strVar); + m_strOldChatTextColor = strVar; + CVARS_GET("chat_input_color", strVar); + m_strOldChatInputColor = strVar; + CVARS_GET("chat_input_text_color", strVar); + m_strOldChatInputTextColor = strVar; + CVARS_GET("chat_font", strVar); + m_strOldChatFont = strVar; + CVARS_GET("chat_lines", strVar); + m_strOldChatLines = strVar; + CVARS_GET("chat_scale", strVar); + m_strOldChatScale = strVar; + CVARS_GET("chat_width", strVar); + m_strOldChatWidth = strVar; + CVARS_GET("chat_css_style_text", strVar); + m_strOldChatCssStyleText = strVar; + CVARS_GET("chat_css_style_background", strVar); + m_strOldChatCssStyleBackground = strVar; + CVARS_GET("chat_nickcompletion", strVar); + m_strOldChatNickCompletion = strVar; + CVARS_GET("chat_text_outline", strVar); + m_strOldChatTextOutline = strVar; + CVARS_GET("chat_line_life", strVar); + m_strOldChatLineLife = strVar; + CVARS_GET("chat_line_fade_out", strVar); + m_strOldChatLineFadeOut = strVar; + CVARS_GET("chat_position_horizontal", strVar); + m_strOldChatPositionHorizontal = strVar; + CVARS_GET("chat_position_vertical", strVar); + m_strOldChatPositionVertical = strVar; + CVARS_GET("chat_text_alignment", strVar); + m_strOldChatTextAlignment = strVar; + CVARS_GET("chat_position_offset_x", strVar); + m_strOldChatPositionOffsetX = strVar; + CVARS_GET("chat_position_offset_y", strVar); + m_strOldChatPositionOffsetY = strVar; + + m_strChatSettingsSignature.clear(); +} + +void CSettings::RestoreChatSettings() +{ + CVARS_SET("chat_color", m_strOldChatColor); + CVARS_SET("chat_text_color", m_strOldChatTextColor); + CVARS_SET("chat_input_color", m_strOldChatInputColor); + CVARS_SET("chat_input_text_color", m_strOldChatInputTextColor); + CVARS_SET("chat_font", m_strOldChatFont); + CVARS_SET("chat_lines", m_strOldChatLines); + CVARS_SET("chat_scale", m_strOldChatScale); + CVARS_SET("chat_width", m_strOldChatWidth); + CVARS_SET("chat_css_style_text", m_strOldChatCssStyleText); + CVARS_SET("chat_css_style_background", m_strOldChatCssStyleBackground); + CVARS_SET("chat_nickcompletion", m_strOldChatNickCompletion); + CVARS_SET("chat_text_outline", m_strOldChatTextOutline); + CVARS_SET("chat_line_life", m_strOldChatLineLife); + CVARS_SET("chat_line_fade_out", m_strOldChatLineFadeOut); + CVARS_SET("chat_position_horizontal", m_strOldChatPositionHorizontal); + CVARS_SET("chat_position_vertical", m_strOldChatPositionVertical); + CVARS_SET("chat_text_alignment", m_strOldChatTextAlignment); + CVARS_SET("chat_position_offset_x", m_strOldChatPositionOffsetX); + CVARS_SET("chat_position_offset_y", m_strOldChatPositionOffsetY); +} + void CSettings::LoadChatPresets() { CXMLFile* pPresetsFile = CCore::GetSingleton().GetXML()->CreateXML(CalcMTASAPath(CHAT_PRESETS_PATH)); diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 864feadb727..3b0e5cf49a1 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -91,6 +91,7 @@ class CSettings void SetVisible(bool bVisible); bool IsVisible(); + bool IsChatTabVisible(); void SetIsModLoaded(bool bLoaded); @@ -352,6 +353,33 @@ class CSettings CGUICheckBox* m_pChatTextBlackOutline; CGUIEdit* m_pChatLineLife; CGUIEdit* m_pChatLineFadeout; + + SString m_strOldChatColor; + SString m_strOldChatTextColor; + SString m_strOldChatInputColor; + SString m_strOldChatInputTextColor; + SString m_strOldChatFont; + SString m_strOldChatLines; + SString m_strOldChatScale; + SString m_strOldChatWidth; + SString m_strOldChatCssStyleText; + SString m_strOldChatCssStyleBackground; + SString m_strOldChatNickCompletion; + SString m_strOldChatTextOutline; + SString m_strOldChatLineLife; + SString m_strOldChatLineFadeOut; + SString m_strOldChatPositionHorizontal; + SString m_strOldChatPositionVertical; + SString m_strOldChatTextAlignment; + SString m_strOldChatPositionOffsetX; + SString m_strOldChatPositionOffsetY; + + int m_iChatHorizontalValue = -1; + int m_iChatVerticalValue = -1; + int m_iChatTextAlignValue = -1; + + SString m_strChatSettingsSignature; + CGUICheckBox* m_pFlashWindow; CGUICheckBox* m_pTrayBalloon; @@ -419,6 +447,9 @@ class CSettings bool OnChatGreenChanged(CGUIElement* pElement); bool OnChatBlueChanged(CGUIElement* pElement); bool OnChatAlphaChanged(CGUIElement* pElement); + bool OnChatHorizontalComboChanged(CGUIElement* pElement); + bool OnChatVerticalComboChanged(CGUIElement* pElement); + bool OnChatTextAlignComboChanged(CGUIElement* pElement); bool OnUpdateButtonClick(CGUIElement* pElement); bool OnCachePathShowButtonClick(CGUIElement* pElement); bool OnMouseSensitivityChanged(CGUIElement* pElement); @@ -469,15 +500,20 @@ class CSettings void LoadSkins(); - void LoadChatPresets(); - void CreateChatColorTab(eChatColorType eType, const char* szName, CGUITabPanel* pParent); - void LoadChatColorFromCVar(eChatColorType eType, const char* szCVar); - void LoadChatColorFromString(eChatColorType eType, const std::string& strColor); - void SaveChatColor(eChatColorType eType, const char* szCVar); - CColor GetChatColorValues(eChatColorType eType); - void SetChatColorValues(eChatColorType eType, CColor pColor); - int GetMilliseconds(CGUIEdit* pEdit); - void SetMilliseconds(CGUIEdit* pEdit, int milliseconds); + void LoadChatPresets(); + void CreateChatColorTab(eChatColorType eType, const char* szName, CGUITabPanel* pParent); + void LoadChatColorFromCVar(eChatColorType eType, const char* szCVar); + void LoadChatColorFromString(eChatColorType eType, const std::string& strColor); + void SaveChatColor(eChatColorType eType, const char* szCVar); + CColor GetChatColorValues(eChatColorType eType); + void SetChatColorValues(eChatColorType eType, CColor pColor); + void SaveChatSettings(); + SString GetChatSettingsSignature(); + void LiveUpdateChatSettings(); + void SnapshotChatSettings(); + void RestoreChatSettings(); + int GetMilliseconds(CGUIEdit* pEdit); + void SetMilliseconds(CGUIEdit* pEdit, int milliseconds); void ResetGTAVolume(); void SetRadioVolume(float fVolume); From 4ed3ce389fa2ed0a2dedd59ec70628812821dbc1 Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Thu, 10 Sep 2026 01:41:05 +0300 Subject: [PATCH 2/4] Important Commit --- Client/core/CChat.cpp | 43 ++++++++++++++++- Client/core/CChat.h | 2 +- Client/core/CConsole.cpp | 14 ++++++ Client/core/CConsole.h | 1 + Client/core/CGUI.cpp | 99 +++++++++++++++++++++++++++------------ Client/core/CSettings.cpp | 7 +++ Client/core/CSettings.h | 1 + 7 files changed, 135 insertions(+), 32 deletions(-) diff --git a/Client/core/CChat.cpp b/Client/core/CChat.cpp index 8150427d886..c68c7a4107a 100644 --- a/Client/core/CChat.cpp +++ b/Client/core/CChat.cpp @@ -155,8 +155,27 @@ void CChat::LoadCVars() // // Draw // -void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) +void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClipRect) { + auto SetScissor = [](bool bEnabled, const CRect2D* pRect) + { + IDirect3DDevice9* pDevice = g_pCore->GetGraphics()->GetDevice(); + if (bEnabled) + { + RECT rect; + rect.left = static_cast(std::max(0.0f, pRect->fX1)); + rect.top = static_cast(std::max(0.0f, pRect->fY1)); + rect.right = static_cast(std::max(0.0f, pRect->fX2)); + rect.bottom = static_cast(std::max(0.0f, pRect->fY2)); + pDevice->SetScissorRect(&rect); + pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + } + else + { + pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + } + }; + // Are we visible and is input blocked? if (!m_bVisible && m_bInputBlocked) return; @@ -170,7 +189,11 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) } bool bUsingOutline = m_bTextBlackOutline && bAllowOutline && bUseCacheTexture; + if (pClipRect) + SetScissor(true, pClipRect); DrawInputLine(bUsingOutline); + if (pClipRect) + SetScissor(false, nullptr); if (m_bInputVisible) { @@ -185,9 +208,13 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) if (!m_bVisible) return; - // Get drawList for the chat box text + // Get drawList for the chat box text. The background box is rendered inside GetDrawList, so it must be scissored as well, otherwise it would cover the settings window and the text drawn by the other clipped draw calls SDrawList drawList; + if (pClipRect) + SetScissor(true, pClipRect); GetDrawList(drawList, bUsingOutline); + if (pClipRect) + SetScissor(false, nullptr); // Calc some size info CVector2D chatTopLeft(drawList.renderBounds.fX1, drawList.renderBounds.fY1); @@ -198,7 +225,11 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) // If we are not using a cache texture, just render the text directly to the screen if (!bUseCacheTexture) { + if (pClipRect) + SetScissor(true, pClipRect); DrawDrawList(drawList, chatTopLeft); + if (pClipRect) + SetScissor(false, nullptr); return; } @@ -238,7 +269,11 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) if (!m_pCacheTexture) { drawList.bOutline = false; // Outline too slow without cache texture + if (pClipRect) + SetScissor(true, pClipRect); DrawDrawList(drawList, chatTopLeft); + if (pClipRect) + SetScissor(false, nullptr); return; } @@ -259,9 +294,13 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) } // Draw the cache texture + if (pClipRect) + SetScissor(true, pClipRect); pGraphics->SetBlendMode(EBlendMode::ADD); pGraphics->DrawTexture(m_pCacheTexture, chatTopLeft.fX, chatTopLeft.fY); pGraphics->SetBlendMode(EBlendMode::BLEND); + if (pClipRect) + SetScissor(false, nullptr); } // diff --git a/Client/core/CChat.h b/Client/core/CChat.h index a3f22147fa5..7beff1c245a 100644 --- a/Client/core/CChat.h +++ b/Client/core/CChat.h @@ -160,7 +160,7 @@ class CChat CChat(CGUI* pManager, const CVector2D& vecPosition); virtual ~CChat(); - virtual void Draw(bool bUseCacheTexture, bool bAllowOutline); + virtual void Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClipRect = nullptr); virtual void Output(const char* szText, bool bColorCoded = true); void Clear(); void ClearInput(); diff --git a/Client/core/CConsole.cpp b/Client/core/CConsole.cpp index 9350863a9f1..9d85ca612aa 100644 --- a/Client/core/CConsole.cpp +++ b/Client/core/CConsole.cpp @@ -462,6 +462,20 @@ CVector2D CConsole::GetPosition() return CVector2D(); } +void CConsole::GetWindowRect(CRect2D& outRect) +{ + if (m_pWindow) + { + CVector2D vecPosition = m_pWindow->GetPosition(false); + CVector2D vecSize = m_pWindow->GetSize(false); + outRect = CRect2D(vecPosition.fX, vecPosition.fY, vecPosition.fX + vecSize.fX, vecPosition.fY + vecSize.fY); + } + else + { + outRect = CRect2D(); + } +} + void CConsole::SetPosition(CVector2D& vecPosition) { if (m_pWindow) diff --git a/Client/core/CConsole.h b/Client/core/CConsole.h index 4b11422ecac..9d6fbd99709 100644 --- a/Client/core/CConsole.h +++ b/Client/core/CConsole.h @@ -52,6 +52,7 @@ class CConsole : public CConsoleInterface void ResetAutoCompleteMatch(); CVector2D GetPosition(); + void GetWindowRect(CRect2D& outRect); void SetPosition(CVector2D& vecPosition); CVector2D GetSize(); diff --git a/Client/core/CGUI.cpp b/Client/core/CGUI.cpp index 5e99819f26e..c0715392ccb 100644 --- a/Client/core/CGUI.cpp +++ b/Client/core/CGUI.cpp @@ -482,7 +482,8 @@ void CLocalGUI::Draw() // Update mainmenu stuff m_pMainMenu->Update(); - // If we're ingame, make sure the chatbox is drawn. Also show it as a preview while the chatbox settings are open (Interface tab), both in the main menu and in-game, so its appearance can be adjusted without having to join a server. + // If we're ingame, make sure the chatbox is drawn. Also show it as a preview while the chatbox settings are open (Interface tab), so its appearance can be + // adjusted without having to join a server. bool bIsIngame = systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && !CCore::GetSingleton().IsOfflineMod(); bool bChatPreview = m_pMainMenu->GetSettingsWindow()->IsChatTabVisible(); bool bChatVisible = (bIsIngame && m_bChatboxVisible) || bChatPreview; @@ -491,33 +492,6 @@ void CLocalGUI::Draw() if (m_pChat->IsVisible() != bChatVisible || m_pChat->IsInputBlocked() != bChatInputBlocked) m_pChat->SetVisible(bChatVisible, bChatInputBlocked); - if (bChatPreview && !bIsIngame) - { - const unsigned int uiRevision = CCore::GetSingleton().GetCVars()->GetRevision(); - if (!m_bChatPreviewActive || uiRevision != m_uiChatPreviewRevision) - { - m_uiChatPreviewRevision = uiRevision; - m_pChat->Clear(); - m_pChat->Output("Multi Theft Auto: What more could you want? Multi Theft Auto provides the best online Grand Theft Auto experience there is."); - m_pChat->Output( - "Multi Theft Auto: If you've played Grand Theft Auto online in the past, you'll know that the accuracy of the reproduction of other player's " - "actions often leaves a lot to be desired. This is a hard thing to get perfect, but Multi Theft Auto has the best GTA synchronization out " - "there " - "and it's getting better all the time! Want to shoot someone's limbs one by one? MTA makes that possible!"); - m_pChat->Output( - "Multi Theft Auto: Online games are all about their community, and Multi Theft Auto has a great community! We've got a great forum where you " - "can " - "get support for any problems you have playing MTA, get help with scripting problems or just hang out and chat. We also run a special site for " - "downloading game modes and maps that members of the community have created."); - m_bChatPreviewActive = true; - } - } - else if (!bChatPreview && m_bChatPreviewActive) - { - m_pChat->Clear(); - m_bChatPreviewActive = false; - } - if (bChatPreview && !m_bChatInputPreviewActive) { m_pChat->SetInputPreview("Your message here..."); @@ -560,7 +534,74 @@ void CLocalGUI::Draw() } if (bChatPreview) - m_pChat->Draw(true, true); + { + const CVector2D resolution = pGUI ? pGUI->GetResolution() : CVector2D(0.0f, 0.0f); + const float fScreenWidth = resolution.fX; + const float fScreenHeight = resolution.fY; + + std::vector clipRects; + clipRects.emplace_back(0.0f, 0.0f, fScreenWidth, fScreenHeight); + + std::vector cutoutRects; + m_pMainMenu->GetSettingsWindow()->GetWindowRect(cutoutRects.emplace_back()); + if (CConsole* console = GetConsole(); console->IsVisible()) + console->GetWindowRect(cutoutRects.emplace_back()); + + for (const CRect2D& cutout : cutoutRects) + { + std::vector splitRects; + for (const CRect2D& rect : clipRects) + { + const CRect2D parts[] = { + {rect.fX1, rect.fY1, rect.fX2, std::min(rect.fY2, cutout.fY1)}, + {rect.fX1, std::max(rect.fY1, cutout.fY2), rect.fX2, rect.fY2}, + {rect.fX1, std::max(rect.fY1, cutout.fY1), std::min(rect.fX2, cutout.fX1), std::min(rect.fY2, cutout.fY2)}, + {std::max(rect.fX1, cutout.fX2), std::max(rect.fY1, cutout.fY1), rect.fX2, std::min(rect.fY2, cutout.fY2)}, + }; + for (const CRect2D& part : parts) + { + if (part.fX2 > part.fX1 && part.fY2 > part.fY1) + splitRects.push_back(part); + } + } + clipRects = std::move(splitRects); + } + + if (!clipRects.empty()) + { + for (const CRect2D& clipRect : clipRects) + m_pChat->Draw(true, true, &clipRect); + } + else + m_pChat->Draw(true, true); + } + + if (bChatPreview && !bIsIngame) + { + const unsigned int uiRevision = CCore::GetSingleton().GetCVars()->GetRevision(); + if (!m_bChatPreviewActive || uiRevision != m_uiChatPreviewRevision) + { + m_uiChatPreviewRevision = uiRevision; + m_pChat->Clear(); + m_pChat->Output("Multi Theft Auto: What more could you want? Multi Theft Auto provides the best online Grand Theft Auto experience there is."); + m_pChat->Output( + "Multi Theft Auto: If you've played Grand Theft Auto online in the past, you'll know that the accuracy of the reproduction of other player's " + "actions often leaves a lot to be desired. This is a hard thing to get perfect, but Multi Theft Auto has the best GTA synchronization out " + "there " + "and it's getting better all the time! Want to shoot someone's limbs one by one? MTA makes that possible!"); + m_pChat->Output( + "Multi Theft Auto: Online games are all about their community, and Multi Theft Auto has a great community! We've got a great forum where you " + "can " + "get support for any problems you have playing MTA, get help with scripting problems or just hang out and chat. We also run a special site for " + "downloading game modes and maps that members of the community have created."); + m_bChatPreviewActive = true; + } + } + else if (!bChatPreview && m_bChatPreviewActive) + { + m_pChat->Clear(); + m_bChatPreviewActive = false; + } } void CLocalGUI::Invalidate() diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 047ac38ee06..35650d6e00c 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -3890,6 +3890,13 @@ bool CSettings::IsChatTabVisible() return IsVisible() && m_pTabs->IsTabSelected(m_pTabInterface); } +void CSettings::GetWindowRect(CRect2D& outRect) +{ + CVector2D vecPosition = m_pWindow->GetPosition(false); + CVector2D vecSize = m_pWindow->GetSize(false); + outRect = CRect2D(vecPosition.fX, vecPosition.fY, vecPosition.fX + vecSize.fX, vecPosition.fY + vecSize.fY); +} + void CSettings::SetIsModLoaded(bool bLoaded) { m_bIsModLoaded = bLoaded; diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 3b0e5cf49a1..2a0de715e1c 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -92,6 +92,7 @@ class CSettings void SetVisible(bool bVisible); bool IsVisible(); bool IsChatTabVisible(); + void GetWindowRect(CRect2D& outRect); void SetIsModLoaded(bool bLoaded); From 2e9de91bbcfc6cf8e1ae74d79365b054d5c7c214 Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Thu, 10 Sep 2026 02:01:20 +0300 Subject: [PATCH 3/4] Run clang-format --- Client/core/CChat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Client/core/CChat.cpp b/Client/core/CChat.cpp index c68c7a4107a..6a954b0ff20 100644 --- a/Client/core/CChat.cpp +++ b/Client/core/CChat.cpp @@ -208,7 +208,8 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClip if (!m_bVisible) return; - // Get drawList for the chat box text. The background box is rendered inside GetDrawList, so it must be scissored as well, otherwise it would cover the settings window and the text drawn by the other clipped draw calls + // Get drawList for the chat box text. The background box is rendered inside GetDrawList, so it must be scissored as well, otherwise it would cover the + // settings window and the text drawn by the other clipped draw calls SDrawList drawList; if (pClipRect) SetScissor(true, pClipRect); From 253f995d4b3696f792f9c78ec98ea9a7e6b0a6de Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Thu, 10 Sep 2026 02:40:25 +0300 Subject: [PATCH 4/4] Add lines --- Client/core/CChat.cpp | 14 ++++++++++++++ Client/core/CGUI.cpp | 12 ++++++++++++ Client/core/CSettings.cpp | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/Client/core/CChat.cpp b/Client/core/CChat.cpp index 6a954b0ff20..465f70fcdf7 100644 --- a/Client/core/CChat.cpp +++ b/Client/core/CChat.cpp @@ -189,9 +189,12 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClip } bool bUsingOutline = m_bTextBlackOutline && bAllowOutline && bUseCacheTexture; + if (pClipRect) SetScissor(true, pClipRect); + DrawInputLine(bUsingOutline); + if (pClipRect) SetScissor(false, nullptr); @@ -211,9 +214,12 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClip // Get drawList for the chat box text. The background box is rendered inside GetDrawList, so it must be scissored as well, otherwise it would cover the // settings window and the text drawn by the other clipped draw calls SDrawList drawList; + if (pClipRect) SetScissor(true, pClipRect); + GetDrawList(drawList, bUsingOutline); + if (pClipRect) SetScissor(false, nullptr); @@ -228,9 +234,12 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClip { if (pClipRect) SetScissor(true, pClipRect); + DrawDrawList(drawList, chatTopLeft); + if (pClipRect) SetScissor(false, nullptr); + return; } @@ -270,11 +279,15 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline, const CRect2D* pClip if (!m_pCacheTexture) { drawList.bOutline = false; // Outline too slow without cache texture + if (pClipRect) SetScissor(true, pClipRect); + DrawDrawList(drawList, chatTopLeft); + if (pClipRect) SetScissor(false, nullptr); + return; } @@ -904,6 +917,7 @@ void CChat::SetInputVisible(bool bVisible) void CChat::SetInputPreview(const char* szText) { m_bInputPreview = (szText != nullptr); + if (m_bInputPreview) SetInputText(szText); else diff --git a/Client/core/CGUI.cpp b/Client/core/CGUI.cpp index c0715392ccb..2149b74b824 100644 --- a/Client/core/CGUI.cpp +++ b/Client/core/CGUI.cpp @@ -489,6 +489,7 @@ void CLocalGUI::Draw() bool bChatVisible = (bIsIngame && m_bChatboxVisible) || bChatPreview; bool bChatInputBlocked = !bChatVisible || bChatPreview; + if (m_pChat->IsVisible() != bChatVisible || m_pChat->IsInputBlocked() != bChatInputBlocked) m_pChat->SetVisible(bChatVisible, bChatInputBlocked); @@ -502,8 +503,10 @@ void CLocalGUI::Draw() m_pChat->SetInputPreview(nullptr); m_bChatInputPreviewActive = false; } + bool bDebugVisible = (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_pDebugViewVisible && !CCore::GetSingleton().IsOfflineMod()); + if (m_pDebugView->IsVisible() != bDebugVisible) m_pDebugView->SetVisible(bDebugVisible, true); @@ -513,6 +516,7 @@ void CLocalGUI::Draw() // Draw the chat if (!bChatPreview) m_pChat->Draw(true, true); + // Draw the debugger m_pDebugView->Draw(true, false); @@ -550,6 +554,7 @@ void CLocalGUI::Draw() for (const CRect2D& cutout : cutoutRects) { std::vector splitRects; + for (const CRect2D& rect : clipRects) { const CRect2D parts[] = { @@ -558,12 +563,14 @@ void CLocalGUI::Draw() {rect.fX1, std::max(rect.fY1, cutout.fY1), std::min(rect.fX2, cutout.fX1), std::min(rect.fY2, cutout.fY2)}, {std::max(rect.fX1, cutout.fX2), std::max(rect.fY1, cutout.fY1), rect.fX2, std::min(rect.fY2, cutout.fY2)}, }; + for (const CRect2D& part : parts) { if (part.fX2 > part.fX1 && part.fY2 > part.fY1) splitRects.push_back(part); } } + clipRects = std::move(splitRects); } @@ -579,21 +586,26 @@ void CLocalGUI::Draw() if (bChatPreview && !bIsIngame) { const unsigned int uiRevision = CCore::GetSingleton().GetCVars()->GetRevision(); + if (!m_bChatPreviewActive || uiRevision != m_uiChatPreviewRevision) { m_uiChatPreviewRevision = uiRevision; m_pChat->Clear(); + m_pChat->Output("Multi Theft Auto: What more could you want? Multi Theft Auto provides the best online Grand Theft Auto experience there is."); + m_pChat->Output( "Multi Theft Auto: If you've played Grand Theft Auto online in the past, you'll know that the accuracy of the reproduction of other player's " "actions often leaves a lot to be desired. This is a hard thing to get perfect, but Multi Theft Auto has the best GTA synchronization out " "there " "and it's getting better all the time! Want to shoot someone's limbs one by one? MTA makes that possible!"); + m_pChat->Output( "Multi Theft Auto: Online games are all about their community, and Multi Theft Auto has a great community! We've got a great forum where you " "can " "get support for any problems you have playing MTA, get help with scripting problems or just hang out and chat. We also run a special site for " "downloading game modes and maps that members of the community have created."); + m_bChatPreviewActive = true; } } diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 35650d6e00c..88146924c2c 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -5024,6 +5024,7 @@ void CSettings::SaveChatSettings() SaveChatColor(Chat::ColorType::TEXT, "chat_text_color"); SaveChatColor(Chat::ColorType::INPUT_BG, "chat_input_color"); SaveChatColor(Chat::ColorType::INPUT_TEXT, "chat_input_text_color"); + for (int iFont = 0; iFont < Chat::Font::MAX; iFont++) { if (m_pRadioChatFont[iFont]->GetSelected()) @@ -5035,6 +5036,7 @@ void CSettings::SaveChatSettings() SString strVar = m_pChatScaleX->GetText() + " " + m_pChatScaleY->GetText(); CVARS_SET("chat_scale", strVar); + CVARS_SET("chat_lines", m_pChatLines->GetText()); CVARS_SET("chat_width", m_pChatWidth->GetText()); CVARS_SET("chat_css_style_text", m_pChatCssText->GetSelected()); @@ -5089,7 +5091,9 @@ bool CSettings::OnChatHorizontalComboChanged(CGUIElement* pElement) { if (CGUIListItem* pSelected = m_pChatHorizontalCombo->GetSelectedItem()) m_iChatHorizontalValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; } @@ -5097,7 +5101,9 @@ bool CSettings::OnChatVerticalComboChanged(CGUIElement* pElement) { if (CGUIListItem* pSelected = m_pChatVerticalCombo->GetSelectedItem()) m_iChatVerticalValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; } @@ -5105,13 +5111,16 @@ bool CSettings::OnChatTextAlignComboChanged(CGUIElement* pElement) { if (CGUIListItem* pSelected = m_pChatTextAlignCombo->GetSelectedItem()) m_iChatTextAlignValue = static_cast(reinterpret_cast(pSelected->GetData())); + LiveUpdateChatSettings(); + return true; } void CSettings::LiveUpdateChatSettings() { SString strSignature = GetChatSettingsSignature(); + if (strSignature != m_strChatSettingsSignature) { m_strChatSettingsSignature = strSignature; @@ -5122,6 +5131,7 @@ void CSettings::LiveUpdateChatSettings() void CSettings::SnapshotChatSettings() { std::string strVar; + CVARS_GET("chat_color", strVar); m_strOldChatColor = strVar; CVARS_GET("chat_text_color", strVar);