mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-14 10:12:59 +02:00
Fix enabling and disabling of mods
This commit is contained in:
parent
34a59d049b
commit
4aaa6c1eb4
@ -32,6 +32,7 @@
|
|||||||
#include "../../lib/texts/Languages.h"
|
#include "../../lib/texts/Languages.h"
|
||||||
#include "../../lib/modding/CModVersion.h"
|
#include "../../lib/modding/CModVersion.h"
|
||||||
#include "../../lib/filesystem/Filesystem.h"
|
#include "../../lib/filesystem/Filesystem.h"
|
||||||
|
#include "../../lib/texts/CGeneralTextHandler.h"
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
@ -395,6 +396,7 @@ QString CModListView::genModInfoText(const ModState & mod)
|
|||||||
|
|
||||||
result += "<p></p>"; // to get some empty space
|
result += "<p></p>"; // to get some empty space
|
||||||
|
|
||||||
|
QString translationMismatch = tr("This mod cannot be enabled because it translates into a different language.");
|
||||||
QString notInstalledDeps = tr("This mod can not be enabled because the following dependencies are not present");
|
QString notInstalledDeps = tr("This mod can not be enabled because the following dependencies are not present");
|
||||||
QString unavailableDeps = tr("This mod can not be installed because the following dependencies are not present");
|
QString unavailableDeps = tr("This mod can not be installed because the following dependencies are not present");
|
||||||
QString thisIsSubmod = tr("This is a submod and it cannot be installed or uninstalled separately from its parent mod");
|
QString thisIsSubmod = tr("This is a submod and it cannot be installed or uninstalled separately from its parent mod");
|
||||||
@ -412,6 +414,9 @@ QString CModListView::genModInfoText(const ModState & mod)
|
|||||||
if(mod.isSubmod())
|
if(mod.isSubmod())
|
||||||
notes += noteTemplate.arg(thisIsSubmod);
|
notes += noteTemplate.arg(thisIsSubmod);
|
||||||
|
|
||||||
|
if (mod.isTranslation() && CGeneralTextHandler::getPreferredLanguage() != mod.getBaseLanguage().toStdString())
|
||||||
|
notes += noteTemplate.arg(translationMismatch);
|
||||||
|
|
||||||
if(notes.size())
|
if(notes.size())
|
||||||
result += textTemplate.arg(tr("Notes")).arg(notes);
|
result += textTemplate.arg(tr("Notes")).arg(notes);
|
||||||
|
|
||||||
@ -456,6 +461,7 @@ void CModListView::selectMod(const QModelIndex & index)
|
|||||||
|
|
||||||
QStringList notInstalledDependencies = this->getModsToInstall(modName);
|
QStringList notInstalledDependencies = this->getModsToInstall(modName);
|
||||||
QStringList unavailableDependencies = this->findUnavailableMods(notInstalledDependencies);
|
QStringList unavailableDependencies = this->findUnavailableMods(notInstalledDependencies);
|
||||||
|
bool translationMismatch = mod.isTranslation() && CGeneralTextHandler::getPreferredLanguage() != mod.getBaseLanguage().toStdString();
|
||||||
|
|
||||||
ui->disableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && modStateModel->isModEnabled(mod.getID()));
|
ui->disableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && modStateModel->isModEnabled(mod.getID()));
|
||||||
ui->enableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && !modStateModel->isModEnabled(mod.getID()));
|
ui->enableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && !modStateModel->isModEnabled(mod.getID()));
|
||||||
@ -465,7 +471,7 @@ void CModListView::selectMod(const QModelIndex & index)
|
|||||||
|
|
||||||
// Block buttons if action is not allowed at this time
|
// Block buttons if action is not allowed at this time
|
||||||
ui->disableButton->setEnabled(true);
|
ui->disableButton->setEnabled(true);
|
||||||
ui->enableButton->setEnabled(notInstalledDependencies.empty());
|
ui->enableButton->setEnabled(notInstalledDependencies.empty() && !translationMismatch);
|
||||||
ui->installButton->setEnabled(unavailableDependencies.empty());
|
ui->installButton->setEnabled(unavailableDependencies.empty());
|
||||||
ui->uninstallButton->setEnabled(true);
|
ui->uninstallButton->setEnabled(true);
|
||||||
ui->updateButton->setEnabled(unavailableDependencies.empty());
|
ui->updateButton->setEnabled(unavailableDependencies.empty());
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "../../lib/modding/CModHandler.h"
|
#include "../../lib/modding/CModHandler.h"
|
||||||
#include "../../lib/modding/IdentifierStorage.h"
|
#include "../../lib/modding/IdentifierStorage.h"
|
||||||
#include "../../lib/json/JsonNode.h"
|
#include "../../lib/json/JsonNode.h"
|
||||||
|
#include "../../lib/texts/CGeneralTextHandler.h"
|
||||||
|
|
||||||
#include "../vcmiqt/jsonutils.h"
|
#include "../vcmiqt/jsonutils.h"
|
||||||
#include "../vcmiqt/launcherdirs.h"
|
#include "../vcmiqt/launcherdirs.h"
|
||||||
@ -156,6 +157,9 @@ bool ModStateController::canEnableMod(QString modname)
|
|||||||
if(!mod.isCompatible())
|
if(!mod.isCompatible())
|
||||||
return addError(modname, tr("Mod is not compatible, please update VCMI and checkout latest mod revisions"));
|
return addError(modname, tr("Mod is not compatible, please update VCMI and checkout latest mod revisions"));
|
||||||
|
|
||||||
|
if (mod.isTranslation() && CGeneralTextHandler::getPreferredLanguage() != mod.getBaseLanguage().toStdString())
|
||||||
|
return addError(modname, tr("Can not enable translation mod for a different language!"));
|
||||||
|
|
||||||
for(const auto & modEntry : mod.getDependencies())
|
for(const auto & modEntry : mod.getDependencies())
|
||||||
{
|
{
|
||||||
if(!modList->isModExists(modEntry)) // required mod is not available
|
if(!modList->isModExists(modEntry)) // required mod is not available
|
||||||
|
@ -205,7 +205,8 @@ TModList ModsPresetState::getActiveRootMods() const
|
|||||||
{
|
{
|
||||||
const JsonNode & modsToActivateJson = getActivePresetConfig()["mods"];
|
const JsonNode & modsToActivateJson = getActivePresetConfig()["mods"];
|
||||||
auto modsToActivate = modsToActivateJson.convertTo<std::vector<TModID>>();
|
auto modsToActivate = modsToActivateJson.convertTo<std::vector<TModID>>();
|
||||||
modsToActivate.push_back(ModScope::scopeBuiltin());
|
if (!vstd::contains(modsToActivate, ModScope::scopeBuiltin()))
|
||||||
|
modsToActivate.push_back(ModScope::scopeBuiltin());
|
||||||
return modsToActivate;
|
return modsToActivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,11 +283,17 @@ std::vector<TModID> ModsPresetState::getActiveMods() const
|
|||||||
|
|
||||||
for(const auto & activeMod : activeRootMods)
|
for(const auto & activeMod : activeRootMods)
|
||||||
{
|
{
|
||||||
|
assert(!vstd::contains(allActiveMods, activeMod));
|
||||||
allActiveMods.push_back(activeMod);
|
allActiveMods.push_back(activeMod);
|
||||||
|
|
||||||
for(const auto & submod : getModSettings(activeMod))
|
for(const auto & submod : getModSettings(activeMod))
|
||||||
|
{
|
||||||
if(submod.second)
|
if(submod.second)
|
||||||
|
{
|
||||||
|
assert(!vstd::contains(allActiveMods, activeMod + '.' + submod.first));
|
||||||
allActiveMods.push_back(activeMod + '.' + submod.first);
|
allActiveMods.push_back(activeMod + '.' + submod.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return allActiveMods;
|
return allActiveMods;
|
||||||
}
|
}
|
||||||
@ -464,7 +471,7 @@ void ModManager::addNewModsToPreset()
|
|||||||
const auto & modSettings = modsPreset->getModSettings(rootMod);
|
const auto & modSettings = modsPreset->getModSettings(rootMod);
|
||||||
|
|
||||||
if (!modSettings.count(settingID))
|
if (!modSettings.count(settingID))
|
||||||
modsPreset->setSettingActive(rootMod, settingID, modsStorage->getMod(modID).keepDisabled());
|
modsPreset->setSettingActive(rootMod, settingID, !modsStorage->getMod(modID).keepDisabled());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,24 +509,25 @@ void ModManager::tryEnableMods(const TModList & modList)
|
|||||||
for (const auto & modName : modList)
|
for (const auto & modName : modList)
|
||||||
{
|
{
|
||||||
for (const auto & dependency : collectDependenciesRecursive(modName))
|
for (const auto & dependency : collectDependenciesRecursive(modName))
|
||||||
|
{
|
||||||
if (!vstd::contains(requiredActiveMods, dependency))
|
if (!vstd::contains(requiredActiveMods, dependency))
|
||||||
|
{
|
||||||
requiredActiveMods.push_back(dependency);
|
requiredActiveMods.push_back(dependency);
|
||||||
|
vstd::erase(additionalActiveMods, dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(!vstd::contains(additionalActiveMods, modName));
|
assert(!vstd::contains(additionalActiveMods, modName));
|
||||||
assert(vstd::contains(requiredActiveMods, modName));// FIXME: fails on attempt to enable broken mod / translation to other language
|
assert(vstd::contains(requiredActiveMods, modName));// FIXME: fails on attempt to enable broken mod / translation to other language
|
||||||
}
|
}
|
||||||
|
|
||||||
ModDependenciesResolver testResolver(requiredActiveMods, *modsStorage);
|
ModDependenciesResolver testResolver(requiredActiveMods, *modsStorage);
|
||||||
assert(testResolver.getBrokenMods().empty());
|
|
||||||
|
|
||||||
testResolver.tryAddMods(additionalActiveMods, *modsStorage);
|
testResolver.tryAddMods(additionalActiveMods, *modsStorage);
|
||||||
|
|
||||||
for (const auto & modName : modList)
|
for (const auto & modName : modList)
|
||||||
{
|
|
||||||
assert(vstd::contains(testResolver.getActiveMods(), modName));
|
|
||||||
if (!vstd::contains(testResolver.getActiveMods(), modName))
|
if (!vstd::contains(testResolver.getActiveMods(), modName))
|
||||||
throw std::runtime_error("Failed to enable mod! Mod " + modName + " remains disabled!");
|
throw std::runtime_error("Failed to enable mod! Mod " + modName + " remains disabled!");
|
||||||
}
|
|
||||||
|
|
||||||
updatePreset(testResolver);
|
updatePreset(testResolver);
|
||||||
}
|
}
|
||||||
@ -536,6 +544,7 @@ void ModManager::tryDisableMod(const TModID & modName)
|
|||||||
if (vstd::contains(testResolver.getActiveMods(), modName))
|
if (vstd::contains(testResolver.getActiveMods(), modName))
|
||||||
throw std::runtime_error("Failed to disable mod! Mod " + modName + " remains enabled!");
|
throw std::runtime_error("Failed to disable mod! Mod " + modName + " remains enabled!");
|
||||||
|
|
||||||
|
modsPreset->setModActive(modName, false);
|
||||||
updatePreset(testResolver);
|
updatePreset(testResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +560,11 @@ void ModManager::updatePreset(const ModDependenciesResolver & testResolver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & modID : newBrokenMods)
|
for (const auto & modID : newBrokenMods)
|
||||||
modsPreset->setModActive(modID, false);
|
{
|
||||||
|
const auto & mod = getModDescription(modID);
|
||||||
|
if (vstd::contains(newActiveMods, mod.getTopParentID()))
|
||||||
|
modsPreset->setModActive(modID, false);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<TModID> desiredModList = modsPreset->getActiveMods();
|
std::vector<TModID> desiredModList = modsPreset->getActiveMods();
|
||||||
depedencyResolver = std::make_unique<ModDependenciesResolver>(desiredModList, *modsStorage);
|
depedencyResolver = std::make_unique<ModDependenciesResolver>(desiredModList, *modsStorage);
|
||||||
@ -620,6 +633,7 @@ void ModDependenciesResolver::tryAddMods(TModList modsToResolve, const ModsStora
|
|||||||
if(isResolved(storage.getMod(*it)))
|
if(isResolved(storage.getMod(*it)))
|
||||||
{
|
{
|
||||||
resolvedOnCurrentTreeLevel.insert(*it); // Not to the resolvedModIDs, so current node children will be resolved on the next iteration
|
resolvedOnCurrentTreeLevel.insert(*it); // Not to the resolvedModIDs, so current node children will be resolved on the next iteration
|
||||||
|
assert(!vstd::contains(sortedValidMods, *it));
|
||||||
sortedValidMods.push_back(*it);
|
sortedValidMods.push_back(*it);
|
||||||
it = modsToResolve.erase(it);
|
it = modsToResolve.erase(it);
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user