From 1d7bb162ff5632d1dcde8224008239e8d64d5340 Mon Sep 17 00:00:00 2001 From: getcetc Date: Wed, 21 Jan 2026 12:56:43 +0700 Subject: [PATCH 1/2] VS 2026 compatibility --- RTEA.vcxproj | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RTEA.vcxproj b/RTEA.vcxproj index e2e0b94c41..fa4523070f 100644 --- a/RTEA.vcxproj +++ b/RTEA.vcxproj @@ -50,6 +50,7 @@ MultiByte v142 v143 + v145 10.0 _Bin\$(Platform)\$(Configuration)\ .\ @@ -100,6 +101,7 @@ Cortex Command.debug.full $(OutDir) WindowsLocalDebugger + v145 true @@ -112,6 +114,7 @@ Cortex Command.debug.minimal $(OutDir) WindowsLocalDebugger + v145 true @@ -133,6 +136,7 @@ Cortex Command.debug.release $(OutDir) WindowsLocalDebugger + v145 true @@ -140,6 +144,7 @@ Cortex Command.profiling $(OutDir) WindowsLocalDebugger + v145 true @@ -154,6 +159,7 @@ Cortex Command $(OutDir) WindowsLocalDebugger + v145 @@ -236,6 +242,7 @@ false #undef GetClassName false + /bigobj %(AdditionalOptions) winmm.lib;ws2_32.lib;dinput8.lib;ddraw.lib;dxguid.lib;dsound.lib;imm32.lib;setupapi.lib;version.lib;zlibstatic.lib;libminizip.lib;libpng16-static.lib;fmod_vc.lib;allegro-debug.lib;loadpng-debug.lib;liblz4_debug_static.lib;luajit-debug.lib;luabind-debug.lib;raknet-debug.lib;SDL3_image-static-debug.lib;SDL3-static-debug.lib;opengl32.lib;dbghelp.lib;%(AdditionalDependencies) @@ -342,6 +349,7 @@ false #undef GetClassName false + /bigobj %(AdditionalOptions) winmm.lib;ws2_32.lib;dinput8.lib;ddraw.lib;dxguid.lib;dsound.lib;imm32.lib;setupapi.lib;version.lib;zlibstatic.lib;libminizip.lib;libpng16-static.lib;fmod_vc.lib;allegro-debug.lib;loadpng-debug.lib;liblz4_debug_static.lib;luajit-debug-release.lib;luabind-debug.lib;raknet-debug.lib;SDL3-static-debug.lib;SDL3_image-static-debug.lib;opengl32.lib;dbghelp.lib;%(AdditionalDependencies) @@ -525,6 +533,7 @@ true false #undef GetClassName + /bigobj %(AdditionalOptions) winmm.lib;ws2_32.lib;dinput8.lib;ddraw.lib;dxguid.lib;dsound.lib;imm32.lib;setupapi.lib;version.lib;zlibstatic.lib;libminizip.lib;libpng16-static.lib;fmod_vc.lib;allegro-debug-release.lib;loadpng-debug-release.lib;liblz4_release_static.lib;luajit-debug-release.lib;luabind-debug-release.lib;raknet-release.lib;opengl32.lib;SDL3-static.lib;SDL3_image-static.lib;dbghelp.lib;%(AdditionalDependencies) @@ -587,6 +596,7 @@ true false #undef GetClassName + /bigobj %(AdditionalOptions) winmm.lib;ws2_32.lib;dinput8.lib;ddraw.lib;dxguid.lib;dsound.lib;imm32.lib;setupapi.lib;version.lib;zlibstatic.lib;libminizip.lib;libpng16-static.lib;fmod_vc.lib;allegro-debug-release.lib;loadpng-debug-release.lib;liblz4_release_static.lib;luajit-debug-release.lib;luabind-debug-release.lib;raknet-release.lib;opengl32.lib;SDL3-static.lib;SDL3_image-static.lib;dbghelp.lib;%(AdditionalDependencies) @@ -707,6 +717,7 @@ true false #undef GetClassName + /bigobj %(AdditionalOptions) winmm.lib;ws2_32.lib;dinput8.lib;ddraw.lib;dxguid.lib;dsound.lib;imm32.lib;setupapi.lib;version.lib;zlibstatic.lib;libminizip.lib;libpng16-static.lib;fmod_vc.lib;allegro-release.lib;loadpng-release.lib;liblz4_release_static.lib;luajit-release.lib;luabind-release.lib;raknet-release.lib;opengl32.lib;SDL3-static.lib;SDL3_image-static.lib;dbghelp.lib;%(AdditionalDependencies) From 207e4baf81c2b4ca692dcbf0814377010d7bb438 Mon Sep 17 00:00:00 2001 From: getcetc Date: Wed, 21 Jan 2026 12:57:56 +0700 Subject: [PATCH 2/2] Mod&script manager menu overhaul --- Source/Menus/ModManagerGUI.cpp | 208 +++++++++++++++++++++++++++------ Source/Menus/ModManagerGUI.h | 52 +++++++-- 2 files changed, 217 insertions(+), 43 deletions(-) diff --git a/Source/Menus/ModManagerGUI.cpp b/Source/Menus/ModManagerGUI.cpp index 2c0f1437bf..864ed6a4cb 100644 --- a/Source/Menus/ModManagerGUI.cpp +++ b/Source/Menus/ModManagerGUI.cpp @@ -88,25 +88,81 @@ void ModManagerGUI::PopulateKnownModsList() { m_ModsListFetched = true; } -void ModManagerGUI::PopulateKnownScriptsList() { - std::list globalScriptList; - g_PresetMan.GetAllOfType(globalScriptList, "GlobalScript"); - - for (Entity* globalScriptListEntry: globalScriptList) { - if (const GlobalScript* globalScript = dynamic_cast(globalScriptListEntry)) { - ScriptRecord scriptRecord = {globalScript->GetModuleAndPresetName(), globalScript->GetDescription(), g_SettingsMan.IsGlobalScriptEnabled(scriptRecord.PresetName)}; - m_KnownScripts.emplace_back(scriptRecord); +//todo to fetch +void ModManagerGUI::InitializeKnownScripts() { + int totalModuleCount = g_PresetMan.GetTotalModuleCount(); + for (int currentModuleIndex = 0; currentModuleIndex < totalModuleCount; ++currentModuleIndex) { + // todo: try GetFriendlyName() + std::list globalScriptListForThisModule; + g_PresetMan.GetAllOfType(globalScriptListForThisModule, "GlobalScript", currentModuleIndex); + + if (globalScriptListForThisModule.empty()) { + continue; } - } - std::sort(m_KnownScripts.begin(), m_KnownScripts.end()); - for (int i = 0; i < m_KnownScripts.size(); i++) { - m_ScriptsListBox->AddItem(m_KnownScripts.at(i).GetDisplayString(), std::string(), nullptr, nullptr, i); + + std::vector& currentModuleScripts = + m_KnownScriptsPerModule.emplace_back( + g_PresetMan.GetDataModule(currentModuleIndex)->GetFileName(), + g_PresetMan.GetDataModule(currentModuleIndex)->GetFriendlyName() + + "\n" + g_PresetMan.GetDataModule(currentModuleIndex)->GetDescription() + ).Records; + + for (Entity* globalScriptListEntry: globalScriptListForThisModule) { + if (const GlobalScript* globalScript = dynamic_cast(globalScriptListEntry)) { + ScriptRecord scriptRecord = + {globalScript->GetPresetName(), + globalScript->GetModuleAndPresetName(), + globalScript->GetDescription(), + g_SettingsMan.IsGlobalScriptEnabled(globalScript->GetModuleAndPresetName())}; + currentModuleScripts.emplace_back(scriptRecord); + } + } + std::sort(currentModuleScripts.begin(), currentModuleScripts.end()); } m_ScriptsListBox->ScrollToTop(); m_ScriptsListFetched = true; } +int ModManagerGUI::ScriptListEntryEncodeExtraIndex(const int moduleNumber, const int scriptNumber) { + return scriptNumber == -1 + ? (moduleNumber << 10) | EXTRA_INDEX_IS_A_MODULE_LABEL_MASK + : (moduleNumber << 10) + scriptNumber; +} + +std::pair ModManagerGUI::ScriptListEntryDecodeExtraIndex(const int extraIndex) { + if (extraIndex & EXTRA_INDEX_IS_A_MODULE_LABEL_MASK) { + return {(extraIndex ^ EXTRA_INDEX_IS_A_MODULE_LABEL_MASK) >> 10, -1}; + } else { + return {extraIndex >> 10, extraIndex - ((extraIndex >> 10) << 10)}; + } +} + +void ModManagerGUI::PopulateKnownScriptsList(bool clearBeforehand = false) { + if (clearBeforehand) { + m_ScriptsListBox->ClearList(); + } + + for (int moduleIt = 0; moduleIt < m_KnownScriptsPerModule.size(); ++moduleIt) { + auto& scriptRecordsInAModule = m_KnownScriptsPerModule[moduleIt]; + + //display the module ".rte" thingy + m_ScriptsListBox->AddItem(scriptRecordsInAModule.GetDisplayString(), + std::string(), nullptr, nullptr, ScriptListEntryEncodeExtraIndex(moduleIt, -1)); + + if (scriptRecordsInAModule.Collapsed) { + continue; + } + + // then per each .rte display the scripts under: + for (int scriptIt = 0; scriptIt < scriptRecordsInAModule.Records.size(); ++scriptIt) { + auto& scriptRecord = scriptRecordsInAModule.Records[scriptIt]; + m_ScriptsListBox->AddItem(scriptRecord.GetDisplayString(), + std::string(), nullptr, nullptr, ScriptListEntryEncodeExtraIndex(moduleIt, scriptIt)); + } + } +} + void ModManagerGUI::ToggleMod() { int index = m_ModsListBox->GetSelectedIndex(); if (index > -1) { @@ -133,62 +189,142 @@ void ModManagerGUI::ToggleMod() { } } -void ModManagerGUI::ToggleScript() { +ModManagerGUI::ScriptRecord* ModManagerGUI::ScriptListExtraIndexToScriptRecord(int extraIndex) { + + auto [moduleInd, scriptInd] = ScriptListEntryDecodeExtraIndex(extraIndex); + // if the list item is a module label header - return nullptr + if (scriptInd == -1) { + return nullptr; + } + // else - a script, decode where to access it from the item's extra value + return &m_KnownScriptsPerModule.at(moduleInd).Records.at(scriptInd); +} + +void ModManagerGUI::ToggleInScriptList() { int index = m_ScriptsListBox->GetSelectedIndex(); - if (index > -1) { + if (index <= -1) { + return; + } + + GUIListPanel::Item* selectedItem = m_ScriptsListBox->GetSelected(); + int extraIndex = selectedItem->m_ExtraIndex; + auto [moduleInd, scriptInd] = ScriptListEntryDecodeExtraIndex(extraIndex); + //if the list item is a module label header then collapse/expand it + if (scriptInd == -1) { + m_KnownScriptsPerModule[moduleInd].Collapsed ^= 1; //toggle it + PopulateKnownScriptsList(true); + } + // else - it's a script, toggle it: + else { std::unordered_map& enabledScriptList = g_SettingsMan.GetEnabledGlobalScriptMap(); - GUIListPanel::Item* selectedItem = m_ScriptsListBox->GetSelected(); - ScriptRecord& scriptRecord = m_KnownScripts.at(selectedItem->m_ExtraIndex); - scriptRecord.Enabled = !scriptRecord.Enabled; - if (scriptRecord.Enabled) { + ScriptRecord* scriptRecord = ScriptListExtraIndexToScriptRecord(extraIndex); + scriptRecord->Enabled = !scriptRecord->Enabled; + if (scriptRecord->Enabled) { m_ToggleScriptButton->SetText("Disable Script"); - if (enabledScriptList.find(scriptRecord.PresetName) != enabledScriptList.end()) { - enabledScriptList.at(scriptRecord.PresetName) = true; + if (enabledScriptList.find(scriptRecord->ModuleAndPresetName) != enabledScriptList.end()) { + enabledScriptList.at(scriptRecord->ModuleAndPresetName) = true; } else { - enabledScriptList.try_emplace(scriptRecord.PresetName, true); + enabledScriptList.try_emplace(scriptRecord->ModuleAndPresetName, true); } } else { m_ToggleScriptButton->SetText("Enable Script"); - enabledScriptList.at(scriptRecord.PresetName) = false; + enabledScriptList.at(scriptRecord->ModuleAndPresetName) = false; } - selectedItem->m_Name = scriptRecord.GetDisplayString(); - m_ScriptsListBox->SetSelectedIndex(index); - m_ScriptsListBox->Invalidate(); - g_GUISound.ItemChangeSound()->Play(); + + selectedItem->m_Name = scriptRecord->GetDisplayString(); } + m_ScriptsListBox->SetSelectedIndex(index); + m_ScriptsListBox->Invalidate(); + g_GUISound.ItemChangeSound()->Play(); +} + +void ModManagerGUI::ResetSelectionsAndGoToTop() { + m_ModsListBox->ScrollToTop(); + m_ScriptsListBox->ScrollToTop(); + + m_ModOrScriptDescriptionLabel->SetText(m_DisclaimerText); } bool ModManagerGUI::HandleInputEvents() { if (!ListsFetched()) { + m_DisclaimerText = m_ModOrScriptDescriptionLabel->GetText(); PopulateKnownModsList(); + InitializeKnownScripts(); PopulateKnownScriptsList(); + ResetSelectionsAndGoToTop(); } m_GUIControlManager->Update(); GUIEvent guiEvent; while (m_GUIControlManager->GetEvent(&guiEvent)) { + // buttons if (guiEvent.GetType() == GUIEvent::Command) { if (guiEvent.GetControl() == m_BackToMainButton) { + ResetSelectionsAndGoToTop(); return true; } else if (guiEvent.GetControl() == m_ToggleModButton) { ToggleMod(); } else if (guiEvent.GetControl() == m_ToggleScriptButton) { - ToggleScript(); + ToggleInScriptList(); } - } else if (guiEvent.GetType() == GUIEvent::Notification) { + } + + else if (guiEvent.GetType() == GUIEvent::Notification) { + // button hover sound if (guiEvent.GetMsg() == GUIButton::Focused && dynamic_cast(guiEvent.GetControl())) { g_GUISound.SelectionChangeSound()->Play(); } - if (guiEvent.GetControl() == m_ModsListBox && (guiEvent.GetMsg() == GUIListBox::Select && m_ModsListBox->GetSelectedIndex() > -1)) { - const ModRecord& modRecord = m_KnownMods.at(m_ModsListBox->GetSelected()->m_ExtraIndex); - m_ModOrScriptDescriptionLabel->SetText(modRecord.Description); - m_ToggleModButton->SetText(modRecord.Disabled ? "Enable Mod" : "Disable Mod"); - } else if (guiEvent.GetControl() == m_ScriptsListBox && (guiEvent.GetMsg() == GUIListBox::Select && m_ScriptsListBox->GetSelectedIndex() > -1)) { - const ScriptRecord& scriptRecord = m_KnownScripts.at(m_ScriptsListBox->GetSelected()->m_ExtraIndex); - m_ModOrScriptDescriptionLabel->SetText(scriptRecord.Description); - m_ToggleScriptButton->SetText(scriptRecord.Enabled ? "Disable Script" : "Enable Script"); + // list entries + if (guiEvent.GetControl() == m_ModsListBox && m_ModsListBox->GetSelectedIndex() > -1) { + switch (guiEvent.GetMsg()) { + case GUIListBox::Select: { + g_GUISound.SelectionChangeSound()->Play(); + const ModRecord& modRecord = m_KnownMods.at(m_ModsListBox->GetSelected()->m_ExtraIndex); + m_ModOrScriptDescriptionLabel->SetText(modRecord.Description); + m_ToggleModButton->SetText(modRecord.Disabled ? "Enable Mod" : "Disable Mod"); + break; + } + case GUIListBox::KeyDown: + if (guiEvent.GetData() != 13) //enter key but doesnt work, todo + break; + case GUIListBox::DoubleClick: + g_GUISound.SelectionChangeSound()->FadeOut(0); + g_GUISound.ItemChangeSound()->Play(); + ToggleMod(); + break; + } + } else if (guiEvent.GetControl() == m_ScriptsListBox && m_ScriptsListBox->GetSelectedIndex() > -1) { + switch (guiEvent.GetMsg()) { + case GUIListBox::Select: { + g_GUISound.SelectionChangeSound()->Play(); + int extraIndex = m_ScriptsListBox->GetSelected()->m_ExtraIndex; + auto [moduleInd, scriptInd] = ScriptListEntryDecodeExtraIndex(extraIndex); + // if we're on a script item + if (scriptInd != -1) { + const ScriptRecord* scriptRecord = ScriptListExtraIndexToScriptRecord(extraIndex); + m_ModOrScriptDescriptionLabel->SetText(scriptRecord->Description.empty() ? "No description." : scriptRecord->Description); + m_ToggleScriptButton->SetText(scriptRecord->Enabled ? "Disable Script" : "Enable Script"); + } + // if we're on a module label + else { + ScriptRecordsInAModule* module = + &m_KnownScriptsPerModule[moduleInd]; + m_ModOrScriptDescriptionLabel->SetText(module->Description); + m_ToggleScriptButton->SetText(module->Collapsed ? "Expand Category" : "Collapse Category"); + } + break; + } + case GUIListBox::KeyDown: + if (guiEvent.GetData() != 13) //todo, check above + break; + case GUIListBox::DoubleClick: + g_GUISound.SelectionChangeSound()->FadeOut(0); + g_GUISound.ItemChangeSound()->Play(); + ToggleInScriptList(); + break; + } } } } diff --git a/Source/Menus/ModManagerGUI.h b/Source/Menus/ModManagerGUI.h index 3c5fbeb018..6b835c2c15 100644 --- a/Source/Menus/ModManagerGUI.h +++ b/Source/Menus/ModManagerGUI.h @@ -54,24 +54,48 @@ namespace RTE { /// Struct containing information about a valid GlobalScript. struct ScriptRecord { - std::string PresetName; //!< Script PresetName. + std::string DisplayName; + std::string ModuleAndPresetName; std::string Description; //!< Script description. bool Enabled; //!< Whether the script is enabled through the settings file or not. /// Makes GUI displayable string with script info. /// @return String with script info. - std::string GetDisplayString() const { return (!Enabled ? "- " : "+ ") + PresetName; } + std::string GetDisplayString() const { + return (!Enabled ? " - " : " + ") + DisplayName; + } /// Comparison operator for sorting the KnownScripts list alphabetically by PresetName with std::sort. /// @param rhs ScriptRecord to compare with. /// @return Bool with result of the alphabetical comparison. - bool operator<(const ScriptRecord& rhs) const { return PresetName < rhs.PresetName; } + bool operator<(const ScriptRecord& rhs) const { return DisplayName < rhs.DisplayName; } + }; + + struct ScriptRecordsInAModule { + std::string ModuleName; + std::string Description; + std::vector Records; + bool Collapsed = false; + + ScriptRecordsInAModule(std::string moduleName, std::string description) { + ModuleName = moduleName; + Description = description; + } + + ScriptRecord& operator[](int i) { + return Records[i]; + } + + std::string GetDisplayString() const { + return (Collapsed ? "+ " : "- ") + ModuleName; + } }; std::unique_ptr m_GUIControlManager; //!< The GUIControlManager which holds all the GUIControls of the ModManagerGUI. std::vector m_KnownMods; //!< Contains ModRecords for all valid mod DataModules. std::vector m_KnownScripts; //!< Contains ScriptRecords for all valid GlobalScripts. + std::vector m_KnownScriptsPerModule; bool m_ModsListFetched; //!< Whether the known mods list was fetched, even if no valid mod DataModules were added to it. bool m_ScriptsListFetched; //!< Whether the known scripts list was fetched, even if no valid GlobalScripts were added to it. @@ -84,6 +108,9 @@ namespace RTE { GUIListBox* m_ScriptsListBox; GUILabel* m_ModOrScriptDescriptionLabel; + //todo + std::string m_DisclaimerText; + #pragma region Mod and Script Handling /// Gets whether both lists were fetched, even if nothing valid was added to them. /// @return Whether both lists were fetched, even if nothing valid was added to them. @@ -92,14 +119,25 @@ namespace RTE { /// Fills the KnownMods list with all valid mod DataModules, then fills the ModsListBox using it. void PopulateKnownModsList(); - /// Fills the KnownScripts list with all valid GlobalScripts, then fills the ScriptsListBox using it. - void PopulateKnownScriptsList(); + void InitializeKnownScripts(); + + int ScriptListEntryEncodeExtraIndex(const int, const int); + std::pair ScriptListEntryDecodeExtraIndex(const int); + + const int EXTRA_INDEX_IS_A_MODULE_LABEL_MASK = 1 << 24; + + void PopulateKnownScriptsList(bool); + + void ResetSelectionsAndGoToTop(); /// Turns currently selected mod on and off and changes GUI elements accordingly. void ToggleMod(); - /// Turns currently selected script on and off and changes GUI elements accordingly. - void ToggleScript(); + //todo + ScriptRecord* ScriptListExtraIndexToScriptRecord(int); + + /// todo Turns currently selected script on and off and changes GUI elements accordingly. + void ToggleInScriptList(); #pragma endregion // Disallow the use of some implicit methods.