diff --git a/RTEA.vcxproj b/RTEA.vcxproj
index e2e0b94c4..fa4523070 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)
diff --git a/Source/Menus/ModManagerGUI.cpp b/Source/Menus/ModManagerGUI.cpp
index 2c0f1437b..864ed6a4c 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 3c5fbeb01..6b835c2c1 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.