diff --git a/client/CMT.cpp b/client/CMT.cpp index 9e95e2966..13b31c89f 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -258,7 +258,7 @@ int main(int argc, char * argv[]) // Init filesystem and settings preinitDLL(::console); - settings.init(); + Settings session = settings.write["session"]; auto setSettingBool = [](std::string key, std::string arg) { Settings s = settings.write(vstd::split(key, "/")); diff --git a/config/schemas/mod.json b/config/schemas/mod.json index 855e13b69..7ee8a4057 100644 --- a/config/schemas/mod.json +++ b/config/schemas/mod.json @@ -91,7 +91,7 @@ "language" : { "type":"string", "description": "Base language of the mod, before applying localizations. By default vcmi assumes English", - "enum" : [ "chinese", "english", "german", "polish", "russian", "ukrainian" ], + "enum" : [ "chinese", "english", "korean", "german", "polish", "russian", "ukrainian" ], }, "depends": { "type":"array", @@ -125,12 +125,18 @@ "type":"boolean", "description": "If set to true, mod will not be enabled automatically on install" }, + "chinese" : { + "$ref" : "#/definitions/localizable" + }, "english" : { "$ref" : "#/definitions/localizable" }, "german" : { "$ref" : "#/definitions/localizable" }, + "korean" : { + "$ref" : "#/definitions/localizable" + }, "polish" : { "$ref" : "#/definitions/localizable" }, diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 651e095c9..e884ec46a 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -22,6 +22,7 @@ "music", "sound", "language", + "gameDataLanguage", "swipe", "swipeDesktop", "saveRandomMaps", @@ -66,6 +67,11 @@ "enum" : [ "chinese", "english", "german", "polish", "russian", "ukrainian" ], "default" : "english" }, + "gameDataLanguage" : { + "type":"string", + "enum" : [ "auto", "chinese", "english", "german", "korean", "polish", "russian", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ], + "default" : "auto" + }, "lastSave" : { "type":"string", "default" : "NEWGAME" @@ -440,7 +446,7 @@ "type" : "object", "default": {}, "additionalProperties" : false, - "required" : [ "repositoryURL", "enableInstalledMods", "extraResolutionsModPath", "autoCheckRepositories", "updateOnStartup", "updateConfigUrl", "lobbyUrl", "lobbyPort", "lobbyUsername", "connectionTimeout" ], + "required" : [ "setupCompleted", "repositoryURL", "enableInstalledMods", "extraResolutionsModPath", "autoCheckRepositories", "updateOnStartup", "updateConfigUrl", "lobbyUrl", "lobbyPort", "lobbyUsername", "connectionTimeout" ], "properties" : { "repositoryURL" : { "type" : "array", @@ -451,6 +457,10 @@ "type" : "string" } }, + "setupCompleted" : { + "type" : "boolean", + "default" : false + }, "enableInstalledMods" : { "type" : "boolean", "default" : true diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 5eaef18a6..34b4605b9 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1,35 +1,16 @@ -set(launcher_modmanager_SRCS +set(launcher_SRCS + StdInc.cpp modManager/cdownloadmanager_moc.cpp modManager/cmodlist.cpp modManager/cmodlistmodel_moc.cpp modManager/cmodlistview_moc.cpp modManager/cmodmanager.cpp modManager/imageviewer_moc.cpp -) - -set(launcher_modmanager_HEADERS - modManager/cdownloadmanager_moc.h - modManager/cmodlist.h - modManager/cmodlistmodel_moc.h - modManager/cmodlistview_moc.h - modManager/cmodmanager.h - modManager/imageviewer_moc.h -) - -set(launcher_settingsview_SRCS settingsView/csettingsview_moc.cpp -) - -set(launcher_settingsview_HEADERS - settingsView/csettingsview_moc.h -) - -set(launcher_SRCS - StdInc.cpp - ${launcher_modmanager_SRCS} - ${launcher_settingsview_SRCS} + firstLaunch/firstlaunch_moc.cpp main.cpp mainwindow_moc.cpp + languages.cpp launcherdirs.cpp jsonutils.cpp updatedialog_moc.cpp @@ -40,9 +21,16 @@ set(launcher_SRCS set(launcher_HEADERS StdInc.h - ${launcher_modmanager_HEADERS} - ${launcher_settingsview_HEADERS} + modManager/cdownloadmanager_moc.h + modManager/cmodlist.h + modManager/cmodlistmodel_moc.h + modManager/cmodlistview_moc.h + modManager/cmodmanager.h + modManager/imageviewer_moc.h + settingsView/csettingsview_moc.h + firstLaunch/firstlaunch_moc.h mainwindow_moc.h + languages.h launcherdirs.h jsonutils.h updatedialog_moc.h @@ -56,6 +44,7 @@ set(launcher_FORMS modManager/cmodlistview_moc.ui modManager/imageviewer_moc.ui settingsView/csettingsview_moc.ui + firstLaunch/firstlaunch_moc.ui mainwindow_moc.ui updatedialog_moc.ui lobby/lobby_moc.ui diff --git a/launcher/firstLaunch/firstlaunch_moc.cpp b/launcher/firstLaunch/firstlaunch_moc.cpp new file mode 100644 index 000000000..b9df75f56 --- /dev/null +++ b/launcher/firstLaunch/firstlaunch_moc.cpp @@ -0,0 +1,396 @@ +/* + * firstlaunch_moc.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" +#include "firstlaunch_moc.h" +#include "ui_firstlaunch_moc.h" + +#include "mainwindow_moc.h" +#include "modManager/cmodlistview_moc.h" + +#include "../../lib/CConfigHandler.h" +#include "../../lib/CGeneralTextHandler.h" +#include "../../lib/Languages.h" +#include "../../lib/VCMIDirs.h" +#include "../../lib/filesystem/Filesystem.h" +#include "../languages.h" + +FirstLaunchView::FirstLaunchView(QWidget * parent) + : QWidget(parent) + , ui(new Ui::FirstLaunchView) +{ + ui->setupUi(this); + + enterSetup(); + activateTabLanguage(); + + ui->lineEditDataSystem->setText(pathToQString(boost::filesystem::absolute(VCMIDirs::get().dataPaths().front()))); + ui->lineEditDataUser->setText(pathToQString(boost::filesystem::absolute(VCMIDirs::get().userDataPath()))); +} + +void FirstLaunchView::on_buttonTabLanguage_clicked() +{ + activateTabLanguage(); +} + +void FirstLaunchView::on_buttonTabHeroesData_clicked() +{ + activateTabHeroesData(); +} + +void FirstLaunchView::on_buttonTabModPreset_clicked() +{ + activateTabModPreset(); +} + +void FirstLaunchView::on_listWidgetLanguage_currentRowChanged(int currentRow) +{ + languageSelected(ui->listWidgetLanguage->item(currentRow)->data(Qt::UserRole).toString()); +} + +void FirstLaunchView::changeEvent(QEvent * event) +{ + if(event->type() == QEvent::LanguageChange) + { + ui->retranslateUi(this); + Languages::fillLanguages(ui->listWidgetLanguage, false); + } + QWidget::changeEvent(event); +} + +void FirstLaunchView::on_pushButtonLanguageNext_clicked() +{ + activateTabHeroesData(); +} + +void FirstLaunchView::on_pushButtonDataNext_clicked() +{ + activateTabModPreset(); +} + +void FirstLaunchView::on_pushButtonDataBack_clicked() +{ + activateTabLanguage(); +} + +void FirstLaunchView::on_pushButtonDataSearch_clicked() +{ + heroesDataUpdate(); +} + +void FirstLaunchView::on_pushButtonDataCopy_clicked() +{ + copyHeroesData(); +} + +void FirstLaunchView::on_pushButtonDataHelp_clicked() +{ + static const QUrl vcmibuilderWiki("https://wiki.vcmi.eu/Installation_on_Linux#Installing_Heroes_III_data_files"); + QDesktopServices::openUrl(vcmibuilderWiki); +} + +void FirstLaunchView::on_comboBoxLanguage_currentIndexChanged(int index) +{ + forceHeroesLanguage(ui->comboBoxLanguage->itemData(index).toString()); +} + +void FirstLaunchView::enterSetup() +{ + Languages::fillLanguages(ui->listWidgetLanguage, false); +} + +void FirstLaunchView::setSetupProgress(int progress) +{ + int value = std::max(progress, ui->setupProgressBar->value()); + + ui->setupProgressBar->setValue(value); + + ui->buttonTabLanguage->setDisabled(value < 1); + ui->buttonTabHeroesData->setDisabled(value < 2); + ui->buttonTabModPreset->setDisabled(value < 3); +} + +void FirstLaunchView::activateTabLanguage() +{ + setSetupProgress(1); + ui->installerTabs->setCurrentIndex(0); + ui->buttonTabLanguage->setChecked(true); + ui->buttonTabHeroesData->setChecked(false); + ui->buttonTabModPreset->setChecked(false); +} + +void FirstLaunchView::activateTabHeroesData() +{ + setSetupProgress(2); + ui->installerTabs->setCurrentIndex(1); + ui->buttonTabLanguage->setChecked(false); + ui->buttonTabHeroesData->setChecked(true); + ui->buttonTabModPreset->setChecked(false); + + if(!hasVCMIBuilderScript) + { + ui->pushButtonDataHelp->hide(); + ui->labelDataHelp->hide(); + } + heroesDataUpdate(); +} + +void FirstLaunchView::activateTabModPreset() +{ + setSetupProgress(3); + ui->installerTabs->setCurrentIndex(2); + ui->buttonTabLanguage->setChecked(false); + ui->buttonTabHeroesData->setChecked(false); + ui->buttonTabModPreset->setChecked(true); + + modPresetUpdate(); +} + +void FirstLaunchView::exitSetup() +{ + if(auto * mainWindow = dynamic_cast(qApp->activeWindow())) + mainWindow->exitSetup(); +} + +// Tab Language +void FirstLaunchView::languageSelected(const QString & selectedLanguage) +{ + Settings node = settings.write["general"]["language"]; + node->String() = selectedLanguage.toStdString(); + + if(auto * mainWindow = dynamic_cast(qApp->activeWindow())) + mainWindow->updateTranslation(); +} + +void FirstLaunchView::heroesDataUpdate() +{ + if(heroesDataDetect()) + heroesDataDetected(); + else + heroesDataMissing(); +} + +void FirstLaunchView::heroesDataMissing() +{ + QPalette newPalette = palette(); + newPalette.setColor(QPalette::Base, QColor(200, 50, 50)); + ui->lineEditDataSystem->setPalette(newPalette); + ui->lineEditDataUser->setPalette(newPalette); + + ui->pushButtonDataSearch->setVisible(true); + ui->pushButtonDataCopy->setVisible(true); + + ui->labelDataSearch->setVisible(true); + ui->labelDataCopy->setVisible(true); + + ui->labelDataFound->setVisible(false); + + if(hasVCMIBuilderScript) + { + ui->pushButtonDataHelp->setVisible(true); + ui->labelDataHelp->setVisible(true); + } +} + +void FirstLaunchView::heroesDataDetected() +{ + QPalette newPalette = palette(); + newPalette.setColor(QPalette::Base, QColor(50, 200, 50)); + ui->lineEditDataSystem->setPalette(newPalette); + ui->lineEditDataUser->setPalette(newPalette); + + ui->pushButtonDataSearch->setVisible(false); + ui->pushButtonDataCopy->setVisible(false); + + ui->labelDataSearch->setVisible(false); + ui->labelDataCopy->setVisible(false); + + if(hasVCMIBuilderScript) + { + ui->pushButtonDataHelp->setVisible(false); + ui->labelDataHelp->setVisible(false); + } + + ui->labelDataFound->setVisible(true); + + heroesLanguageUpdate(); +} + +// Tab Heroes III Data +bool FirstLaunchView::heroesDataDetect() +{ + // user might have copied files to one of our data path. + // perform full reinitialization of virtual filesystem + CResourceHandler::destroy(); + CResourceHandler::initialize(); + CResourceHandler::load("config/filesystem.json"); + + // use file from lod archive to check presence of H3 data. Very rough estimate, but will work in majority of cases + bool heroesDataFound = CResourceHandler::get()->existsResource(ResourceID("DATA/GENRLTXT.TXT")); + + return heroesDataFound; +} + +void FirstLaunchView::heroesLanguageUpdate() +{ + Languages::fillLanguages(ui->comboBoxLanguage, true); + + QString language = Languages::getHeroesDataLanguage(); + bool success = !language.isEmpty(); + + ui->labelDataFailure->setVisible(!success); + ui->labelDataSuccess->setVisible(success); + ui->pushButtonDataNext->setEnabled(success); +} + +void FirstLaunchView::forceHeroesLanguage(const QString & language) +{ + Settings node = settings.write["general"]["gameDataLanguage"]; + + node->String() = language.toStdString(); +} + +void FirstLaunchView::copyHeroesData() +{ + QDir sourceRoot = QFileDialog::getExistingDirectory(this, "", "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + if(!sourceRoot.exists()) + return; + + QStringList dirData = sourceRoot.entryList({"data"}, QDir::Filter::Dirs); + QStringList dirMaps = sourceRoot.entryList({"maps"}, QDir::Filter::Dirs); + QStringList dirMp3 = sourceRoot.entryList({"mp3"}, QDir::Filter::Dirs); + + if(dirData.empty() || dirMaps.empty() || dirMp3.empty()) + return; + + QDir sourceData = sourceRoot.filePath(dirData.front()); + QStringList lodArchives = sourceData.entryList({"*.lod"}, QDir::Filter::Files); + + if(lodArchives.empty()) + return; + + QStringList copyDirectories = {dirData.front(), dirMaps.front(), dirMp3.front()}; + + QDir targetRoot = pathToQString(VCMIDirs::get().userDataPath()); + + for(const QString & dirName : copyDirectories) + { + QDir sourceDir = sourceRoot.filePath(dirName); + QDir targetDir = targetRoot.filePath(dirName); + + if(!targetRoot.exists(dirName)) + targetRoot.mkdir(dirName); + + for(const QString & filename : sourceDir.entryList(QDir::Filter::Files)) + { + QFile sourceFile(sourceDir.filePath(filename)); + sourceFile.copy(targetDir.filePath(filename)); + } + } + + heroesDataUpdate(); +} + +// Tab Mod Preset +void FirstLaunchView::modPresetUpdate() +{ + bool translationExists = !findTranslationModName().isEmpty(); + + ui->labelPresetLanguage->setVisible(translationExists); + ui->checkBoxPresetLanguage->setVisible(translationExists); + + ui->checkBoxPresetLanguage->setEnabled(checkCanInstallTranslation()); + ui->checkBoxPresetExtras->setEnabled(checkCanInstallExtras()); + ui->checkBoxPresetHota->setEnabled(checkCanInstallHota()); + ui->checkBoxPresetWog->setEnabled(checkCanInstallWog()); +} + +QString FirstLaunchView::findTranslationModName() +{ + if (!getModView()) + return QString(); + + QString preferredlanguage = QString::fromStdString(settings["general"]["language"].String()); + QString installedlanguage = QString::fromStdString(settings["session"]["language"].String()); + + if (preferredlanguage == installedlanguage) + return QString(); + + return getModView()->getTranslationModName(preferredlanguage); +} + +bool FirstLaunchView::checkCanInstallTranslation() +{ + QString modName = findTranslationModName(); + + if(modName.isEmpty()) + return false; + + return checkCanInstallMod(modName); +} + +bool FirstLaunchView::checkCanInstallWog() +{ + return checkCanInstallMod("wake-of-gods"); +} + +bool FirstLaunchView::checkCanInstallHota() +{ + return checkCanInstallMod("hota"); +} + +bool FirstLaunchView::checkCanInstallExtras() +{ + return checkCanInstallMod("vcmi-extras"); +} + +CModListView * FirstLaunchView::getModView() +{ + auto * mainWindow = dynamic_cast(qApp->activeWindow()); + + assert(mainWindow); + if (!mainWindow) + return nullptr; + + return mainWindow->getModView(); +} + +bool FirstLaunchView::checkCanInstallMod(const QString & modID) +{ + return getModView() && !getModView()->isModInstalled(modID); +} + +void FirstLaunchView::on_pushButtonPresetBack_clicked() +{ + activateTabHeroesData(); +} + +void FirstLaunchView::on_pushButtonPresetNext_clicked() +{ + QStringList modsToInstall; + + if (ui->checkBoxPresetLanguage && checkCanInstallTranslation()) + modsToInstall.push_back(findTranslationModName()); + + if (ui->checkBoxPresetExtras && checkCanInstallExtras()) + modsToInstall.push_back("vcmi-extras"); + + if (ui->checkBoxPresetWog && checkCanInstallWog()) + modsToInstall.push_back("wake-of-gods"); + + if (ui->checkBoxPresetHota && checkCanInstallHota()) + modsToInstall.push_back("hota"); + + exitSetup(); + + for (auto const & modName : modsToInstall) + getModView()->doInstallMod(modName); +} + diff --git a/launcher/firstLaunch/firstlaunch_moc.h b/launcher/firstLaunch/firstlaunch_moc.h new file mode 100644 index 000000000..340a98311 --- /dev/null +++ b/launcher/firstLaunch/firstlaunch_moc.h @@ -0,0 +1,99 @@ +/* + * firstlaunch_moc.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once +#include "../StdInc.h" + +namespace Ui +{ +class FirstLaunchView; +} + +class CModListView; + +class FirstLaunchView : public QWidget +{ + Q_OBJECT + + // vcmibuilder script is not available on these platforms +#if defined(VCMI_WINDOWS) || defined(VCMI_MOBILE) || defined(VCMI_APPLE) + static constexpr bool hasVCMIBuilderScript = false; +#else + static constexpr bool hasVCMIBuilderScript = true; +#endif + + void changeEvent(QEvent *event); + CModListView * getModView(); + + void setSetupProgress(int progress); + void enterSetup(); + void activateTabLanguage(); + void activateTabHeroesData(); + void activateTabModPreset(); + void exitSetup(); + + // Tab Language + void languageSelected(const QString & languageCode); + + // Tab Heroes III Data + void heroesDataUpdate(); + bool heroesDataDetect(); + + void heroesDataMissing(); + void heroesDataDetected(); + + void heroesLanguageUpdate(); + void forceHeroesLanguage(const QString & language); + + void copyHeroesData(); + + // Tab Mod Preset + void modPresetUpdate(); + + QString findTranslationModName(); + + bool checkCanInstallTranslation(); + bool checkCanInstallWog(); + bool checkCanInstallHota(); + bool checkCanInstallExtras(); + bool checkCanInstallMod(const QString & modID); + + void installMod(const QString & modID); + +public: + explicit FirstLaunchView(QWidget * parent = 0); + +public slots: + +private slots: + + void on_buttonTabLanguage_clicked(); + void on_buttonTabHeroesData_clicked(); + void on_buttonTabModPreset_clicked(); + void on_listWidgetLanguage_currentRowChanged(int currentRow); + void on_pushButtonLanguageNext_clicked(); + void on_pushButtonDataNext_clicked(); + void on_pushButtonDataBack_clicked(); + + void on_pushButtonDataSearch_clicked(); + + void on_pushButtonDataCopy_clicked(); + + void on_pushButtonDataHelp_clicked(); + + void on_comboBoxLanguage_currentIndexChanged(int index); + + void on_pushButtonPresetBack_clicked(); + + void on_pushButtonPresetNext_clicked(); + +private: + Ui::FirstLaunchView * ui; + +}; diff --git a/launcher/firstLaunch/firstlaunch_moc.ui b/launcher/firstLaunch/firstlaunch_moc.ui new file mode 100644 index 000000000..a120ada53 --- /dev/null +++ b/launcher/firstLaunch/firstlaunch_moc.ui @@ -0,0 +1,735 @@ + + + FirstLaunchView + + + + 0 + 0 + 650 + 409 + + + + + + + + + + + + + 0 + 0 + + + + Language + + + true + + + true + + + Qt::ToolButtonTextOnly + + + true + + + + + + + + 0 + 0 + + + + Heroes III Data + + + true + + + true + + + Qt::ToolButtonTextOnly + + + true + + + + + + + + 0 + 0 + + + + Mods Preset + + + true + + + true + + + Qt::ToolButtonTextOnly + + + true + + + + + + + + + 0 + + + 3 + + + 0 + + + true + + + Step %v out of %m + + + + + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 75 + true + + + + Choose your language + + + + + + + Next + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 5 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 75 + true + + + + Find Heroes III data files + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + 6 + + + + + + 25 + 0 + + + + Open help in browser + + + + + + + + 25 + 0 + + + + Search again + + + + + + + true + + + + 50 + 0 + + + + true + + + + + + + true + + + + 50 + 0 + + + + true + + + + + + + + 100 + 0 + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + true + + + + + + + + 100 + 0 + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + true + + + + + + + + 50 + 0 + + + + + 75 + true + + + + Heroes III data files + + + + + + + + 100 + 0 + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + true + + + + + + + + 25 + 0 + + + + Copy existing data + + + + + + + + 100 + 0 + + + + Your Heroes III data files have been successfully found. + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + 6 + + + + + Your Heroes III language has been successfully detected. + + + true + + + + + + + Automatic detection of language failed. Please select language of your Heroes III copy + + + true + + + + + + + + + + + 75 + true + + + + Heroes III language + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + 6 + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 20 + 20 + + + + + + + + Back + + + + + + + Next + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 75 + true + + + + Install VCMI Mod Preset + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 100 + 0 + + + + Optionally, you can install additional mods either now or at any point later: + + + true + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + 100 + 0 + + + + Install translation of Heroes III to your language + + + true + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + 100 + 0 + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + true + + + + + + + + 0 + 0 + + + + + + + + + + + + 100 + 0 + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + true + + + + + + + + 0 + 0 + + + + + + + + + + + + 100 + 0 + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Back + + + + + + + Finish + + + + + + + + + + + + + + diff --git a/launcher/languages.cpp b/launcher/languages.cpp new file mode 100644 index 000000000..cf8e1b4dc --- /dev/null +++ b/launcher/languages.cpp @@ -0,0 +1,150 @@ +/* + * languages.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" +#include "languages.h" + +#include "../lib/CConfigHandler.h" +#include "../lib/Languages.h" +#include "../lib/CGeneralTextHandler.h" + +#include +#include + +// list of language names, for generation of translations. Do not use directly, use Languages namespace instead +static const std::array languageTranslatedNamesGenerator = { + { + QT_TRANSLATE_NOOP("Language", "Chinese"), + QT_TRANSLATE_NOOP("Language", "English"), + QT_TRANSLATE_NOOP("Language", "French"), + QT_TRANSLATE_NOOP("Language", "German"), + QT_TRANSLATE_NOOP("Language", "Korean"), + QT_TRANSLATE_NOOP("Language", "Polish"), + QT_TRANSLATE_NOOP("Language", "Russian"), + QT_TRANSLATE_NOOP("Language", "Spanish"), + QT_TRANSLATE_NOOP("Language", "Ukrainian"), + QT_TRANSLATE_NOOP("Language", "Other (East European)"), + QT_TRANSLATE_NOOP("Language", "Other (Cyrillic Script)"), + QT_TRANSLATE_NOOP("Language", "Other (West European)"), + } +}; + +static_assert(languageTranslatedNamesGenerator.size() == static_cast(Languages::ELanguages::COUNT), "Languages array is missing a value!"); + +QString Languages::getHeroesDataLanguage() +{ + CGeneralTextHandler::detectInstallParameters(); + + QString language = QString::fromStdString(settings["session"]["language"].String()); + double deviation = settings["session"]["languageDeviation"].Float(); + + if(deviation > 0.05) + return QString(); + return language; +} + +QString generateAutodetectedLanguageName(QString const & language) +{ + std::string languageNameEnglish = Languages::getLanguageOptions(language.toStdString()).nameEnglish; + QString languageName = QApplication::translate( "Language", languageNameEnglish.c_str()); + QString itemName = QApplication::translate("Language", "Auto (%1)").arg(languageName); + + return itemName; +} + +QString Languages::generateLanguageName(const Languages::Options & language) +{ + std::string activeLanguage = settings["general"]["language"].String(); + + QString localizedName = QApplication::translate("Language", language.nameEnglish.c_str()); + QString nativeName = language.nameNative.c_str(); + + if(!language.hasTranslation) + return localizedName; + + if(activeLanguage == language.identifier) + return nativeName; + + QString displayName = QString("%1 (%2)").arg(localizedName, nativeName); + + return displayName; +} + +void Languages::fillLanguages(QComboBox * widget, bool includeAll) +{ + widget->blockSignals(true); // we do not want calls caused by initialization + widget->clear(); + + std::string activeLanguage = includeAll ? + settings["general"]["gameDataLanguage"].String(): + settings["general"]["language"].String(); + + if (includeAll) + { + QString language = getHeroesDataLanguage(); + if (!language.isEmpty()) + widget->addItem(generateAutodetectedLanguageName(language), QString("auto")); + + if (activeLanguage == "auto") + widget->setCurrentIndex(0); + } + + for(const auto & language : Languages::getLanguageList()) + { + if (!language.hasTranslation && !includeAll) + continue; + + QString displayName = generateLanguageName(language); + QVariant userData = QString::fromStdString(language.identifier); + + widget->addItem(displayName, userData); + if(activeLanguage == language.identifier) + widget->setCurrentIndex(widget->count() - 1); + } + + widget->blockSignals(false); +} + +void Languages::fillLanguages(QListWidget * widget, bool includeAll) +{ + widget->blockSignals(true); // we do not want calls caused by initialization + widget->clear(); + + std::string activeLanguage = includeAll ? + settings["general"]["gameDataLanguage"].String(): + settings["general"]["language"].String(); + + if (includeAll) + { + QString language = getHeroesDataLanguage(); + if (!language.isEmpty()) + { + widget->addItem(generateAutodetectedLanguageName(language)); + widget->item(widget->count() - 1)->setData(Qt::UserRole, QString("auto")); + + if (activeLanguage == "auto") + widget->setCurrentRow(0); + } + } + + for(const auto & language : Languages::getLanguageList()) + { + if (!language.hasTranslation && !includeAll) + continue; + + QString displayName = generateLanguageName(language); + QVariant userData = QString::fromStdString(language.identifier); + + widget->addItem(displayName); + widget->item(widget->count() - 1)->setData(Qt::UserRole, userData); + if(activeLanguage == language.identifier) + widget->setCurrentRow(widget->count() - 1); + } + widget->blockSignals(false); +} diff --git a/launcher/languages.h b/launcher/languages.h new file mode 100644 index 000000000..97b6f3149 --- /dev/null +++ b/launcher/languages.h @@ -0,0 +1,27 @@ +/* + * languages.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +class QString; +class QComboBox; +class QListWidget; + +namespace Languages +{ + struct Options; + + QString generateLanguageName(const Languages::Options & identifier); + QString getHeroesDataLanguage(); + + /// if includeAll is set, all languages including encoding placeholders will be included into widget + void fillLanguages(QComboBox * widget, bool includeAll); + void fillLanguages(QListWidget * widget, bool includeAll); + +} diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp index f76798404..6833ccd7d 100644 --- a/launcher/mainwindow_moc.cpp +++ b/launcher/mainwindow_moc.cpp @@ -102,7 +102,13 @@ MainWindow::MainWindow(QWidget * parent) computeSidePanelSizes(); - ui->tabListWidget->setCurrentIndex(0); + bool h3DataFound = CResourceHandler::get()->existsResource(ResourceID("DATA/GENRLTXT.TXT")); + bool setupCompleted = settings["launcher"]["setupCompleted"].Bool(); + + if (h3DataFound && setupCompleted) + ui->tabListWidget->setCurrentIndex(TabRows::MODS); + else + enterSetup(); ui->settingsView->isExtraResolutionsModEnabled = ui->modlistView->isExtraResolutionsModEnabled(); ui->settingsView->setDisplayList(); @@ -113,6 +119,35 @@ MainWindow::MainWindow(QWidget * parent) UpdateDialog::showUpdateDialog(false); } +void MainWindow::enterSetup() +{ + ui->startGameButton->setEnabled(false); + ui->startEditorButton->setEnabled(false); + ui->lobbyButton->setEnabled(false); + ui->settingsButton->setEnabled(false); + ui->modslistButton->setEnabled(false); + ui->tabListWidget->setCurrentIndex(TabRows::SETUP); +} + +void MainWindow::exitSetup() +{ + Settings writer = settings.write["launcher"]["setupCompleted"]; + writer->Bool() = true; + + ui->startGameButton->setEnabled(true); + ui->startEditorButton->setEnabled(true); + ui->lobbyButton->setEnabled(true); + ui->settingsButton->setEnabled(true); + ui->modslistButton->setEnabled(true); + ui->tabListWidget->setCurrentIndex(TabRows::MODS); +} + +void MainWindow::switchToModsTab() +{ + ui->startGameButton->setEnabled(true); + ui->tabListWidget->setCurrentIndex(TabRows::MODS); +} + void MainWindow::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) @@ -147,10 +182,14 @@ const CModList & MainWindow::getModList() const return ui->modlistView->getModList(); } +CModListView * MainWindow::getModView() +{ + return ui->modlistView; +} + void MainWindow::on_modslistButton_clicked() { - ui->startGameButton->setEnabled(true); - ui->tabListWidget->setCurrentIndex(TabRows::MODS); + switchToModsTab(); } void MainWindow::on_settingsButton_clicked() diff --git a/launcher/mainwindow_moc.h b/launcher/mainwindow_moc.h index b7505635d..f16329ee3 100644 --- a/launcher/mainwindow_moc.h +++ b/launcher/mainwindow_moc.h @@ -21,7 +21,7 @@ const QString appName = "VCMI Launcher"; class QTableWidgetItem; class CModList; - +class CModListView; class MainWindow : public QMainWindow { @@ -36,19 +36,27 @@ private: enum TabRows { - MODS = 0, SETTINGS = 1, LOBBY = 2 + MODS = 0, + SETTINGS = 1, + LOBBY = 2, + SETUP = 3 }; void changeEvent(QEvent *event) override; public: - explicit MainWindow(QWidget * parent = 0); - ~MainWindow(); + explicit MainWindow(QWidget * parent = nullptr); + ~MainWindow() override; const CModList & getModList() const; + CModListView * getModView(); void updateTranslation(); void computeSidePanelSizes(); + void enterSetup(); + void exitSetup(); + void switchToModsTab(); + public slots: void on_startGameButton_clicked(); diff --git a/launcher/mainwindow_moc.ui b/launcher/mainwindow_moc.ui index 9665d131f..0f98adf27 100644 --- a/launcher/mainwindow_moc.ui +++ b/launcher/mainwindow_moc.ui @@ -7,7 +7,7 @@ 0 0 800 - 410 + 490 @@ -316,11 +316,12 @@ - 0 + 3 + @@ -346,6 +347,12 @@
lobby/lobby_moc.h
1 + + FirstLaunchView + QWidget +
firstLaunch/firstlaunch_moc.h
+ 1 +
diff --git a/launcher/modManager/cmodlist.cpp b/launcher/modManager/cmodlist.cpp index 8c0e27fc6..cc52a8bb6 100644 --- a/launcher/modManager/cmodlist.cpp +++ b/launcher/modManager/cmodlist.cpp @@ -139,6 +139,11 @@ bool CModEntry::isValid() const return !localData.isEmpty() || !repository.isEmpty(); } +bool CModEntry::isTranslation() const +{ + return getBaseValue("modType").toString().toLower() == "translation"; +} + int CModEntry::getModStatus() const { int status = 0; @@ -158,6 +163,17 @@ QString CModEntry::getName() const } QVariant CModEntry::getValue(QString value) const +{ + return getValueImpl(value, true); +} + +QVariant CModEntry::getBaseValue(QString value) const +{ + return getValueImpl(value, false); +} + +QVariant CModEntry::getValueImpl(QString value, bool localized) const + { QString langValue = QString::fromStdString(settings["general"]["language"].String()); @@ -178,7 +194,7 @@ QVariant CModEntry::getValue(QString value) const auto & storage = useRepositoryData ? repository : localData; - if(storage.contains(langValue)) + if(localized && storage.contains(langValue)) { auto langStorage = storage[langValue].toMap(); if (langStorage.contains(value)) diff --git a/launcher/modManager/cmodlist.h b/launcher/modManager/cmodlist.h index 0b3cc76b8..b8a9276ae 100644 --- a/launcher/modManager/cmodlist.h +++ b/launcher/modManager/cmodlist.h @@ -42,6 +42,7 @@ class CModEntry QString modname; + QVariant getValueImpl(QString value, bool localized) const; public: CModEntry(QVariantMap repository, QVariantMap localData, QVariantMap modSettings, QString modname); @@ -61,6 +62,8 @@ public: bool isCompatible() const; // returns if has any data bool isValid() const; + // installed and enabled + bool isTranslation() const; // see ModStatus enum int getModStatus() const; @@ -69,6 +72,7 @@ public: // get value of some field in mod structure. Returns empty optional if value is not present QVariant getValue(QString value) const; + QVariant getBaseValue(QString value) const; // returns true if less < greater comparing versions section by section static bool compareVersions(QString lesser, QString greater); diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp index 6ebfad9c8..679a8a5e8 100644 --- a/launcher/modManager/cmodlistview_moc.cpp +++ b/launcher/modManager/cmodlistview_moc.cpp @@ -90,19 +90,21 @@ void CModListView::setupModsView() } CModListView::CModListView(QWidget * parent) - : QWidget(parent), settingsListener(settings.listen["launcher"]["repositoryURL"]), ui(new Ui::CModListView) + : QWidget(parent) + , settingsListener(settings.listen["launcher"]["repositoryURL"]) + , ui(new Ui::CModListView) + , repositoriesChanged(false) { settingsListener([&](const JsonNode &){ repositoriesChanged = true; }); ui->setupUi(this); - setupModModel(); setupFilterModel(); setupModsView(); ui->progressWidget->setVisible(false); dlManager = nullptr; - disableModInfo(); + if(settings["launcher"]["autoCheckRepositories"].Bool()) { loadRepositories(); @@ -814,3 +816,45 @@ const CModList & CModListView::getModList() const assert(modModel); return *modModel; } + +void CModListView::doInstallMod(const QString & modName) +{ + assert(findInvalidDependencies(modName).empty()); + + for(auto & name : modModel->getRequirements(modName)) + { + auto mod = modModel->getMod(name); + if(!mod.isInstalled()) + downloadFile(name + ".zip", mod.getValue("download").toString(), "mods"); + } +} + +bool CModListView::isModInstalled(const QString & modName) +{ + auto mod = modModel->getMod(modName); + return mod.isInstalled(); +} + +bool CModListView::isModEnabled(const QString & modName) +{ + auto mod = modModel->getMod(modName); + return mod.isEnabled(); +} + +QString CModListView::getTranslationModName(const QString & language) +{ + for(const auto & modName : modModel->getModList()) + { + auto mod = modModel->getMod(modName); + + if (!mod.isTranslation()) + continue; + + if (mod.getBaseValue("language").toString() != language) + continue; + + return modName; + } + + return QString(); +} diff --git a/launcher/modManager/cmodlistview_moc.h b/launcher/modManager/cmodlistview_moc.h index db13c29eb..7b7566339 100644 --- a/launcher/modManager/cmodlistview_moc.h +++ b/launcher/modManager/cmodlistview_moc.h @@ -74,7 +74,6 @@ public: void loadScreenshots(); - void enableModInfo(); void disableModInfo(); void selectMod(const QModelIndex & index); @@ -82,6 +81,20 @@ public: const CModList & getModList() const; + // First Launch View interface + + /// install mod by name + void doInstallMod(const QString & modName); + + /// returns true if mod is currently installed + bool isModInstalled(const QString & modName); + + /// finds translation mod for specified languages. Returns empty string on error + QString getTranslationModName(const QString & language); + + /// returns true if mod is currently enabled + bool isModEnabled(const QString & modName); + public slots: void enableModByName(QString modName); void disableModByName(QString modName); diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 7ed92c7e5..3f464f688 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -13,7 +13,9 @@ #include "mainwindow_moc.h" +#include "../modManager/cmodlistview_moc.h" #include "../jsonutils.h" +#include "../languages.h" #include "../launcherdirs.h" #include "../updatedialog_moc.h" @@ -29,18 +31,6 @@ QString resolutionToString(const QSize & resolution) { return QString{"%1x%2"}.arg(resolution.width()).arg(resolution.height()); } -} - -/// List of tags of languages that can be selected from Launcher (and have translation for Launcher) -static const std::string languageTagList[] = -{ - "chinese", - "english", - "german", - "polish", - "russian", - "ukrainian", -}; static const std::string cursorTypesList[] = { @@ -49,6 +39,8 @@ static const std::string cursorTypesList[] = "software" }; +} + void CSettingsView::setDisplayList() { QStringList list; @@ -92,12 +84,13 @@ void CSettingsView::loadSettings() ui->spinBoxNetworkPort->setValue(settings["server"]["port"].Integer()); ui->comboBoxAutoCheck->setCurrentIndex(settings["launcher"]["autoCheckRepositories"].Bool()); - // all calls to plainText will trigger textChanged() signal overwriting config. Create backup before editing widget - JsonNode urls = settings["launcher"]["repositoryURL"]; + JsonNode urls = settings["launcher"]["repositoryURL"]; + ui->plainTextEditRepos->blockSignals(true); // Do not report loading as change of data ui->plainTextEditRepos->clear(); for(auto entry : urls.Vector()) ui->plainTextEditRepos->appendPlainText(QString::fromUtf8(entry.String().c_str())); + ui->plainTextEditRepos->blockSignals(false); ui->lineEditUserDataDir->setText(pathToQString(VCMIDirs::get().userDataPath())); ui->lineEditGameDir->setText(pathToQString(VCMIDirs::get().binaryPath())); @@ -105,10 +98,7 @@ void CSettingsView::loadSettings() ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0); - std::string language = settings["general"]["language"].String(); - size_t languageIndex = boost::range::find(languageTagList, language) - languageTagList; - if(languageIndex < ui->comboBoxLanguage->count()) - ui->comboBoxLanguage->setCurrentIndex((int)languageIndex); + Languages::fillLanguages(ui->comboBoxLanguage, false); std::string cursorType = settings["video"]["cursor"].String(); size_t cursorTypeIndex = boost::range::find(cursorTypesList, cursorType) - cursorTypesList; @@ -308,13 +298,13 @@ void CSettingsView::on_updatesButton_clicked() UpdateDialog::showUpdateDialog(true); } - void CSettingsView::on_comboBoxLanguage_currentIndexChanged(int index) { Settings node = settings.write["general"]["language"]; - node->String() = languageTagList[index]; + QString selectedLanguage = ui->comboBoxLanguage->itemData(index).toString(); + node->String() = selectedLanguage.toStdString(); - if ( auto mainWindow = dynamic_cast(qApp->activeWindow()) ) + if(auto * mainWindow = dynamic_cast(qApp->activeWindow())) mainWindow->updateTranslation(); } @@ -323,17 +313,24 @@ void CSettingsView::changeEvent(QEvent *event) if(event->type() == QEvent::LanguageChange) { ui->retranslateUi(this); + Languages::fillLanguages(ui->comboBoxLanguage, false); + loadTranslation(); } QWidget::changeEvent(event); } +void CSettingsView::showEvent(QShowEvent * event) +{ + loadTranslation(); + QWidget::showEvent(event); +} + void CSettingsView::on_comboBoxCursorType_currentIndexChanged(int index) { Settings node = settings.write["video"]["cursor"]; node->String() = cursorTypesList[index]; } - void CSettingsView::on_listWidgetSettings_currentRowChanged(int currentRow) { QVector targetWidgets = { @@ -352,5 +349,84 @@ void CSettingsView::on_listWidgetSettings_currentRowChanged(int currentRow) int maxPosition = ui->settingsScrollArea->verticalScrollBar()->maximum(); ui->settingsScrollArea->verticalScrollBar()->setValue(maxPosition); ui->settingsScrollArea->ensureWidgetVisible(currentTarget, 5, 5); - +} + +void CSettingsView::loadTranslation() +{ + Languages::fillLanguages(ui->comboBoxLanguageBase, true); + + QString baseLanguage = Languages::getHeroesDataLanguage(); + + auto * mainWindow = dynamic_cast(qApp->activeWindow()); + + if (!mainWindow) + return; + + QString languageName = QString::fromStdString(settings["general"]["language"].String()); + QString modName = mainWindow->getModView()->getTranslationModName(languageName); + bool translationExists = !modName.isEmpty(); + bool translationNeeded = languageName != baseLanguage; + bool showTranslation = translationNeeded && translationExists; + + ui->labelTranslation->setVisible(showTranslation); + ui->labelTranslationStatus->setVisible(showTranslation); + ui->pushButtonTranslation->setVisible(showTranslation); + + if (!translationExists) + return; + + bool translationInstalled = mainWindow->getModView()->isModInstalled(modName); + bool translationEnabled = mainWindow->getModView()->isModEnabled(modName); + + ui->pushButtonTranslation->setVisible(!translationEnabled); + + if (translationEnabled) + { + ui->labelTranslationStatus->setText(tr("Active")); + } + + if (translationInstalled && !translationEnabled) + { + ui->labelTranslationStatus->setText(tr("Disabled")); + ui->pushButtonTranslation->setText(tr("Enable")); + } + + if (!translationInstalled) + { + ui->labelTranslationStatus->setText(tr("Not Installed")); + ui->pushButtonTranslation->setText(tr("Install")); + } +} + +void CSettingsView::on_pushButtonTranslation_clicked() +{ + auto * mainWindow = dynamic_cast(qApp->activeWindow()); + + assert(mainWindow); + if (!mainWindow) + return; + + QString languageName = QString::fromStdString(settings["general"]["language"].String()); + QString modName = mainWindow->getModView()->getTranslationModName(languageName); + + assert(!modName.isEmpty()); + if (modName.isEmpty()) + return; + + if (mainWindow->getModView()->isModInstalled(modName)) + { + mainWindow->getModView()->enableModByName(modName); + } + else + { + mainWindow->switchToModsTab(); + mainWindow->getModView()->doInstallMod(modName); + } +} + +void CSettingsView::on_comboBoxLanguageBase_currentIndexChanged(int index) +{ + Settings node = settings.write["general"]["gameDataLanguage"]; + QString selectedLanguage = ui->comboBoxLanguageBase->itemData(index).toString(); + node->String() = selectedLanguage.toStdString(); } diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 967a4a565..49cdb822a 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -24,8 +24,10 @@ public: ~CSettingsView(); void loadSettings(); + void loadTranslation(); void setDisplayList(); void changeEvent(QEvent *event) override; + void showEvent(QShowEvent * event) override; bool isExtraResolutionsModEnabled{}; @@ -34,44 +36,28 @@ public slots: private slots: void on_comboBoxResolution_currentTextChanged(const QString & arg1); - void on_comboBoxFullScreen_currentIndexChanged(int index); - void on_comboBoxPlayerAI_currentIndexChanged(const QString & arg1); - void on_comboBoxFriendlyAI_currentIndexChanged(const QString & arg1); - void on_comboBoxNeutralAI_currentIndexChanged(const QString & arg1); - void on_comboBoxEnemyAI_currentIndexChanged(const QString & arg1); - void on_spinBoxNetworkPort_valueChanged(int arg1); - void on_plainTextEditRepos_textChanged(); - void on_openTempDir_clicked(); - void on_openUserDataDir_clicked(); - void on_openGameDataDir_clicked(); - void on_comboBoxShowIntro_currentIndexChanged(int index); - void on_changeGameDataDir_clicked(); - void on_comboBoxAutoCheck_currentIndexChanged(int index); - void on_comboBoxDisplayIndex_currentIndexChanged(int index); - void on_comboBoxAutoSave_currentIndexChanged(int index); - void on_updatesButton_clicked(); - void on_comboBoxLanguage_currentIndexChanged(int index); - void on_comboBoxCursorType_currentIndexChanged(int index); - void on_listWidgetSettings_currentRowChanged(int currentRow); + void on_pushButtonTranslation_clicked(); + + void on_comboBoxLanguageBase_currentIndexChanged(int index); private: Ui::CSettingsView * ui; diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index 4592897ff..4e46c899f 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -114,59 +114,119 @@ 0 0 620 - 731 + 793 - - - - QPlainTextEdit::NoWrap + + + + false - - http://downloads.vcmi.eu/Mods/repository.json - - - - - - VCAI + BattleAI - VCAI + BattleAI - Nullkiller + StupidAI - - + + - Enemy AI + VCMI Language - - - - Update now - - - - + Network port - + + + + Fullscreen + + + + + + + Resolution + + + + + + + Neutral AI + + + + + + + Autosave + + + + + + + + 75 + true + + + + Video + + + + + + + false + + + /home/user/.vcmi + + + true + + + + + + + + + + Cursor + + + + + + + Open + + + + + + + false @@ -186,65 +246,7 @@ - - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - Autosave - - - - - - - /usr/share/vcmi - - - - - - - Open - - - - - - - Show intro - - - - - - - false - - - /home/user/.vcmi - - - true - - - - + 0 @@ -266,27 +268,27 @@ - - - - - 75 - true - + + + + 1024 - - Mod Repositories + + 65535 + + + 3030 - - + + - Display index + Open - + 1 @@ -303,8 +305,8 @@ - - + + 75 @@ -312,22 +314,77 @@ - Video + Data Directories - - - - Log files directory - - - - - - + + + false + + Change + + + + + + + User data directory + + + + + + + Build version + + + + + + + + 75 + true + + + + General + + + + + + + Show intro + + + + + + + Update now + + + + + + + Display index + + + + + + + /usr/share/vcmi + + + + + BattleAI @@ -343,31 +400,37 @@ - - + + + + + + + + 75 + true + + - Build version + Mod Repositories - - + + - Open + Friendly AI - - + + - - - - true + Check on startup - + 1 @@ -384,41 +447,105 @@ - - - - - 75 - true - + + + + false - Artificial Intelligence + /home/user/.vcmi + + + true - - + + - Resolution + Extra data directory - - + + - Cursor + Open - - + + + + + + + 1 + + + + Off + + + + + On + + + + + + - Neutral AI + Heroes III Data Language - + + + + VCAI + + + + VCAI + + + + + Nullkiller + + + + + + + + + + + true + + + + + + + Enemy AI + + + + + + + QPlainTextEdit::NoWrap + + + http://downloads.vcmi.eu/Mods/repository.json + + + + @@ -437,178 +564,51 @@ - - - - Check on startup - - - - - - - Open - - - - - - - Fullscreen - - - - - - - - - - - - - false + + + + + 75 + true + - /home/user/.vcmi - - - true + Artificial Intelligence - - + + - VCMI Language + Log files directory - - - - 1 - - - - Off - - - - - On - - - - - + Adventure Map AI - - - - - English - - - - - 简体中文 (Simplified Chinese) - - - - - Deutsch (German) - - - - - Polska (Polish) - - - - - Русский (Russian) - - - - - Українська (Ukrainian) - - - - - - - - - 75 - true - - + + - Data Directories + Heroes III Translation - - - - - 75 - true - - + + - General + - - + + - User data directory - - - - - - - Extra data directory - - - - - - - Friendly AI - - - - - - - 1024 - - - 65535 - - - 3030 - - - - - - - false - - - Change + diff --git a/launcher/translation/english.ts b/launcher/translation/english.ts index 3360d5869..d3bd72292 100644 --- a/launcher/translation/english.ts +++ b/launcher/translation/english.ts @@ -4,101 +4,86 @@ CModListModel - + Name - + Type - + Version - - - Size - - - - - Author - - CModListView - + Filter - + All mods - + Downloadable - + Installed - + Updatable - + Active - + Inactive - + Download && refresh repositories - - + + Description - + Changelog - + Screenshots - - Show details - - - - + Uninstall - + Enable @@ -108,134 +93,134 @@ - + Update - + Install - + %p% (%v KB out of %m KB) - + Abort - + Mod name - + Installed version - + Latest version - + Download size - + Authors - + License - - Home + + Contact - - + + Compatibility - - + + Required VCMI version - + Supported VCMI version - + Supported VCMI versions - + Required mods - + Conflicting mods - + This mod can not be installed or enabled because following dependencies are not present - + This mod can not be enabled because following mods are incompatible with this mod - + This mod can not be disabled because it is required to run following mods - + This mod can not be uninstalled or updated because it is required to run following mods - + This is submod and it can not be installed or uninstalled separately from parent mod - + Notes - + Screenshot %1 - + Mod is compatible - + Mod is incompatible @@ -243,216 +228,341 @@ CSettingsView - + Change - - - + + + Open - + + Adventure Map AI + + + + User data directory - - - - + + + + Off - - - - + + + Artificial Intelligence + + + + + + Mod Repositories + + + + + Update now + + + + + + + On - + + Cursor + + + + + Heroes III Data Language + + + + + Default + + + + + Hardware + + + + + Software + + + + + Heroes III Translation + + + + + Check on startup + + + + Fullscreen - - Repositories - - - - - Check for updates - - - - + Neutral AI - + Real - + + General - - Player AI - - - - + VCMI Language - - Central European (Windows 1250) - - - - - Cyrillic script (Windows 1251) - - - - - Western European (Windows 1252) - - - - - Simplified Chinese (GBK) - - - - - Simplified Chinese (GB2312) - - - - - Korean (Windows 949) - - - - - English - - - - - Deutsch (German) - - - - - Polska (Polish) - - - - - Русский (Russian) - - - - - Українська (Ukrainian) - - - - + Friendly AI - + Resolution - - AI on the map - - - - + Autosave - + Display index - - Check repositories on startup - - - - + Network port - + + Data Directories - + + Video - - Heroes III character set - - - - + Extra data directory - + Log files directory - + Show intro - - Launcher Settings - - - - + Build version - + Enemy AI - - AI in the battlefield + + Active + + + + + Disabled + + + + + Enable + + + + + Not Installed + + + + + Install + + + + + FirstLaunchView + + + Language + + + + + Heroes III Data + + + + + Mods Preset + + + + + Your Heroes III data files have been successfully found. + + + + + Optionally, you can install additional mods either now or at any point later: + + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + + + Finish + + + + + Step %v out of %m + + + + + Choose your language + + + + + + Next + + + + + Find Heroes III data files + + + + + Open help in browser + + + + + Search again + + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + + + Heroes III data files + + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + + + Copy existing data + + + + + Your Heroes III language has been successfully detected. + + + + + Automatic detection of language failed. Please select language of your Heroes III copy + + + + + Heroes III language + + + + + + Back + + + + + Install VCMI Mod Preset + + + + + Install translation of Heroes III to your language @@ -464,68 +574,172 @@ + + Language + + + Chinese + + + + + English + + + + + French + + + + + German + + + + + Korean + + + + + Polish + + + + + Russian + + + + + Spanish + + + + + Ukrainian + + + + + Other (East European) + + + + + Other (Cyrillic Script) + + + + + Other (West European) + + + + + Auto (%1) + + + Lobby - + + Connect - + Username - + Server - + + People in lobby + + + + + Lobby chat + + + + Session - + Players - + + Resolve + + + + + New game + + + + + Load game + + + + New room - + Join room - + Ready - + Mods mismatch - + Leave - + Kick player - + Players in the room + + + Disconnect + + + + + No issues detected + + LobbyRoomRequest @@ -558,27 +772,27 @@ - + Settings - + Map Editor - + Start game - + Lobby - + Mods diff --git a/launcher/translation/german.ts b/launcher/translation/german.ts index 48358d7d1..ad4592135 100644 --- a/launcher/translation/german.ts +++ b/launcher/translation/german.ts @@ -4,101 +4,86 @@ CModListModel - + Name Name - + Type Typ - + Version Version - - - Size - Größe - - - - Author - Autor - CModListView - + Filter Filter - + All mods Alle Mods - + Downloadable Herunterladbar - + Installed Installiert - + Updatable Aktualisierbar - + Active Aktiv - + Inactive Inaktiv - + Download && refresh repositories Repositories herunterladen && aktualisieren - - + + Description Beschreibung - + Changelog Änderungslog - + Screenshots Screenshots - - Show details - Details anzeigen - - - + Uninstall Deinstallieren - + Enable Aktivieren @@ -108,134 +93,134 @@ Deaktivieren - + Update Aktualisieren - + Install Installieren - + %p% (%v KB out of %m KB) %p% (%v КB von %m КB) - + Abort Abbrechen - + Mod name Mod-Name - + Installed version Installierte Version - + Latest version Letzte Version - + Download size Downloadgröße - + Authors Autoren - + License Lizenz - - Home - Home + + Contact + - - + + Compatibility Kompatibilität - - + + Required VCMI version Benötigte VCMI Version - + Supported VCMI version Unterstützte VCMI Version - + Supported VCMI versions Unterstützte VCMI Versionen - + Required mods Benötigte Mods - + Conflicting mods Mods mit Konflikt - + This mod can not be installed or enabled because following dependencies are not present Diese Mod kann nicht installiert oder aktiviert werden, da die folgenden Abhängigkeiten nicht vorhanden sind - + This mod can not be enabled because following mods are incompatible with this mod Diese Mod kann nicht aktiviert werden, da folgende Mods nicht mit dieser Mod kompatibel sind - + This mod can not be disabled because it is required to run following mods Diese Mod kann nicht deaktiviert werden, da sie zum Ausführen der folgenden Mods erforderlich ist - + This mod can not be uninstalled or updated because it is required to run following mods Diese Mod kann nicht deinstalliert oder aktualisiert werden, da sie für die folgenden Mods erforderlich ist - + This is submod and it can not be installed or uninstalled separately from parent mod Dies ist eine Submod und kann nicht separat von der Hauptmod installiert oder deinstalliert werden - + Notes Anmerkungen - + Screenshot %1 Screenshot %1 - + Mod is compatible Mod ist kompatibel - + Mod is incompatible Mod ist inkompatibel @@ -243,218 +228,343 @@ CSettingsView - + Change Ändern - - - + + + Open Öffnen - + + Adventure Map AI + + + + User data directory Verzeichnis der Benutzerdaten - - - - + + + + Off Aus - - - - + + + Artificial Intelligence + + + + + + Mod Repositories + + + + + Update now + + + + + + + On An - + + Cursor + + + + + Heroes III Data Language + + + + + Default + + + + + Hardware + + + + + Software + + + + + Heroes III Translation + + + + + Check on startup + + + + Fullscreen Vollbild - - AI in the battlefield - KI auf dem Schlachtfeld - - - - Repositories - Repositories - - - - Check for updates - Nach Aktualisierungen suchen - - - + Neutral AI Neutrale KI - + Real Vollständig - + + General Allgemein - - Player AI - Spieler-KI - - - + VCMI Language VCMI-Sprache - - Central European (Windows 1250) - Mitteleuropäisch (Windows 1250) - - - - Cyrillic script (Windows 1251) - Kyrillische Schrift (Windows 1251) - - - - Western European (Windows 1252) - Westeuropäisch (Windows 1252) - - - - Simplified Chinese (GBK) - Vereinfachtes Chinesisch (GBK) - - - - Simplified Chinese (GB2312) - Vereinfachtes Chinesisch (GB2312) - - - - Korean (Windows 949) - Koreanisch (Windows 949) - - - - English - English (Englisch) - - - - Deutsch (German) - Deutsch - - - - Polska (Polish) - Polska (Polnisch) - - - - Русский (Russian) - Русский (Russisch) - - - - Українська (Ukrainian) - Українська (Ukrainisch) - - - + Friendly AI Freundliche KI - + Resolution Auflösung - - AI on the map - KI auf der Karte - - - + Autosave Autospeichern - + Display index Anzeige-Index - - Check repositories on startup - Repositories beim Start prüfen - - - + Network port Netzwerk-Port - + + Data Directories Daten-Verzeichnisse - + + Video Video - - Heroes III character set - Heroes III Zeichensatz - - - + Extra data directory Zusätzliches Daten-Verzeichnis - + Log files directory Verzeichnis der Log-Dateien - + Show intro Intro anzeigen - - Launcher Settings - Launcher-Einstellungen - - - + Build version Version des Builds - + Enemy AI Feindliche KI + + + Active + Aktiv + + + + Disabled + + + + + Enable + Aktivieren + + + + Not Installed + + + + + Install + Installieren + + + + FirstLaunchView + + + Language + + + + + Heroes III Data + + + + + Mods Preset + + + + + Your Heroes III data files have been successfully found. + + + + + Optionally, you can install additional mods either now or at any point later: + + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + + + Finish + + + + + Step %v out of %m + + + + + Choose your language + + + + + + Next + + + + + Find Heroes III data files + + + + + Open help in browser + + + + + Search again + + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + + + Heroes III data files + + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + + + Copy existing data + + + + + Your Heroes III language has been successfully detected. + + + + + Automatic detection of language failed. Please select language of your Heroes III copy + + + + + Heroes III language + + + + + + Back + + + + + Install VCMI Mod Preset + + + + + Install translation of Heroes III to your language + + ImageViewer @@ -464,68 +574,172 @@ Bildbetrachter + + Language + + + Chinese + + + + + English + English (Englisch) + + + + French + + + + + German + + + + + Korean + + + + + Polish + + + + + Russian + + + + + Spanish + + + + + Ukrainian + + + + + Other (East European) + + + + + Other (Cyrillic Script) + + + + + Other (West European) + + + + + Auto (%1) + + + Lobby - + + Connect Verbinden - + Username Benutzername - + Server Server - + + People in lobby + + + + + Lobby chat + + + + Session Sitzung - + Players Spieler - + + Resolve + + + + + New game + + + + + Load game + + + + New room Neuer Raum - + Join room Raum beitreten - + Ready Bereit - + Mods mismatch Mods stimmen nicht überein - + Leave Verlassen - + Kick player Spieler kicken - + Players in the room Spieler im Raum + + + Disconnect + + + + + No issues detected + + LobbyRoomRequest @@ -558,31 +772,27 @@ VCMI Launcher - + Mods Mods - Editor - Editor - - - + Settings Einstellungen - + Lobby Lobby - + Map Editor - + Start game Spiel starten diff --git a/launcher/translation/polish.ts b/launcher/translation/polish.ts index 2521652c5..a6abadb69 100644 --- a/launcher/translation/polish.ts +++ b/launcher/translation/polish.ts @@ -4,101 +4,86 @@ CModListModel - + Name Nazwa - + Type Typ - + Version Wersja - - - Size - Rosmiar - - - - Author - Autor - CModListView - + Filter Filtruj - + All mods Wszystkie mody - + Downloadable Dostępny do pobrania - + Installed Zainstalowany - + Updatable Można zaktualizować - + Active Aktywny - + Inactive Nieaktywny - + Download && refresh repositories Pobierz i odśwież repozytoria - - + + Description Opis - + Changelog Lista zmian - + Screenshots Zrzuty ekranu - - Show details - Pokaż szczegóły - - - + Uninstall Odinstaluj - + Enable Włącz @@ -108,134 +93,134 @@ Wyłącz - + Update Zaktualizuj - + Install Zainstaluj - + %p% (%v KB out of %m KB) %p% (%v KB z %m KB) - + Abort Przerwij - + Mod name Nazwa moda - + Installed version Zainstalowana wersja - + Latest version Najnowsza wersja - + Download size Rozmiar pobierania - + Authors Autorzy - + License Licencja - - Home - Źródło + + Contact + - - + + Compatibility Kompatybilność - - + + Required VCMI version Wymagana wersja VCMI - + Supported VCMI version Wspierana wersja VCMI - + Supported VCMI versions Wspierane wersje VCMI - + Required mods Wymagane mody - + Conflicting mods Konfliktujące mody - + This mod can not be installed or enabled because following dependencies are not present Ten mod nie może zostać zainstalowany lub włączony ponieważ następujące zależności nie zostały spełnione - + This mod can not be enabled because following mods are incompatible with this mod Ten mod nie może zostać włączony ponieważ następujące mody są z nim niekompatybilne - + This mod can not be disabled because it is required to run following mods Ten mod nie może zostać wyłączony ponieważ jest wymagany by do uruchomienia następujących modów - + This mod can not be uninstalled or updated because it is required to run following mods Ten mod nie może zostać odinstalowany lub zaktualizowany ponieważ jest wymagany do uruchomienia następujących modów - + This is submod and it can not be installed or uninstalled separately from parent mod To jest moduł składowy innego moda i nie może być zainstalowany lub odinstalowany oddzielnie od moda nadrzędnego - + Notes Uwagi - + Screenshot %1 Zrzut ekranu %1 - + Mod is compatible Mod jest kompatybilny - + Mod is incompatible Mod jest niekompatybilny @@ -243,217 +228,342 @@ CSettingsView - + Change Zmień - - - + + + Open Otwórz - + + Adventure Map AI + + + + User data directory Katalog danych użytkownika - - - - + + + + Off Wyłączony - - - - + + + Artificial Intelligence + + + + + + Mod Repositories + + + + + Update now + + + + + + + On Włączony - + + Cursor + + + + + Heroes III Data Language + + + + + Default + + + + + Hardware + + + + + Software + + + + + Heroes III Translation + + + + + Check on startup + + + + Fullscreen Pełny ekran - - Repositories - Repozytoria - - - - Check for updates - Sprawdź czy są aktualizacje - - - + Neutral AI AI jednostek neutralnych - + Real Prawdziwy - + + General Ogólne - - Player AI - AI graczy - - - + VCMI Language Język VCMI - - Central European (Windows 1250) - Środkowoeuropejski (Windows 1250) - - - - Cyrillic script (Windows 1251) - Cyrylica (Windows 1251) - - - - Western European (Windows 1252) - Wschodnioeuropejski (Windows 1252) - - - - Simplified Chinese (GBK) - Uproszczony chiński (GBK) - - - - Simplified Chinese (GB2312) - Uproszczony chiński (GB2312) - - - - Korean (Windows 949) - Koreański (Windows 949) - - - - English - English (Angielski) - - - - Deutsch (German) - Deutsch (Niemiecki) - - - - Polski (Polish) - Polski - - - - Русский (Russian) - Русский (Rosyjski) - - - - Українська (Ukrainian) - Українська (Ukraiński) - - - + Friendly AI AI sojuszników - + Resolution Rozdzielczość - - AI on the map - AI na mapie przygody - - - + Autosave Autozapis - + Display index Numer wyświetlacza - - Check repositories on startup - Sprawdź repozytoria przy starcie - - - + Network port Port sieciowy - + + Data Directories Katalogi z danymi - + + Video Obraz - - Heroes III character set - Zestaw znaków w grze - - - + Extra data directory Katalog danych dodatkowych - + Log files directory Katalog logów - + Show intro Pokaż intro - - Launcher Settings - Ustawienia Launchera - - - + Build version Wersja programu - + Enemy AI AI wrogich graczy - - AI in the battlefield - AI na polu bitwy + + Active + Aktywny + + + + Disabled + + + + + Enable + Włącz + + + + Not Installed + + + + + Install + Zainstaluj + + + + FirstLaunchView + + + Language + + + + + Heroes III Data + + + + + Mods Preset + + + + + Your Heroes III data files have been successfully found. + + + + + Optionally, you can install additional mods either now or at any point later: + + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + + + Finish + + + + + Step %v out of %m + + + + + Choose your language + + + + + + Next + + + + + Find Heroes III data files + + + + + Open help in browser + + + + + Search again + + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + + + Heroes III data files + + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + + + Copy existing data + + + + + Your Heroes III language has been successfully detected. + + + + + Automatic detection of language failed. Please select language of your Heroes III copy + + + + + Heroes III language + + + + + + Back + + + + + Install VCMI Mod Preset + + + + + Install translation of Heroes III to your language + @@ -464,68 +574,172 @@ Wyświetlacz obrazków + + Language + + + Chinese + + + + + English + English (Angielski) + + + + French + + + + + German + + + + + Korean + + + + + Polish + + + + + Russian + + + + + Spanish + + + + + Ukrainian + + + + + Other (East European) + + + + + Other (Cyrillic Script) + + + + + Other (West European) + + + + + Auto (%1) + + + Lobby - + + Connect Połącz - + Username Nazwa użytkownika - + Server Serwer - + + People in lobby + + + + + Lobby chat + + + + Session Sesja - + Players Gracze - + + Resolve + + + + + New game + + + + + Load game + + + + New room Nowy pokój - + Join room Dołącz - + Ready Zgłoś gotowość - + Mods mismatch Niezgodność modów - + Leave Wyjdź - + Kick player Wyrzuć gracza - + Players in the room Gracze w pokoju + + + Disconnect + + + + + No issues detected + + LobbyRoomRequest @@ -558,34 +772,30 @@ VCMI Launcher (program startowy) - + Settings Ustawienia - + Map Editor - + Start game Uruchom grę - + Lobby Lobby - + Mods Mody - - Editor - Edytor - UpdateDialog diff --git a/launcher/translation/russian.ts b/launcher/translation/russian.ts index dd445542f..bf4f89f7b 100644 --- a/launcher/translation/russian.ts +++ b/launcher/translation/russian.ts @@ -4,257 +4,223 @@ CModListModel - + Name Название - + Type Тип - + Version Версия - - - Size - Размер - - - - Author - Автор - CModListView - - + Filter Фильтр - - + All mods Все моды - - + Downloadable Доступные - - + Installed Установленные - - + Updatable Обновления - - + Active Активны - - + Inactive Неактивны - - + Download && refresh repositories Обновить репозиторий - - - + + Description Описание - - + Changelog Изменения - - + Screenshots Скриншоты - - - Show details - Подробности - - - - + Uninstall Удалить - - + Enable Включить - Disable Отключить - - + Update Обновить - - + Install Установить - - + %p% (%v KB out of %m KB) %p% (%v КБ з %m КБ) - - + Abort Отмена - + Mod name Название мода - + Installed version Установленная версия - + Latest version Последняя версия - + Download size Размер загрузки - + Authors Авторы - + License Лицензия - - Home - Домашняя страница + + Contact + - - + + Compatibility Совместимость - - + + Required VCMI version Требуемая версия VCMI - + Supported VCMI version Поддерживаемая версия VCMI - + Supported VCMI versions Поддерживаемые версии VCMI - + Required mods Зависимости - + Conflicting mods Конфликтующие моды - + This mod can not be installed or enabled because following dependencies are not present Этот мод не может быть установлен или активирован, так как отсутствуют следующие зависимости - + This mod can not be enabled because following mods are incompatible with this mod Этот мод не может быть установлен или активирован, так как следующие моды несовместимы с этим - + This mod can not be disabled because it is required to run following mods Этот мод не может быть выключен, так как он является зависимостью для следующих - + This mod can not be uninstalled or updated because it is required to run following mods Этот мод не может быть удален или обновлен, так как является зависимостью для следующих модов - + This is submod and it can not be installed or uninstalled separately from parent mod Это вложенный мод, он не может быть установлен или удален отдельно от родительского - + Notes Замечания - + Screenshot %1 Скриншот %1 - + Mod is compatible Мод совместим - + Mod is incompatible Мод несовместим @@ -262,409 +228,505 @@ CSettingsView - - + Change Изменить - - - - - - + + + Open Открыть - - + + Adventure Map AI + + + + User data directory Данные пользователя - - - - - - - - + + + + Off Отключено - - - - - - - - + + + + On Включено - - + + Check on startup + + + + Fullscreen Полноэкранный режим - - - Repositories - Репозитории - - - - - Check for updates - Проверить обновления - - - - + Neutral AI Нейтральный ИИ - - + Real Полный - - + + General Общее - - - Player AI - ИИ игроков - - - - + VCMI Language Язык VCMI - - - Automatic detection - Автоматическое определение - - - - - Central European (Windows 1250) - Центральноевропейская (Windows-1250) - - - - - Cyrillic script (Windows 1251) - Кириллица (Windows 1251) - - - - - Western European (Windows 1252) - Западноевропейская (Windows 1252) - - - - - Simplified Chinese (GBK) - Упрощенная китайская (GBK) - - - - - Simplified Chinese (GB2312) - Упрощенная китайская (GB2312) - - - - - Korean (Windows 949) - Корейская (Windows 949) - - - - - English - English (Английский) - - - - - Deutsch (German) - Deutsch (Немецкий) - - - - - Polska (Polish) - Polska (Польский) - - - - - Русский (Russian) - Русский - - - - - Українська (Ukrainian) - Українська (Украинский) - - - - + Friendly AI Дружественный ИИ - - + Cursor Курсор - - + + + Artificial Intelligence + + + + + + Mod Repositories + + + + + Update now + + + + + Heroes III Data Language + + + + Default По умолчанию - - + Hardware Аппаратный - - + Software Программный - - + + Heroes III Translation + + + + Resolution Разрешение экрана - - - AI on the map - ИИ на карте приключений - - - - + Autosave Автосохранение - - + Display index Дисплей - - - Check repositories on startup - Проверка репозиториев при запуске - - - - + Network port Сетевой порт - - + + Data Directories Директории данных - - + + Video Графика - - - Heroes III character set - Кодировка Героев III - - - - + Extra data directory Дополнительные данные - - + Log files directory Журналы - - + Show intro Вступление - - - Launcher Settings - Настройки загрузчика - - - - + Build version Версия сборки - - + Enemy AI Вражеский ИИ - - - AI in the battlefield - ИИ на поле боя + + Active + Активны + + + + Disabled + + + + + Enable + Включить + + + + Not Installed + + + + + Install + Установить + + + + FirstLaunchView + + + Language + + + + + Heroes III Data + + + + + Mods Preset + + + + + Your Heroes III data files have been successfully found. + + + + + Optionally, you can install additional mods either now or at any point later: + + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + + + Finish + + + + + Step %v out of %m + + + + + Choose your language + + + + + + Next + + + + + Find Heroes III data files + + + + + Open help in browser + + + + + Search again + + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + + + Heroes III data files + + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + + + Copy existing data + + + + + Your Heroes III language has been successfully detected. + + + + + Automatic detection of language failed. Please select language of your Heroes III copy + + + + + Heroes III language + + + + + + Back + + + + + Install VCMI Mod Preset + + + + + Install translation of Heroes III to your language + ImageViewer - Image Viewer Просмотр изображений + + Language + + + Chinese + + + + + English + English (Английский) + + + + French + + + + + German + + + + + Korean + + + + + Polish + + + + + Russian + + + + + Spanish + + + + + Ukrainian + + + + + Other (East European) + + + + + Other (Cyrillic Script) + + + + + Other (West European) + + + + + Auto (%1) + + + Lobby - Connect Подключиться - Username Имя пользователя - Server Сервер - People in lobby Люди в лобби - Lobby chat Чат лобби - Session Сессия - Players Игроки - Resolve Скорректировать - New game Новая игра - Load game Загрузить игру - New room Создать комнату - Join room Присоединиться к комнате - Ready Готово - Mods mismatch Моды не совпадают - Leave Выйти - Kick player Выгнать игрока - Players in the room Игроки в комнате @@ -683,25 +745,21 @@ LobbyRoomRequest - Room settings Настройки комнаты - Room name Название - Maximum players Максимум игроков - Password (optional) Пароль (не обязательно) @@ -710,37 +768,31 @@ MainWindow - VCMI Launcher Запуск VCMI - Settings Параметры - Map Editor Редактор карт - Start game Играть - Lobby Лобби - Mods Моды @@ -749,19 +801,16 @@ UpdateDialog - You have latest version У вас уже последняя версия - Close Закрыть - Check updates on startup Проверять обновления при запуске diff --git a/launcher/translation/ukrainian.ts b/launcher/translation/ukrainian.ts index b93221b03..1b059748f 100644 --- a/launcher/translation/ukrainian.ts +++ b/launcher/translation/ukrainian.ts @@ -4,101 +4,86 @@ CModListModel - + Name Назва - + Type Тип - + Version Версія - - - Size - Розмір - - - - Author - Автори - CModListView - + Filter Фільтр - + All mods Усі модифікації - + Downloadable Усі доступні - + Installed Встановлені - + Updatable Доступні оновлення - + Active Активні - + Inactive Неактивні - + Download && refresh repositories Оновити репозиторії - - + + Description Опис - + Changelog Зміни - + Screenshots Знімки - - Show details - Показати подробиці - - - + Uninstall Видалити - + Enable Активувати @@ -108,134 +93,134 @@ Деактивувати - + Update Оновити - + Install Встановити - + %p% (%v KB out of %m KB) %p% (%v КБ з %m КБ) - + Abort Відмінити - + Mod name Назва модифікації - + Installed version Встановлена версія - + Latest version Найновіша версія - + Download size Розмір для завантаження - + Authors Автори - + License Ліцензія - - Home - Домашня сторінка + + Contact + Контакти - - + + Compatibility Сумісність - - + + Required VCMI version Необхідна версія VCMI - + Supported VCMI version Підтримувана версія VCMI - + Supported VCMI versions Підтримувані версії VCMI - + Required mods Необхідні модифікації - + Conflicting mods Конфліктуючі модифікації - + This mod can not be installed or enabled because following dependencies are not present Цю модифікацію не можна встановити чи активувати, оскільки відсутні наступні залежності - + This mod can not be enabled because following mods are incompatible with this mod Цю модифікацію не можна ввімкнути, оскільки наступні модифікації несумісні з цією модифікацією - + This mod can not be disabled because it is required to run following mods Цю модифікацію не можна відключити, оскільки вона необхідна для запуску наступних модифікацій - + This mod can not be uninstalled or updated because it is required to run following mods Цю модифікацію не можна видалити або оновити, оскільки вона необхідна для запуску наступних модифікацій - + This is submod and it can not be installed or uninstalled separately from parent mod Це вкладена модифікація, і її не можна встановити або видалити окремо від батьківської модифікації - + Notes Примітки - + Screenshot %1 Знімок екрану %1 - + Mod is compatible Модифікація сумісна - + Mod is incompatible Модифікація несумісна @@ -243,218 +228,343 @@ CSettingsView - + Change Змінити - - - + + + Open Відкрити - + + Adventure Map AI + ШІ Гравця + + + User data directory Тека даних користувача - - - - + + + + Off Вимкнено - - - - + + + Artificial Intelligence + Штучний інтелект + + + + + Mod Repositories + Репозиторії модифікацій + + + + Update now + Оновити зараз + + + + + + On Увімкнено - + + Cursor + Курсор + + + + Heroes III Data Language + Мова Heroes III + + + + Default + За замовчуванням + + + + Hardware + Апаратний + + + + Software + Програмний + + + + Heroes III Translation + Переклад Heroes III + + + + Check on startup + Перевіряти на старті + + + Fullscreen Повноекранний режим - - AI in the battlefield - Штучний інтелект на полі бою - - - - Repositories - Репозиторії - - - - Check for updates - Оновити зараз - - - + Neutral AI Нейтральний ШІ - + Real Повний - + + General Загальні налаштування - - Player AI - ШІ гравців - - - + VCMI Language Мова VCMI - - Central European (Windows 1250) - Центральноєвропейська (Windows 1250) - - - - Cyrillic script (Windows 1251) - Кирилиця (Windows 1251) - - - - Western European (Windows 1252) - Західноєвропейська (Windows 1252) - - - - Simplified Chinese (GBK) - Спрощена китайська (GBK) - - - - Simplified Chinese (GB2312) - Спрощена китайська (GB2312) - - - - Korean (Windows 949) - Корейська (Windows 949) - - - - English - English (Англійська) - - - - Deutsch (German) - Deutsch (Німецька) - - - - Polska (Polish) - Polska (Польська) - - - - Русский (Russian) - Русский (Російська) - - - - Українська (Ukrainian) - Українська - - - + Friendly AI Дружній ШІ - + Resolution Роздільна здатність - - AI on the map - Штучний інтелект на карті пригод - - - + Autosave Автозбереження - + Display index Дісплей - - Check repositories on startup - Перевірка репозиторіїв при запуску - - - + Network port Мережевий порт - + + Data Directories Теки даних гри - + + Video Графіка - - Heroes III character set - Кодування Heroes III - - - + Extra data directory Додаткова тека даних - + Log files directory Тека файлів журналу - + Show intro Вступні відео - - Launcher Settings - Налаштування лаунчера - - - + Build version Версія збірки - + Enemy AI Ворожий ШІ + + + Active + Активні + + + + Disabled + Деактивований + + + + Enable + Активувати + + + + Not Installed + Не встановлено + + + + Install + Встановити + + + + FirstLaunchView + + + Language + Мова + + + + Heroes III Data + Дані Heroes III + + + + Mods Preset + Початкові модифікації + + + + Your Heroes III data files have been successfully found. + Файли даних вашої гри Heroes III успішно знайдено. + + + + Optionally, you can install additional mods either now or at any point later: + За бажанням ви можете встановити додаткові модифікації зараз або пізніше: + + + + Install support for playing Heroes III in resolutions other than 800x600. + + + + + Install compatible version of addon Horn of the Abyss: fan-made Heroes III expansion, ported by VCMI team + + + + + Install compatible version of addon "In The Wake of Gods": fan-made Heroes III expansion + + + + + Finish + Завершити + + + + Step %v out of %m + Крок %v з %m + + + + Choose your language + Оберіть свою мову + + + + + Next + Далі + + + + Find Heroes III data files + Пошук файлів даних Heroes III + + + + Open help in browser + Відкрити довідку у браузері + + + + Search again + Повторити пошук + + + + If you don't have installed Heroes III copy, it is possible to use our automatic installation tool 'vcmibuilder' to extract data from GoG.com installer. Visit our wiki for detailed instructions. + + + + + VCMI requires Heroes III data files in one of the locations listed above. Please copy Heroes III data in one of these directories. + + + + + Heroes III data files + Файли даних Heroes III + + + + Alternatively, you can select directory with installed Heroes III data and VCMI will copy exisiting data automatically. + + + + + Copy existing data + Копіювати наявні дані + + + + Your Heroes III language has been successfully detected. + Мову вашої гри Heroes III успішно визначено. + + + + Automatic detection of language failed. Please select language of your Heroes III copy + Не вдалося визначити мову гри. Будь ласка, виберіть мову вашої копії Heroes III + + + + Heroes III language + Мова Heroes III + + + + + Back + Назад + + + + Install VCMI Mod Preset + Встановлення початкових модифікацій VCMI + + + + Install translation of Heroes III to your language + Встановити переклад Heroes III на вашу мову + ImageViewer @@ -464,68 +574,172 @@ Перегляд зображень + + Language + + + Chinese + Китайська + + + + English + Англійська + + + + French + Французька + + + + German + Німецька + + + + Korean + Корейська + + + + Polish + Польська + + + + Russian + Російська + + + + Spanish + Іспанська + + + + Ukrainian + Українська + + + + Other (East European) + Інша (східноєвропейська) + + + + Other (Cyrillic Script) + Інша (кирилиця) + + + + Other (West European) + Інша (західноєвропейська) + + + + Auto (%1) + Авто (%1) + + Lobby - + + Connect Підключитися - + Username Ім'я користувача - + Server Сервер - + + People in lobby + Гравці у лобі + + + + Lobby chat + Лобі чат + + + Session Сесія - + Players Гравці - + + Resolve + Розв'язати + + + + New game + Нова гра + + + + Load game + Завантажити гру + + + New room Створити кімнату - + Join room Приєднатися до кімнати - + Ready Готовність - + Mods mismatch Модифікації, що не збігаються - + Leave Вийти з кімнати - + Kick player Виключити гравця - + Players in the room Гравці у кімнаті + + + Disconnect + Від'єднатися + + + + No issues detected + Проблем не виявлено + LobbyRoomRequest @@ -558,31 +772,27 @@ VCMI Launcher - + Mods Модифікації - Editor - Редактор - - - + Settings Налаштування - + Lobby Лобі - + Map Editor - + Редактор мап - + Start game Грати diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index af09b3381..3285007b7 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -49,7 +49,7 @@ void CGeneralTextHandler::detectInstallParameters() // load file that will be used for footprint generation // this is one of the most text-heavy files in game and consists solely from translated texts - auto resource = CResourceHandler::get()->load(ResourceID("DATA/GENRLTXT.TXT", EResType::TEXT)); + auto resource = CResourceHandler::get("core")->load(ResourceID("DATA/GENRLTXT.TXT", EResType::TEXT)); std::array charCount{}; std::array footprint{}; @@ -87,6 +87,9 @@ void CGeneralTextHandler::detectInstallParameters() Settings language = settings.write["session"]["language"]; language->String() = knownLanguages[bestIndex]; + Settings confidence = settings.write["session"]["languageDeviation"]; + confidence->Float() = deviations[bestIndex]; + Settings encoding = settings.write["session"]["encoding"]; encoding->String() = Languages::getLanguageOptions(knownLanguages[bestIndex]).encoding; } @@ -387,8 +390,6 @@ CGeneralTextHandler::CGeneralTextHandler(): znpc00 (*this, "vcmi.znpc00" ), // technically - wog qeModCommands (*this, "vcmi.quickExchange" ) { - detectInstallParameters(); - readToVector("core.vcdesc", "DATA/VCDESC.TXT" ); readToVector("core.lcdesc", "DATA/LCDESC.TXT" ); readToVector("core.tcommand", "DATA/TCOMMAND.TXT" ); @@ -605,16 +606,19 @@ std::string CGeneralTextHandler::getModLanguage(const std::string & modContext) std::string CGeneralTextHandler::getPreferredLanguage() { + assert(!settings["general"]["language"].String().empty()); return settings["general"]["language"].String(); } std::string CGeneralTextHandler::getInstalledLanguage() { + assert(!settings["session"]["language"].String().empty()); return settings["session"]["language"].String(); } std::string CGeneralTextHandler::getInstalledEncoding() { + assert(!settings["session"]["encoding"].String().empty()); return settings["session"]["encoding"].String(); } diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index be7af936c..7516bfc84 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -616,7 +616,8 @@ bool CModInfo::Version::isNull() const CModInfo::CModInfo(): checksum(0), - enabled(false), + explicitlyEnabled(false), + implicitlyEnabled(true), validation(PENDING) { @@ -629,7 +630,8 @@ CModInfo::CModInfo(std::string identifier,const JsonNode & local, const JsonNode dependencies(config["depends"].convertTo >()), conflicts(config["conflicts"].convertTo >()), checksum(0), - enabled(false), + explicitlyEnabled(false), + implicitlyEnabled(true), validation(PENDING), config(addMeta(config, identifier)) { @@ -654,7 +656,7 @@ JsonNode CModInfo::saveLocalData() const stream << std::noshowbase << std::hex << std::setw(8) << std::setfill('0') << checksum; JsonNode conf; - conf["active"].Bool() = enabled; + conf["active"].Bool() = explicitlyEnabled; conf["validated"].Bool() = validation != FAILED; conf["checksum"].String() = stream.str(); return conf; @@ -683,33 +685,52 @@ void CModInfo::updateChecksum(ui32 newChecksum) void CModInfo::loadLocalData(const JsonNode & data) { bool validated = false; - enabled = true; + implicitlyEnabled = true; + explicitlyEnabled = true; checksum = 0; if (data.getType() == JsonNode::JsonType::DATA_BOOL) { - enabled = data.Bool(); + explicitlyEnabled = data.Bool(); } if (data.getType() == JsonNode::JsonType::DATA_STRUCT) { - enabled = data["active"].Bool(); + explicitlyEnabled = data["active"].Bool(); validated = data["validated"].Bool(); checksum = strtol(data["checksum"].String().c_str(), nullptr, 16); } //check compatibility - bool wasEnabled = enabled; - enabled = enabled && (vcmiCompatibleMin.isNull() || Version::GameVersion().compatible(vcmiCompatibleMin)); - enabled = enabled && (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(Version::GameVersion())); + implicitlyEnabled &= (vcmiCompatibleMin.isNull() || Version::GameVersion().compatible(vcmiCompatibleMin)); + implicitlyEnabled &= (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(Version::GameVersion())); - if(wasEnabled && !enabled) + if(!implicitlyEnabled) logGlobal->warn("Mod %s is incompatible with current version of VCMI and cannot be enabled", name); - if (enabled) + if (boost::iequals(config["modType"].String(), "translation")) // compatibility code - mods use "Translation" type at the moment + { + if (baseLanguage != VLC->generaltexth->getPreferredLanguage()) + { + logGlobal->warn("Translation mod %s was not loaded: language mismatch!", name); + implicitlyEnabled = false; + } + } + + if (isEnabled()) validation = validated ? PASSED : PENDING; else validation = validated ? PASSED : FAILED; } +bool CModInfo::isEnabled() const +{ + return implicitlyEnabled && explicitlyEnabled; +} + +void CModInfo::setEnabled(bool on) +{ + explicitlyEnabled = on; +} + CModHandler::CModHandler() : content(std::make_shared()) { modules.COMMANDERS = false; @@ -820,36 +841,6 @@ bool CModHandler::hasCircularDependency(TModID modID, std::set currentL return false; } -bool CModHandler::checkDependencies(const std::vector & input) const -{ - for(const TModID & id : input) - { - const CModInfo & mod = allMods.at(id); - - for(const TModID & dep : mod.dependencies) - { - if(!vstd::contains(input, dep)) - { - logMod->error("Error: Mod %s requires missing %s!", mod.name, dep); - return false; - } - } - - for(const TModID & conflicting : mod.conflicts) - { - if(vstd::contains(input, conflicting)) - { - logMod->error("Error: Mod %s conflicts with %s!", mod.name, allMods.at(conflicting).name); - return false; - } - } - - if(hasCircularDependency(id)) - return false; - } - return true; -} - // Returned vector affects the resource loaders call order (see CFilesystemList::load). // The loaders call order matters when dependent mod overrides resources in its dependencies. std::vector CModHandler::validateAndSortDependencies(std::vector modsToResolve) const @@ -995,10 +986,10 @@ void CModHandler::loadOneMod(std::string modName, std::string parent, const Json mod.dependencies.insert(parent); allMods[modFullName] = mod; - if (mod.enabled && enableMods) + if (mod.isEnabled() && enableMods) activeMods.push_back(modFullName); - loadMods(CModInfo::getModDir(modFullName) + '/', modFullName, modSettings[modName]["mods"], enableMods && mod.enabled); + loadMods(CModInfo::getModDir(modFullName) + '/', modFullName, modSettings[modName]["mods"], enableMods && mod.isEnabled()); } } @@ -1087,6 +1078,8 @@ static ui32 calculateModChecksum(const std::string modName, ISimpleResourceLoade void CModHandler::loadModFilesystems() { + CGeneralTextHandler::detectInstallParameters(); + activeMods = validateAndSortDependencies(activeMods); coreMod.updateChecksum(calculateModChecksum(CModHandler::scopeBuiltin(), CResourceHandler::get(CModHandler::scopeBuiltin()))); @@ -1109,6 +1102,9 @@ TModID CModHandler::findResourceOrigin(const ResourceID & name) if(CResourceHandler::get("core")->existsResource(name)) return "core"; + if(CResourceHandler::get("mapEditor")->existsResource(name)) + return "core"; // Workaround for loading maps via map editor + assert(0); return ""; } diff --git a/lib/CModHandler.h b/lib/CModHandler.h index 27dfd3836..a3953e7be 100644 --- a/lib/CModHandler.h +++ b/lib/CModHandler.h @@ -236,9 +236,6 @@ public: /// CRC-32 checksum of the mod ui32 checksum; - /// true if mod is enabled - bool enabled; - EValidationStatus validation; JsonNode config; @@ -249,10 +246,19 @@ public: JsonNode saveLocalData() const; void updateChecksum(ui32 newChecksum); + bool isEnabled() const; + void setEnabled(bool on); + static std::string getModDir(std::string name); static std::string getModFile(std::string name); private: + /// true if mod is enabled by user, e.g. in Launcher UI + bool explicitlyEnabled; + + /// true if mod can be loaded - compatible and has no missing deps + bool implicitlyEnabled; + void loadLocalData(const JsonNode & data); }; @@ -266,12 +272,6 @@ class DLL_LINKAGE CModHandler bool hasCircularDependency(TModID mod, std::set currentList = std::set ()) const; - //returns false if mod list is incorrect and prints error to console. Possible errors are: - // - missing dependency mod - // - conflicting mod in load order - // - circular dependencies - bool checkDependencies(const std::vector & input) const; - /** * 1. Set apart mods with resolved dependencies from mods which have unresolved dependencies * 2. Sort resolved mods using topological algorithm @@ -449,7 +449,7 @@ public: h & mver; if(allMods.count(m) && (allMods[m].version.isNull() || mver.isNull() || allMods[m].version.compatible(mver))) - allMods[m].enabled = true; + allMods[m].setEnabled(true); else missingMods.emplace_back(m, mver.toString()); } diff --git a/lib/Languages.h b/lib/Languages.h index c1610976d..f87ae6e0b 100644 --- a/lib/Languages.h +++ b/lib/Languages.h @@ -18,10 +18,17 @@ enum class ELanguages ENGLISH, FRENCH, GERMAN, + KOREAN, // currently has no translations or detection POLISH, RUSSIAN, + SPANISH, UKRAINIAN, + // Pseudo-languages, that have no translations but can define H3 encoding to use + OTHER_CP1250, + OTHER_CP1251, + OTHER_CP1252, + COUNT }; @@ -46,34 +53,39 @@ struct Options bool hasTranslation = false; }; -inline auto const & getLanguageList( ) +inline const auto & getLanguageList() { - static const std::array languages + static const std::array languages { { - { "chinese", "Chinese", "简体中文", "GBK", true, true }, + { "chinese", "Chinese", "简体中文", "GBK", true, true }, // Note: actually Simplified Chinese { "english", "English", "English", "CP1252", true, true }, { "french", "French", "Français", "CP1252", true, true }, { "german", "German", "Deutsch", "CP1252", true, true }, - //TODO: korean - CP949 encoding + { "korean", "Korean", "한국어", "CP949", false, false }, { "polish", "Polish", "Polski", "CP1250", true, true }, { "russian", "Russian", "Русский", "CP1251", true, true }, - { "ukrainian", "Ukrainian", "Українська", "CP1251", true, true } + { "spanish", "Spanish", "Español", "CP1252", false, true }, + { "ukrainian", "Ukrainian", "Українська", "CP1251", true, true }, + + { "other_cp1250", "Other (East European)", "", "CP1251", false, false }, + { "other_cp1251", "Other (Cyrillic Script)", "", "CP1250", false, false }, + { "other_cp1252", "Other (West European)", "", "CP1252", false, false } } }; - static_assert (languages.size() == static_cast(ELanguages::COUNT), "Languages array is missing a value!" ); + static_assert(languages.size() == static_cast(ELanguages::COUNT), "Languages array is missing a value!"); return languages; } -inline const Options & getLanguageOptions( ELanguages language ) +inline const Options & getLanguageOptions(ELanguages language) { assert(language < ELanguages::COUNT); return getLanguageList()[static_cast(language)]; } -inline const Options & getLanguageOptions( std::string language ) +inline const Options & getLanguageOptions(const std::string & language) { - for (auto const & entry : getLanguageList()) - if (entry.identifier == language) + for(const auto & entry : getLanguageList()) + if(entry.identifier == language) return entry; static const Options emptyValue; diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index 647ddce44..c7d2d85f2 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -18,6 +18,7 @@ #include "CHeroHandler.h" #include "mapObjects/CObjectHandler.h" #include "CTownHandler.h" +#include "CConfigHandler.h" #include "RoadHandler.h" #include "RiverHandler.h" #include "TerrainHandler.h" @@ -48,7 +49,9 @@ DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential, bool VLC = new LibClasses(); try { - VLC->loadFilesystem(onlyEssential, extractArchives); + VLC->loadFilesystem(extractArchives); + settings.init(); + VLC->loadModFilesystem(onlyEssential); } catch(...) { @@ -160,9 +163,8 @@ void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & } } -void LibClasses::loadFilesystem(bool onlyEssential, bool extractArchives) +void LibClasses::loadFilesystem(bool extractArchives) { - CStopWatch totalTime; CStopWatch loadTime; CResourceHandler::initialize(); @@ -170,15 +172,17 @@ void LibClasses::loadFilesystem(bool onlyEssential, bool extractArchives) CResourceHandler::load("config/filesystem.json", extractArchives); logGlobal->info("\tData loading: %d ms", loadTime.getDiff()); +} +void LibClasses::loadModFilesystem(bool onlyEssential) +{ + CStopWatch loadTime; modh = new CModHandler(); + modh->loadMods(onlyEssential); logGlobal->info("\tMod handler: %d ms", loadTime.getDiff()); - modh->loadMods(onlyEssential); modh->loadModFilesystems(); logGlobal->info("\tMod filesystems: %d ms", loadTime.getDiff()); - - logGlobal->info("Basic initialization: %d ms", totalTime.getDiff()); } static void logHandlerLoaded(const std::string & name, CStopWatch & timer) diff --git a/lib/VCMI_Lib.h b/lib/VCMI_Lib.h index 55e58712b..16a52e0eb 100644 --- a/lib/VCMI_Lib.h +++ b/lib/VCMI_Lib.h @@ -107,7 +107,8 @@ public: void clear(); //deletes all handlers and its data // basic initialization. should be called before init(). Can also extract original H3 archives - void loadFilesystem(bool onlyEssential, bool extractArchives = false); + void loadFilesystem(bool extractArchives); + void loadModFilesystem(bool onlyEssential); #if SCRIPTING_ENABLED void scriptsLoaded(); diff --git a/lib/filesystem/AdapterLoaders.cpp b/lib/filesystem/AdapterLoaders.cpp index b328253b9..a3fd4699f 100644 --- a/lib/filesystem/AdapterLoaders.cpp +++ b/lib/filesystem/AdapterLoaders.cpp @@ -58,12 +58,10 @@ std::unordered_set CMappedFileLoader::getFilteredFiles(std::function CFilesystemList::CFilesystemList() { - //loaders = new std::vector >; } CFilesystemList::~CFilesystemList() { - //delete loaders; } std::unique_ptr CFilesystemList::load(const ResourceID & resourceName) const diff --git a/lib/filesystem/Filesystem.cpp b/lib/filesystem/Filesystem.cpp index 99303e563..aa586efc5 100644 --- a/lib/filesystem/Filesystem.cpp +++ b/lib/filesystem/Filesystem.cpp @@ -192,6 +192,12 @@ void CResourceHandler::initialize() addFilesystem("root", "local", localFS); } +void CResourceHandler::destroy() +{ + knownLoaders.clear(); + globalResourceHandler.rootLoader.reset(); +} + ISimpleResourceLoader * CResourceHandler::get() { return get("root"); diff --git a/lib/filesystem/Filesystem.h b/lib/filesystem/Filesystem.h index f501a302f..cdbff4f27 100644 --- a/lib/filesystem/Filesystem.h +++ b/lib/filesystem/Filesystem.h @@ -81,6 +81,12 @@ public: */ static void initialize(); + /** + * Destroys all existing data in filesystem, bringing it into uninitialized state + * + */ + static void destroy(); + /** * Will load all filesystem data from Json data at this path (normally - config/filesystem.json) * @param fsConfigURI - URI from which data will be loaded diff --git a/mapeditor/mainwindow.cpp b/mapeditor/mainwindow.cpp index bb05305a3..ce3150731 100644 --- a/mapeditor/mainwindow.cpp +++ b/mapeditor/mainwindow.cpp @@ -170,7 +170,6 @@ MainWindow::MainWindow(QWidget* parent) : //init preinitDLL(::console, false, extractionOptions.extractArchives); - settings.init(); // Initialize logging based on settings logConfig->configure(); diff --git a/mapeditor/translation/ukrainian.ts b/mapeditor/translation/ukrainian.ts index 4b547aff0..dea30ccd3 100644 --- a/mapeditor/translation/ukrainian.ts +++ b/mapeditor/translation/ukrainian.ts @@ -62,17 +62,17 @@ Toolbar - + Панель інструментів Minimap - + Мінімапа Map Objects View - + Перегляд об'єктів мапи @@ -97,7 +97,7 @@ Terrains View - + Перегляд поверхні @@ -339,53 +339,53 @@ Difficulty - + Складність Events - + Події Victory - + Перемога Victory message - + Повідомлення про перемогу Only for human players - + Тільки для гравців-людей Allow standard victory - + Дозволити типову перемогу Parameters - + Параметри Loss - + Програш 7 days without town - + 7 днів без міста Defeat message - + Повідомлення про програш @@ -415,67 +415,67 @@ No special victory - + Немає особливої перемоги Capture artifact - + Отримати артефакт Hire creatures - + Найняти істот Accumulate resources - + Накопичити ресурси Construct building - + Побудувати будівлю Capture town - + Захопити місто Defeat hero - + Перемогти героя Transport artifact - + Доставити артефакт No special loss - + Немає особливої поразки Lose castle - + Втратити місто Lose hero - + Втратити героя Time expired - + Закінчився час Days without town - + Дні без міста @@ -751,7 +751,7 @@ Filepath of the map to open. - Файл мапи, який слід відкрити + diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 3ce05505e..ce24bba5e 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -1117,7 +1117,6 @@ int main(int argc, const char * argv[]) boost::program_options::variables_map opts; handleCommandOptions(argc, argv, opts); preinitDLL(console); - settings.init(); logConfig.configure(); loadDLLClasses();