diff --git a/po/colobot.pot b/po/colobot.pot index a331ffba..262b251a 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -120,6 +120,12 @@ msgstr "" msgid "2) Then press the key you want to use instead." msgstr "" +msgid "Unloaded Mods:" +msgstr "" + +msgid "Loaded Mods:" +msgstr "" + msgid "Face type:" msgstr "" @@ -343,6 +349,18 @@ msgstr "" msgid "Play\\Start mission!" msgstr "" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + +msgid "Open Directory\\Open Mods directory" +msgstr "" + +msgid "Load\\Load Mod" +msgstr "" + +msgid "Unload\\Unload Mod" +msgstr "" + msgid "Device\\Driver and resolution settings" msgstr "" @@ -358,6 +376,9 @@ msgstr "" msgid "Sound\\Music and game sound volume" msgstr "" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Unit" msgstr "" diff --git a/po/cs.po b/po/cs.po index 175ab412..0d4d482b 100644 --- a/po/cs.po +++ b/po/cs.po @@ -844,12 +844,18 @@ msgstr "Seznam uložených misí" msgid "Load a saved mission" msgstr "Nahrát uloženou misi" +msgid "Load\\Load Mod" +msgstr "" + msgid "Load\\Load a saved mission" msgstr "Nahrát\\Nahrát uloženou misi" msgid "Load\\Loads the selected mission" msgstr "Nahrát\\Nahraje vybranou misi" +msgid "Loaded Mods:" +msgstr "" + msgid "Loading basic level settings" msgstr "Načítám základní nastavení mapy" @@ -904,6 +910,9 @@ msgstr "Mise na této planetě:" msgid "Missions\\Select mission" msgstr "Mise\\Vyberte misi" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" msgstr "Vodorovné převrácení posunu\\Při vodorovném posunu kamery myší pousouvat opačným směrem" @@ -1072,6 +1081,9 @@ msgstr "Otevřít" msgid "Open (Ctrl+O)" msgstr "Otevřít (Ctrl+O)" +msgid "Open Directory\\Open Mods directory" +msgstr "" + msgid "Opening brace missing" msgstr "Chybí levá složená závorka" @@ -1691,6 +1703,12 @@ msgstr "Neznámá zástupná sekvence" msgid "Unknown function" msgstr "Neznámá funkce" +msgid "Unload\\Unload Mod" +msgstr "" + +msgid "Unloaded Mods:" +msgstr "" + msgid "Up (\\key gup;)" msgstr "Vzhůru (\\key gup;)" @@ -1766,6 +1784,9 @@ msgstr "Létající detektor" msgid "Withdraw shield (\\key action;)" msgstr "Vypnout štít (\\key action;)" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + msgid "Worm" msgstr "Červ" diff --git a/po/de.po b/po/de.po index 8afe0c8b..b03c22ab 100644 --- a/po/de.po +++ b/po/de.po @@ -846,12 +846,18 @@ msgstr "Liste der gespeicherten Missionen" msgid "Load a saved mission" msgstr "Gespeicherte Mission laden" +msgid "Load\\Load Mod" +msgstr "" + msgid "Load\\Load a saved mission" msgstr "Laden\\Eine gespeicherte Mission öffnen" msgid "Load\\Loads the selected mission" msgstr "Laden\\Öffnet eine gespeicherte Mission" +msgid "Loaded Mods:" +msgstr "" + msgid "Loading basic level settings" msgstr "Lade Level-Grundeinstellungen" @@ -920,6 +926,9 @@ msgstr "Liste der Missionen des Planeten:" msgid "Missions\\Select mission" msgstr "Missionen\\Aufbruch ins Weltall" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" msgstr "Umkehr X\\Umkehr der Kameradrehung X-Achse" @@ -1088,6 +1097,9 @@ msgstr "Öffnen" msgid "Open (Ctrl+O)" msgstr "Öffnen (Ctrl+O)" +msgid "Open Directory\\Open Mods directory" +msgstr "" + msgid "Opening brace missing" msgstr "Es fehlt eine offene geschweifte Klammer\"{\"" @@ -1708,6 +1720,12 @@ msgstr "" msgid "Unknown function" msgstr "Unbekannte Funktion" +msgid "Unload\\Unload Mod" +msgstr "" + +msgid "Unloaded Mods:" +msgstr "" + msgid "Up (\\key gup;)" msgstr "Steigt (\\key gup;)" @@ -1783,6 +1801,9 @@ msgstr "Schnüffler" msgid "Withdraw shield (\\key action;)" msgstr "Schutzschild einholen (\\key action;)" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + msgid "Worm" msgstr "Wurm" diff --git a/po/fr.po b/po/fr.po index 2bfb0c04..6c49754a 100644 --- a/po/fr.po +++ b/po/fr.po @@ -848,12 +848,18 @@ msgstr "Liste des missions enregistrées" msgid "Load a saved mission" msgstr "Chargement d'une mission enregistrée" +msgid "Load\\Load Mod" +msgstr "" + msgid "Load\\Load a saved mission" msgstr "Charger\\Charger une mission enregistrée" msgid "Load\\Loads the selected mission" msgstr "Charger\\Charger la mission sélectionnée" +msgid "Loaded Mods:" +msgstr "" + msgid "Loading basic level settings" msgstr "Chargement des configurations de base du niveau" @@ -922,6 +928,9 @@ msgstr "Liste des missions du chapitre :" msgid "Missions\\Select mission" msgstr "Missions\\La grande aventure" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" msgstr "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord" @@ -1090,6 +1099,9 @@ msgstr "Ouvrir" msgid "Open (Ctrl+O)" msgstr "Ouvrir (Ctrl+O)" +msgid "Open Directory\\Open Mods directory" +msgstr "" + msgid "Opening brace missing" msgstr "Début d'un bloc attendu" @@ -1710,6 +1722,12 @@ msgstr "Séquence d'échappement inconnue" msgid "Unknown function" msgstr "Routine inconnue" +msgid "Unload\\Unload Mod" +msgstr "" + +msgid "Unloaded Mods:" +msgstr "" + msgid "Up (\\key gup;)" msgstr "Monte (\\key gup;)" @@ -1785,6 +1803,9 @@ msgstr "Robot renifleur volant" msgid "Withdraw shield (\\key action;)" msgstr "Refermer le bouclier (\\key action;)" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + msgid "Worm" msgstr "Ver" diff --git a/po/pl.po b/po/pl.po index 3cef57ef..7c90d67f 100644 --- a/po/pl.po +++ b/po/pl.po @@ -843,12 +843,18 @@ msgstr "Lista zapisanych misji" msgid "Load a saved mission" msgstr "Wczytaj zapisaną misję" +msgid "Load\\Load Mod" +msgstr "" + msgid "Load\\Load a saved mission" msgstr "Wczytaj\\Wczytuje zapisaną misję" msgid "Load\\Loads the selected mission" msgstr "Wczytaj\\Wczytuje zaznaczoną misję" +msgid "Loaded Mods:" +msgstr "" + msgid "Loading basic level settings" msgstr "Wczytywanie ustawień poziomu" @@ -903,6 +909,9 @@ msgstr "Misje na tej planecie:" msgid "Missions\\Select mission" msgstr "Misje\\Wybierz misję" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" msgstr "Odwrócenie myszy X\\Odwrócenie kierunków przewijania w poziomie" @@ -1071,6 +1080,9 @@ msgstr "Otwórz" msgid "Open (Ctrl+O)" msgstr "Otwórz (Ctrl+O)" +msgid "Open Directory\\Open Mods directory" +msgstr "" + msgid "Opening brace missing" msgstr "Brak klamry otwierającej" @@ -1690,6 +1702,12 @@ msgstr "" msgid "Unknown function" msgstr "Funkcja nieznana" +msgid "Unload\\Unload Mod" +msgstr "" + +msgid "Unloaded Mods:" +msgstr "" + msgid "Up (\\key gup;)" msgstr "Góra (\\key gup;)" @@ -1765,6 +1783,9 @@ msgstr "Szperacz latający" msgid "Withdraw shield (\\key action;)" msgstr "Wyłącz osłonę (\\key action;)" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + msgid "Worm" msgstr "Robal" diff --git a/po/ru.po b/po/ru.po index 4e3f371b..c062a50b 100644 --- a/po/ru.po +++ b/po/ru.po @@ -852,12 +852,18 @@ msgstr "Список сохраненных миссий" msgid "Load a saved mission" msgstr "Загрузить" +msgid "Load\\Load Mod" +msgstr "" + msgid "Load\\Load a saved mission" msgstr "Загрузить\\Загрузить сохраненную миссию" msgid "Load\\Loads the selected mission" msgstr "Загрузить\\Загрузить выбранную миссию" +msgid "Loaded Mods:" +msgstr "" + msgid "Loading basic level settings" msgstr "Загрузка основных настроек уровня" @@ -926,6 +932,9 @@ msgstr "Миссии на этой планете:" msgid "Missions\\Select mission" msgstr "Миссии\\Выбор миссии" +msgid "Mods\\Manage installed mods" +msgstr "" + msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" msgstr "Инверсия мыши по оси X\\Инверсия прокрутки по оси Х" @@ -1096,6 +1105,9 @@ msgstr "Открыть" msgid "Open (Ctrl+O)" msgstr "Открыть (Ctrl+O)" +msgid "Open Directory\\Open Mods directory" +msgstr "" + msgid "Opening brace missing" msgstr "Открывающая скобка отсутствует" @@ -1721,6 +1733,12 @@ msgstr "" msgid "Unknown function" msgstr "Неизвестная функция" +msgid "Unload\\Unload Mod" +msgstr "" + +msgid "Unloaded Mods:" +msgstr "" + msgid "Up (\\key gup;)" msgstr "Вверх (\\key gup;)" @@ -1796,6 +1814,9 @@ msgstr "Летающий искатель" msgid "Withdraw shield (\\key action;)" msgstr "Снять щит (\\key action;)" +msgid "Workshop\\Open Workshop to search Mods" +msgstr "" + msgid "Worm" msgstr "Червь" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aefd0fad..2fa18acc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -581,6 +581,8 @@ set(BASE_SOURCES ui/screen/screen_setup_game.h ui/screen/screen_setup_graphics.cpp ui/screen/screen_setup_graphics.h + ui/screen/screen_setup_mods.cpp + ui/screen/screen_setup_mods.h ui/screen/screen_setup_sound.cpp ui/screen/screen_setup_sound.h ui/screen/screen_welcome.cpp diff --git a/src/app/app.cpp b/src/app/app.cpp index b5bd3ca0..d0cb9692 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -726,6 +726,26 @@ bool CApplication::Create() return true; } +void CApplication::Reload() +{ + m_sound->Create(); + m_engine->ReloadAllTextures(); + CThread musicLoadThread([this]() + { + SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp(); + m_systemUtils->GetCurrentTimeStamp(musicLoadStart); + m_sound->CacheAll(); + SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp(); + m_systemUtils->GetCurrentTimeStamp(musicLoadEnd); + float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC); + GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime); + }, + "Sound loading thread"); + musicLoadThread.Start(); + m_controller->GetRobotMain()->UpdateCustomLevelList(); +} + + bool CApplication::CreateVideoSurface() { Uint32 videoFlags = SDL_WINDOW_OPENGL; diff --git a/src/app/app.h b/src/app/app.h index c55eca38..c45e6320 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -170,6 +170,8 @@ public: ParseArgsStatus ParseArguments(int argc, char *argv[]); //! Initializes the application bool Create(); + //! Reloads the application + void Reload(); //! Main event loop int Run(); //! Returns the code to be returned at main() exit diff --git a/src/app/pathman.cpp b/src/app/pathman.cpp index 690f6d34..d007b0fd 100644 --- a/src/app/pathman.cpp +++ b/src/app/pathman.cpp @@ -72,7 +72,28 @@ void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath) void CPathManager::AddMod(const std::string &modPath) { - m_mods.push_back(modPath); + std::string::size_type enabled; + enabled = modPath.find('~'); + if (enabled == std::string::npos) + { + GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath, true); + } + else + { + GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); + } +} + +void CPathManager::RemoveMod(const std::string &modPath) +{ + std::string::size_type enabled; + enabled = modPath.find('~'); + if (enabled == std::string::npos) + { + GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str()); + CResourceManager::RemoveLocation(modPath); + } } const std::string& CPathManager::GetDataPath() @@ -154,15 +175,33 @@ void CPathManager::InitPaths() GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str()); for (const std::string& modPath : FindModsInDir(modAutoloadDir)) { - GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath); + std::string::size_type enabled; + enabled = modPath.find('~'); + if (enabled == std::string::npos) + { + GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + else + { + GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); + } } } for (const std::string& modPath : m_mods) { - GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath); + std::string::size_type enabled; + enabled = modPath.find('~'); + if (enabled == std::string::npos) + { + GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + else + { + GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); + } } CResourceManager::SetSaveLocation(m_savePath); diff --git a/src/app/pathman.h b/src/app/pathman.h index 561f66f3..9cd9ffe1 100644 --- a/src/app/pathman.h +++ b/src/app/pathman.h @@ -39,6 +39,7 @@ public: void SetSavePath(const std::string &savePath); void AddModAutoloadDir(const std::string &modAutoloadDirPath); void AddMod(const std::string &modPath); + void RemoveMod(const std::string &modPath); const std::string& GetDataPath(); const std::string& GetLangPath(); diff --git a/src/common/event.cpp b/src/common/event.cpp index 214fd20e..3de67fc1 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -201,6 +201,7 @@ void InitializeEventTypeTexts() EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPp] = "EVENT_INTERFACE_SETUPp"; EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPc] = "EVENT_INTERFACE_SETUPc"; EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPs] = "EVENT_INTERFACE_SETUPs"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPm] = "EVENT_INTERFACE_SETUPm"; EVENT_TYPE_TEXT[EVENT_INTERFACE_DEVICE] = "EVENT_INTERFACE_DEVICE"; EVENT_TYPE_TEXT[EVENT_INTERFACE_RESOL] = "EVENT_INTERFACE_RESOL"; @@ -272,6 +273,13 @@ void InitializeEventTypeTexts() EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT"; EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_UNLOADED] = "EVENT_INTERFACE_MODS_UNLOADED"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_LOADED] = "EVENT_INTERFACE_MODS_LOADED"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_WORKSHOP] = "EVENT_INTERFACE_WORKSHOP"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_DIR] = "EVENT_INTERFACE_MODS_DIR"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_LOAD] = "EVENT_INTERFACE_LOAD"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_UNLOAD] = "EVENT_INTERFACE_UNLOAD"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTl] = "EVENT_INTERFACE_GLINTl"; EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTr] = "EVENT_INTERFACE_GLINTr"; EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTu] = "EVENT_INTERFACE_GLINTu"; diff --git a/src/common/event.h b/src/common/event.h index c2029e82..91d79439 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -236,6 +236,7 @@ enum EventType EVENT_INTERFACE_SETUPp = 432, EVENT_INTERFACE_SETUPc = 433, EVENT_INTERFACE_SETUPs = 434, + EVENT_INTERFACE_SETUPm = 435, EVENT_INTERFACE_DEVICE = 440, EVENT_INTERFACE_RESOL = 441, @@ -311,6 +312,13 @@ enum EventType EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT = 573, EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT = 574, + EVENT_INTERFACE_MODS_UNLOADED = 580, + EVENT_INTERFACE_MODS_LOADED = 581, + EVENT_INTERFACE_WORKSHOP = 582, + EVENT_INTERFACE_MODS_DIR = 583, + EVENT_INTERFACE_LOAD = 584, + EVENT_INTERFACE_UNLOAD = 585, + EVENT_INTERFACE_GLINTl = 590, EVENT_INTERFACE_GLINTr = 591, EVENT_INTERFACE_GLINTu = 592, diff --git a/src/common/restext.cpp b/src/common/restext.cpp index cd05d59f..74fb31ed 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -92,6 +92,9 @@ void InitializeRestext() stringsText[RT_SETUP_KEY1] = TR("1) First click on the key you want to redefine."); stringsText[RT_SETUP_KEY2] = TR("2) Then press the key you want to use instead."); + stringsText[RT_MODS_UNLOADED] = TR("Unloaded Mods:"); + stringsText[RT_MODS_LOADED] = TR("Loaded Mods:"); + stringsText[RT_PERSO_FACE] = TR("Face type:"); stringsText[RT_PERSO_GLASSES] = TR("Eyeglasses:"); stringsText[RT_PERSO_HAIR] = TR("Hair color:"); @@ -182,11 +185,16 @@ void InitializeRestext() stringsEvent[EVENT_INTERFACE_QUIT] = TR("Quit\\Quit Colobot: Gold Edition"); stringsEvent[EVENT_INTERFACE_BACK] = TR("<< Back \\Back to the previous screen"); stringsEvent[EVENT_INTERFACE_PLAY] = TR("Play\\Start mission!"); + stringsEvent[EVENT_INTERFACE_WORKSHOP] = TR("Workshop\\Open Workshop to search Mods"); + stringsEvent[EVENT_INTERFACE_MODS_DIR] = TR("Open Directory\\Open Mods directory"); + stringsEvent[EVENT_INTERFACE_LOAD] = TR("Load\\Load Mod"); + stringsEvent[EVENT_INTERFACE_UNLOAD] = TR("Unload\\Unload Mod"); stringsEvent[EVENT_INTERFACE_SETUPd] = TR("Device\\Driver and resolution settings"); stringsEvent[EVENT_INTERFACE_SETUPg] = TR("Graphics\\Graphics settings"); stringsEvent[EVENT_INTERFACE_SETUPp] = TR("Game\\Game settings"); stringsEvent[EVENT_INTERFACE_SETUPc] = TR("Controls\\Keyboard, joystick and mouse settings"); stringsEvent[EVENT_INTERFACE_SETUPs] = TR("Sound\\Music and game sound volume"); + stringsEvent[EVENT_INTERFACE_SETUPm] = TR("Mods\\Manage installed mods"); stringsEvent[EVENT_INTERFACE_DEVICE] = TR("Unit"); stringsEvent[EVENT_INTERFACE_RESOL] = TR("Resolution"); stringsEvent[EVENT_INTERFACE_FULL] = TR("Full screen\\Full screen or window mode"); diff --git a/src/common/restext.h b/src/common/restext.h index c33a864f..824481d5 100644 --- a/src/common/restext.h +++ b/src/common/restext.h @@ -86,6 +86,9 @@ enum ResTextType RT_SETUP_KEY1 = 82, RT_SETUP_KEY2 = 83, + RT_MODS_UNLOADED = 85, + RT_MODS_LOADED = 86, + RT_PERSO_FACE = 90, RT_PERSO_GLASSES = 91, RT_PERSO_HAIR = 92, diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index a815964d..f1ede192 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -215,3 +215,13 @@ std::string CSystemUtils::GetEnvVar(const std::string& name) { return ""; } + +void CSystemUtils::OpenPath(std::string path) +{ + assert(false); +} + +void CSystemUtils::OpenWebsite(std::string website) +{ + assert(false); +} diff --git a/src/common/system/system.h b/src/common/system/system.h index ebc92269..a5e01245 100644 --- a/src/common/system/system.h +++ b/src/common/system/system.h @@ -145,6 +145,12 @@ public: //! Returns the environment variable with the given name or an empty string if it does not exist virtual std::string GetEnvVar(const std::string &name); + //! Opens a path with default file browser + virtual void OpenPath(std::string path); + + //! Opens a website with default web browser + virtual void OpenWebsite(std::string website); + //! Sleep for given amount of microseconds virtual void Usleep(int usecs) = 0; diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index 459c071f..a531e45e 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -150,6 +150,28 @@ std::string CSystemUtilsLinux::GetEnvVar(const std::string& name) return ""; } +void CSystemUtilsLinux::OpenPath(std::string path) +{ + int result; + + result = system(("xdg-open \""+path+"\"").c_str()); + if (result == -1) + { + GetLogger()->Error("Failed to open path: %s\n", path.c_str()); + } +} + +void CSystemUtilsLinux::OpenWebsite(std::string website) +{ + int result; + + result = system(("xdg-open \""+website+"\"").c_str()); + if (result == -1) + { + GetLogger()->Error("Failed to open website: %s\n", website.c_str()); + } +} + void CSystemUtilsLinux::Usleep(int usec) { usleep(usec); diff --git a/src/common/system/system_linux.h b/src/common/system/system_linux.h index b3446aa6..e14da475 100644 --- a/src/common/system/system_linux.h +++ b/src/common/system/system_linux.h @@ -48,6 +48,9 @@ public: std::string GetEnvVar(const std::string& name) override; + void OpenPath(std::string path) override; + void OpenWebsite(std::string website) override; + void Usleep(int usec) override; private: diff --git a/src/common/system/system_macosx.cpp b/src/common/system/system_macosx.cpp index 752cf98f..761a68ea 100644 --- a/src/common/system/system_macosx.cpp +++ b/src/common/system/system_macosx.cpp @@ -119,6 +119,28 @@ std::string CSystemUtilsMacOSX::GetEnvVar(const std::string& str) return std::string(); } +void CSystemUtilsLinux::OpenPath(std::string path) +{ + int result; + + result = system(("open \""+path+"\"").c_str()); // TODO: Test on macOS + if (result == -1) + { + GetLogger()->Error("Failed to open path: %s\n", path.c_str()); + } +} + +void CSystemUtilsLinux::OpenWebsite(std::string website) +{ + int result; + + result = system(("open \""+website+"\"").c_str()); // TODO: Test on macOS + if (result == -1) + { + GetLogger()->Error("Failed to open website: %s\n", website.c_str()); + } +} + void CSystemUtilsMacOSX::Usleep(int usec) { usleep(usec); diff --git a/src/common/system/system_macosx.h b/src/common/system/system_macosx.h index dc3f785a..08b7b91e 100644 --- a/src/common/system/system_macosx.h +++ b/src/common/system/system_macosx.h @@ -38,6 +38,9 @@ public: std::string GetEnvVar(const std::string& name) override; + void OpenPath(std::string path) override; + void OpenWebsite(std::string website) override; + void Usleep(int usec) override; private: diff --git a/src/common/system/system_other.cpp b/src/common/system/system_other.cpp index 865db847..549c9af1 100644 --- a/src/common/system/system_other.cpp +++ b/src/common/system/system_other.cpp @@ -44,6 +44,16 @@ long long int CSystemUtilsOther::TimeStampExactDiff(SystemTimeStamp* before, Sys return (after->sdlTicks - before->sdlTicks) * 1000000ll; } +void CSystemUtilsOther::OpenPath(std::string path) +{ + // TODO +} + +void CSystemUtilsOther::OpenWebsite(std::string website) +{ + // TODO +} + void CSystemUtilsOther::Usleep(int usec) { SDL_Delay(usec / 1000); // close enough diff --git a/src/common/system/system_other.h b/src/common/system/system_other.h index 5964b585..c27d7d52 100644 --- a/src/common/system/system_other.h +++ b/src/common/system/system_other.h @@ -50,6 +50,9 @@ public: void GetCurrentTimeStamp(SystemTimeStamp *stamp) override; long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override; + void OpenPath(std::string path) override; + void OpenWebsite(std::string website) override; + void Usleep(int usec) override; }; diff --git a/src/common/system/system_windows.cpp b/src/common/system/system_windows.cpp index 413b0575..21a77aa9 100644 --- a/src/common/system/system_windows.cpp +++ b/src/common/system/system_windows.cpp @@ -152,6 +152,28 @@ std::string CSystemUtilsWindows::GetEnvVar(const std::string& name) } } +void CSystemUtilsWindows::OpenPath(std::string path) +{ + int result; + + result = system(("explorer \""+path+"\"").c_str()); // TODO: Test on macOS + if (result == -1) + { + GetLogger()->Error("Failed to open path: %s\n", path.c_str()); + } +} + +void CSystemUtilsWindows::OpenWebsite(std::string website) +{ + int result; + + result = system(("rundll32 url.dll,FileProtocolHandler \""+website+"\"").c_str()); // TODO: Test on macOS + if (result == -1) + { + GetLogger()->Error("Failed to open website: %s\n", website.c_str()); + } +} + void CSystemUtilsWindows::Usleep(int usec) { LARGE_INTEGER ft; diff --git a/src/common/system/system_windows.h b/src/common/system/system_windows.h index 4bbd704f..e3b98f20 100644 --- a/src/common/system/system_windows.h +++ b/src/common/system/system_windows.h @@ -46,6 +46,9 @@ public: std::string GetEnvVar(const std::string& name) override; + void OpenPath(std::string path) override; + void OpenWebsite(std::string website) override; + void Usleep(int usec) override; public: diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index af455819..aee24f34 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1189,6 +1189,10 @@ public: void EnablePauseBlur(); void DisablePauseBlur(); + //! Reloads all textures + /** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/ + void ReloadAllTextures(); + protected: //! Resets some states and flushes textures after device was changed (e.g. resoulution changed) /** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/ @@ -1287,10 +1291,6 @@ protected: }; static void WriteScreenShotThread(std::unique_ptr data); - //! Reloads all textures - /** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/ - void ReloadAllTextures(); - protected: CApplication* m_app; CSystemUtils* m_systemUtils; diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 484a7374..4306dae8 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -262,6 +262,8 @@ void CText::FlushCache() m_lastCachedFont = nullptr; m_lastFontType = FONT_COMMON; m_lastFontSize = 0; + + Create(); } int CText::GetTabSize() diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 1a51c7e1..b9e3633f 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -326,11 +326,13 @@ std::string PhaseToString(Phase phase) if (phase == PHASE_SETUPp) return "PHASE_SETUPp"; if (phase == PHASE_SETUPc) return "PHASE_SETUPc"; if (phase == PHASE_SETUPs) return "PHASE_SETUPs"; + if (phase == PHASE_SETUPm) return "PHASE_SETUPm"; if (phase == PHASE_SETUPds) return "PHASE_SETUPds"; if (phase == PHASE_SETUPgs) return "PHASE_SETUPgs"; if (phase == PHASE_SETUPps) return "PHASE_SETUPps"; if (phase == PHASE_SETUPcs) return "PHASE_SETUPcs"; if (phase == PHASE_SETUPss) return "PHASE_SETUPss"; + if (phase == PHASE_SETUPms) return "PHASE_SETUPms"; if (phase == PHASE_WRITEs) return "PHASE_WRITEs"; if (phase == PHASE_READ) return "PHASE_READ"; if (phase == PHASE_READs) return "PHASE_READs"; @@ -343,7 +345,7 @@ std::string PhaseToString(Phase phase) bool IsInSimulationConfigPhase(Phase phase) { - return (phase >= PHASE_SETUPds && phase <= PHASE_SETUPss) || phase == PHASE_READs || phase == PHASE_WRITEs; + return (phase >= PHASE_SETUPds && phase <= PHASE_SETUPms) || phase == PHASE_READs || phase == PHASE_WRITEs; } bool IsPhaseWithWorld(Phase phase) @@ -3911,6 +3913,7 @@ void CRobotMain::ChangeColor() m_phase != PHASE_SETUPps && m_phase != PHASE_SETUPcs && m_phase != PHASE_SETUPss && + m_phase != PHASE_SETUPms && m_phase != PHASE_WIN && m_phase != PHASE_LOST && m_phase != PHASE_APPERANCE ) return; diff --git a/src/level/robotmain.h b/src/level/robotmain.h index e95d6671..b339cfdc 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -61,11 +61,13 @@ enum Phase PHASE_SETUPp, PHASE_SETUPc, PHASE_SETUPs, + PHASE_SETUPm, PHASE_SETUPds, PHASE_SETUPgs, PHASE_SETUPps, PHASE_SETUPcs, PHASE_SETUPss, + PHASE_SETUPms, PHASE_WRITEs, PHASE_READ, PHASE_READs, diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index 5cdfdd47..b21070fb 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -107,6 +107,7 @@ bool CMainDialog::EventProcess(const Event &event) if ( CScreenSetup::GetTab() == PHASE_SETUPp ) m_main->ChangePhase(PHASE_SETUPps); if ( CScreenSetup::GetTab() == PHASE_SETUPc ) m_main->ChangePhase(PHASE_SETUPcs); if ( CScreenSetup::GetTab() == PHASE_SETUPs ) m_main->ChangePhase(PHASE_SETUPss); + if ( CScreenSetup::GetTab() == PHASE_SETUPm ) m_main->ChangePhase(PHASE_SETUPss); } if ( pressedButton == EVENT_INTERFACE_WRITE ) diff --git a/src/ui/mainui.cpp b/src/ui/mainui.cpp index 4070e5ec..ab737e12 100644 --- a/src/ui/mainui.cpp +++ b/src/ui/mainui.cpp @@ -55,6 +55,7 @@ #include "ui/screen/screen_setup_display.h" #include "ui/screen/screen_setup_game.h" #include "ui/screen/screen_setup_graphics.h" +#include "ui/screen/screen_setup_mods.h" #include "ui/screen/screen_setup_sound.h" #include "ui/screen/screen_welcome.h" @@ -84,6 +85,7 @@ CMainUserInterface::CMainUserInterface() m_screenSetupDisplay = MakeUnique(); m_screenSetupGame = MakeUnique(); m_screenSetupGraphics = MakeUnique(); + m_screenSetupMods = MakeUnique(); m_screenSetupSound = MakeUnique(); m_screenMainMenu = MakeUnique(); m_screenPlayerSelect = MakeUnique(m_dialog.get()); @@ -144,6 +146,7 @@ CScreenSetup* CMainUserInterface::GetSetupScreen(Phase phase) if(phase == PHASE_SETUPp) return m_screenSetupGame.get(); if(phase == PHASE_SETUPc) return m_screenSetupControls.get(); if(phase == PHASE_SETUPs) return m_screenSetupSound.get(); + if(phase == PHASE_SETUPm) return m_screenSetupMods.get(); assert(false); return nullptr; } @@ -184,14 +187,14 @@ void CMainUserInterface::ChangePhase(Phase phase) m_screenLevelList->SetLevelCategory(m_main->GetLevelCategory()); m_currentScreen = m_screenLevelList.get(); } - if (m_phase >= PHASE_SETUPd && m_phase <= PHASE_SETUPs) + if (m_phase >= PHASE_SETUPd && m_phase <= PHASE_SETUPm) { CScreenSetup* screenSetup = GetSetupScreen(m_phase); screenSetup->SetInSimulation(false); screenSetup->SetActive(); m_currentScreen = screenSetup; } - if (m_phase >= PHASE_SETUPds && m_phase <= PHASE_SETUPss) + if (m_phase >= PHASE_SETUPds && m_phase <= PHASE_SETUPms) { CScreenSetup* screenSetup = GetSetupScreen(static_cast(m_phase - PHASE_SETUPds + PHASE_SETUPd)); screenSetup->SetInSimulation(true); @@ -347,6 +350,7 @@ void CMainUserInterface::GlintMove() m_phase == PHASE_SETUPp || m_phase == PHASE_SETUPc || m_phase == PHASE_SETUPs || + m_phase == PHASE_SETUPm || m_phase == PHASE_SETUPds || m_phase == PHASE_SETUPgs || m_phase == PHASE_SETUPps || @@ -536,6 +540,7 @@ void CMainUserInterface::FrameParticle(float rTime) m_phase == PHASE_SETUPp || m_phase == PHASE_SETUPc || m_phase == PHASE_SETUPs || + m_phase == PHASE_SETUPm || m_phase == PHASE_READ ) { pParti = partiPosBig; diff --git a/src/ui/mainui.h b/src/ui/mainui.h index 50888f5b..76440a40 100644 --- a/src/ui/mainui.h +++ b/src/ui/mainui.h @@ -57,6 +57,7 @@ class CScreenSetupControls; class CScreenSetupDisplay; class CScreenSetupGame; class CScreenSetupGraphics; +class CScreenSetupMods; class CScreenSetupSound; class CScreenWelcome; @@ -120,6 +121,7 @@ protected: std::unique_ptr m_screenSetupDisplay; std::unique_ptr m_screenSetupGame; std::unique_ptr m_screenSetupGraphics; + std::unique_ptr m_screenSetupMods; std::unique_ptr m_screenSetupSound; std::unique_ptr m_screenWelcome; diff --git a/src/ui/screen/screen_setup.cpp b/src/ui/screen/screen_setup.cpp index 67848640..7a83ae1e 100644 --- a/src/ui/screen/screen_setup.cpp +++ b/src/ui/screen/screen_setup.cpp @@ -83,7 +83,7 @@ void CScreenSetup::CreateInterface() ddim.y = 0.05f; pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray - ddim.x = 0.78f/5-0.01f; + ddim.x = 0.65f/5-0.01f; ddim.y = 0.06f; pos.x = 0.115f; pos.y = 0.76f; @@ -116,6 +116,12 @@ void CScreenSetup::CreateInterface() pb->SetState(STATE_CARD); pb->SetState(STATE_CHECK, (m_tab == PHASE_SETUPs)); + pos.x += ddim.x+0.01f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPm); + pb->SetState(STATE_SHADOW); + pb->SetState(STATE_CARD); + pb->SetState(STATE_CHECK, (m_tab == PHASE_SETUPm)); + pos.x = 0.10f; ddim.x = 0.80f; pos.y = 0.34f; @@ -148,6 +154,10 @@ bool CScreenSetup::EventProcess(const Event &event) CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); if ( pw == nullptr ) return false; + CButton* pb = static_cast(pw->SearchControl(EVENT_INTERFACE_SETUPm)); + if ( pb == nullptr ) return false; + pb->SetState(STATE_ENABLE); + if ( event.type == pw->GetEventTypeClose() || event.type == EVENT_INTERFACE_BACK || (event.type == EVENT_KEY_DOWN && event.GetData()->key == KEY(ESCAPE)) ) @@ -179,6 +189,10 @@ bool CScreenSetup::EventProcess(const Event &event) m_main->ChangePhase(PHASE_SETUPs); return false; + case EVENT_INTERFACE_SETUPm: + m_main->ChangePhase(PHASE_SETUPm); + return false; + default: break; } @@ -188,6 +202,10 @@ bool CScreenSetup::EventProcess(const Event &event) CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); if ( pw == nullptr ) return false; + CButton* pb = static_cast(pw->SearchControl(EVENT_INTERFACE_SETUPm)); + if ( pb == nullptr ) return false; + pb->ClearState(STATE_ENABLE); + if ( event.type == pw->GetEventTypeClose() || event.type == EVENT_INTERFACE_BACK || (event.type == EVENT_KEY_DOWN && event.GetData()->key == KEY(ESCAPE)) ) @@ -221,6 +239,9 @@ bool CScreenSetup::EventProcess(const Event &event) m_main->ChangePhase(PHASE_SETUPss); return false; + case EVENT_INTERFACE_SETUPm: + assert(false); // should never get here + default: break; } diff --git a/src/ui/screen/screen_setup_mods.cpp b/src/ui/screen/screen_setup_mods.cpp new file mode 100644 index 00000000..3779ee32 --- /dev/null +++ b/src/ui/screen/screen_setup_mods.cpp @@ -0,0 +1,291 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "ui/screen/screen_setup_mods.h" + +#include "app/app.h" +#include "app/pathman.h" + +#include "common/system/system.h" + +#include "common/restext.h" +#include "common/config.h" +#include "common/logger.h" +#include "common/settings.h" + +#include "common/resources/resourcemanager.h" +#include "level/parser/parser.h" + +#include "ui/controls/button.h" +#include "ui/controls/edit.h" +#include "ui/controls/interface.h" +#include "ui/controls/label.h" +#include "ui/controls/list.h" +#include "ui/controls/window.h" + +#include +#include +#include + +using namespace boost::filesystem; + +namespace Ui +{ + +CScreenSetupMods::CScreenSetupMods() +{ +} + +void CScreenSetupMods::SetActive() +{ + m_tab = PHASE_SETUPm; +} + +void CScreenSetupMods::CreateInterface() +{ + CWindow* pw; + CLabel* pl; + CButton* pb; + CList* pli; + Math::Point pos, ddim; + std::string name; + + CScreenSetup::CreateInterface(); + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) return; + + // Displays a list of unloaded mods: + pos.x = ox+sx*3; + pos.y = oy+sy*9; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_TEXT, RT_MODS_UNLOADED, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name); + pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); + + pos.y = oy+sy*3.75f; + ddim.x = dim.x*6.5f; + ddim.y = dim.y*6.05f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MODS_UNLOADED); + pli->SetState(STATE_SHADOW); + UpdateUnloadedModList(); + + // Displays a list of loaded mods: + pos.x = ox+sx*9.5f; + pos.y = oy+sy*9; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_TEXT, RT_MODS_LOADED, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name); + pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); + + pos.y = oy+sy*3.75f; + ddim.x = dim.x*6.5f; + ddim.y = dim.y*6.05f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MODS_LOADED); + pli->SetState(STATE_SHADOW); + UpdateLoadedModList(); + + pos = pli->GetPos(); + ddim = pli->GetDim(); + pos.x = ox+sx*8.2f; + pos.y = oy+sy*2; + ddim.x = dim.x*1; + ddim.y = dim.y*1; + pb = pw->CreateButton(pos, ddim, 40, EVENT_INTERFACE_WORKSHOP); + pb->SetState(STATE_SHADOW); + + pos.x += dim.x*1.3f; + pb = pw->CreateButton(pos, ddim, 57, EVENT_INTERFACE_MODS_DIR); + pb->SetState(STATE_SHADOW); + + pos.x += dim.x*1.3f; + ddim.x = dim.x*2.5f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_LOAD); + pb->SetState(STATE_SHADOW); + pb->ClearState(STATE_ENABLE); + + pos.x += dim.x*2.8f; + pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_UNLOAD); + pb->SetState(STATE_SHADOW); + pb->ClearState(STATE_ENABLE); +} +bool CScreenSetupMods::EventProcess(const Event &event) +{ + CWindow* pw; + CButton* pb; + CList* pl; + std::string modName, modPath, website = "https://www.moddb.com/games/colobot-gold-edition"; + auto systemUtils = CSystemUtils::Create(); // platform-specific utils + + if (!CScreenSetup::EventProcess(event)) return false; + + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) return false; + + if (event.type == EVENT_INTERFACE_LOAD) + { + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED)); + if ( pl == nullptr ) return false; + modName = pl->GetItemName(pl->GetSelect()); + LoadMod(modName); + + m_app->Reload(); + m_main->ChangePhase(PHASE_SETUPm); + } + if (event.type == EVENT_INTERFACE_UNLOAD) + { + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED)); + if ( pl == nullptr ) return false; + modName = pl->GetItemName(pl->GetSelect()); + UnloadMod(modName); + + m_app->Reload(); + m_main->ChangePhase(PHASE_SETUPm); + } + if (event.type == EVENT_INTERFACE_MODS_DIR) + { + modPath = CResourceManager::GetSaveLocation() + "/" + "mods"; + systemUtils->OpenPath(modPath); + } + switch (event.type) + { + case EVENT_INTERFACE_MODS_UNLOADED: + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED)); + if ( pl == nullptr ) break; + + pb = static_cast(pw->SearchControl(EVENT_INTERFACE_UNLOAD)); + if ( pb == nullptr ) break; + pl->SetSelect(-1); + pb->ClearState(STATE_ENABLE); + + pb = static_cast(pw->SearchControl(EVENT_INTERFACE_LOAD)); + if ( pb == nullptr ) break; + pb->SetState(STATE_ENABLE); + break; + + case EVENT_INTERFACE_MODS_LOADED: + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED)); + if ( pl == nullptr ) break; + + pb = static_cast(pw->SearchControl(EVENT_INTERFACE_LOAD)); + if ( pb == nullptr ) break; + pl->SetSelect(-1); + pb->ClearState(STATE_ENABLE); + + pb = static_cast(pw->SearchControl(EVENT_INTERFACE_UNLOAD)); + if ( pb == nullptr ) break; + pb->SetState(STATE_ENABLE); + break; + + case EVENT_INTERFACE_WORKSHOP: + systemUtils->OpenWebsite(website); + break; + default: + return true; + } + return false; +} + +void CScreenSetupMods::UnloadMod(std::string modName) +{ + std::string modPath, modPathRaw, disabled = "~"; + + modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; + modPath = modPathRaw.c_str(); + + m_pathManager->RemoveMod(modPath+modName); + boost::filesystem::rename(modPath+modName, modPath+disabled+modName); +} + +void CScreenSetupMods::LoadMod(std::string modName) +{ + std::string modPath, modPathRaw, disabled = "~"; + + modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; + modPath = modPathRaw.c_str(); + + boost::filesystem::rename(modPath+disabled+modName, modPath+modName); + m_pathManager->AddMod(modPath+modName); +} + +void CScreenSetupMods::UpdateUnloadedModList() +{ + CWindow* pw; + CList* pl; + int i = 0; + std::string modPath, modPathRaw; + directory_iterator end_itr; + + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) return; + + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED)); + if ( pl == nullptr ) return; + pl->Flush(); + + modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; + modPath = modPathRaw.c_str(); + + for (directory_iterator itr(modPath); itr != end_itr; ++itr) + { + std::string modName = itr->path().string(); + boost::erase_all(modName, modPath); + std::string::size_type enabled; + enabled = modName.find('~'); + if (enabled != std::string::npos) + { + modName.erase(0,1); + pl->SetItemName(i++, modName); + } + } + + pl->ShowSelect(false); // shows the selected columns +} +void CScreenSetupMods::UpdateLoadedModList() +{ + CWindow* pw; + CList* pl; + int i = 0; + std::string modPath, modPathRaw; + directory_iterator end_itr; + + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) return; + + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED)); + if ( pl == nullptr ) return; + pl->Flush(); + + modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; + modPath = modPathRaw.c_str(); + + for (directory_iterator itr(modPath); itr != end_itr; ++itr) + { + std::string modName = itr->path().string(); + boost::erase_all(modName, modPath); + std::string::size_type enabled; + enabled = modName.find('~'); + if (enabled == std::string::npos) + pl->SetItemName(i++, modName); + } + + pl->ShowSelect(false); // shows the selected columns +} +} // namespace Ui diff --git a/src/ui/screen/screen_setup_mods.h b/src/ui/screen/screen_setup_mods.h new file mode 100644 index 00000000..e61d75bc --- /dev/null +++ b/src/ui/screen/screen_setup_mods.h @@ -0,0 +1,52 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "ui/screen/screen_setup.h" + +#include + +class CPathManager; + +namespace Ui +{ + +class CScreenSetupMods : public CScreenSetup +{ +public: + CScreenSetupMods(); + void SetActive() override; + + void CreateInterface() override; + bool EventProcess(const Event &event) override; + +protected: + void UnloadMod(std::string ModName); + void LoadMod(std::string ModName); + void UpdateUnloadedModList(); + void UpdateLoadedModList(); + +protected: + CPathManager* m_pathManager; + std::vector m_unloadedModList; + std::vector m_loadedModList; +}; + +} // namespace Ui