diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp index 609edf4d4..7b7cbaa8f 100644 --- a/soh/soh/Enhancements/mod_menu.cpp +++ b/soh/soh/Enhancements/mod_menu.cpp @@ -2,8 +2,10 @@ #include "utils/StringHelper.h" #include #include "soh/OTRGlobals.h" +#include "soh/resource/type/Skeleton.h" #include #include +extern "C" void gfx_texture_cache_clear(); std::shared_ptr GetArchiveManager() { return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager(); @@ -11,6 +13,34 @@ std::shared_ptr GetArchiveManager() { std::map modFiles; +#define CVAR_ENABLED_MODS_NAME CVAR_GENERAL("EnabledMods") +#define CVAR_ENABLED_MODS_DEFAULT "" +#define CVAR_ENABLED_MODS_VALUE CVarGetString(CVAR_ENABLED_MODS_NAME, CVAR_ENABLED_MODS_DEFAULT) + +#define SEPARATOR "|" + +void SaveEnabledModsCVarValue() { + std::string s = ""; + + for (auto& [modPath, enabled] : modFiles) { + if (enabled) { + s += modPath + SEPARATOR; + } + } + + //remove trailing separator if present + if (s.length() != 0) { + s.pop_back(); + } + + CVarSetString(CVAR_ENABLED_MODS_NAME, s.c_str()); +} + +std::vector GetEnabledModsFromCVar() { + std::string enabledModsCVarValue = CVAR_ENABLED_MODS_VALUE; + return StringHelper::Split(enabledModsCVarValue, SEPARATOR); +} + bool is_enabled(const std::pair& p) { return p.second; } @@ -41,8 +71,9 @@ std::vector GetDisabledModFiles() { return keys; } -void UpdateModFiles() { +void UpdateModFiles(bool init = false) { modFiles.clear(); + std::vector enabledMods = GetEnabledModsFromCVar(); std::string modsPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName); if (modsPath.length() > 0 && std::filesystem::exists(modsPath)) { if (std::filesystem::is_directory(modsPath)) { @@ -54,7 +85,12 @@ void UpdateModFiles() { StringHelper::IEquals(extension, ".o2r") || StringHelper::IEquals(extension, ".zip") ) { - modFiles.emplace(p.path().generic_string(), false); + std::string path = p.path().generic_string(); + bool shouldBeEnabled = std::find(enabledMods.begin(), enabledMods.end(), path) != enabledMods.end(); + if (init && shouldBeEnabled) { + GetArchiveManager()->AddArchive(path); + } + modFiles.emplace(path, shouldBeEnabled); } } } @@ -73,6 +109,13 @@ void UpdateModFiles() { */ } +void AfterModChange() { + SaveEnabledModsCVarValue(); + gfx_texture_cache_clear(); + SOH::SkeletonPatcher::UpdateSkeletons(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); +} + void ModMenuWindow::DrawElement() { if (ImGui::Button("Update")) { UpdateModFiles(); @@ -94,7 +137,8 @@ void ModMenuWindow::DrawElement() { for (std::string file : enabledMods) { if (ImGui::Button(("Disable##" + file).c_str())) { modFiles[file] = false; - Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->RemoveArchive(file); + GetArchiveManager()->RemoveArchive(file); + AfterModChange(); } ImGui::SameLine(); ImGui::Text(file.c_str()); @@ -114,7 +158,8 @@ void ModMenuWindow::DrawElement() { for (std::string file : disabledMods) { if (ImGui::Button(("Enable##" + file).c_str())) { modFiles[file] = true; - Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->AddArchive(file); + GetArchiveManager()->AddArchive(file); + AfterModChange(); } ImGui::SameLine(); ImGui::Text(file.c_str()); @@ -131,5 +176,5 @@ void ModMenuWindow::DrawElement() { } void ModMenuWindow::InitElement() { - UpdateModFiles(); + UpdateModFiles(true); } \ No newline at end of file