1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Added mod type "Compatibility" that is hidden in launcher

This commit is contained in:
Ivan Savenko 2023-10-21 23:55:20 +03:00
parent f3acc939b9
commit b50ebba1ba
10 changed files with 42 additions and 31 deletions

View File

@ -55,7 +55,7 @@
},
"modType" : {
"type" : "string",
"enum" : [ "Translation", "Town", "Test", "Templates", "Spells", "Music", "Sounds", "Skills", "Other", "Objects", "Mechanics", "Interface", "Heroes", "Graphical", "Expansion", "Creatures", "Artifacts", "AI" ],
"enum" : [ "Translation", "Town", "Test", "Templates", "Spells", "Music", "Maps", "Sounds", "Skills", "Other", "Objects", "Mechanics", "Interface", "Heroes", "Graphical", "Expansion", "Creatures", "Compatibility", "Artifacts", "AI" ],
"description" : "Type of mod, e.g. Town, Artifacts, Graphical."
},
"author" : {

View File

@ -30,11 +30,12 @@
"version" : "1.2.3"
// Type of mod, list of all possible values:
// "Translation", "Town", "Test", "Templates", "Spells", "Music", "Sounds", "Skills", "Other", "Objects",
// "Mechanics", "Interface", "Heroes", "Graphical", "Expansion", "Creatures", "Artifacts", "AI"
// "Translation", "Town", "Test", "Templates", "Spells", "Music", "Maps", "Sounds", "Skills", "Other", "Objects",
// "Mechanics", "Interface", "Heroes", "Graphical", "Expansion", "Creatures", "Compatibility", "Artifacts", "AI"
//
// Some mod types have additional effects on your mod:
// Translation: mod of this type is only active if player uses base language of this mod. See "language" property.
// Compatibility: mods of this type are hidden in UI and will be automatically activated if all mod dependencies are active. Intended to be used to provide compatibility patches between mods
"modType" : "Graphical",
// Base language of the mod, before applying localizations. By default vcmi assumes English

View File

@ -90,14 +90,22 @@ bool CModEntry::isInstalled() const
return !localData.isEmpty();
}
bool CModEntry::isValid() const
bool CModEntry::isVisible() const
{
if (getBaseValue("modType").toString() == "Compatibility" && isSubmod())
return false;
return !localData.isEmpty() || !repository.isEmpty();
}
bool CModEntry::isTranslation() const
{
return getBaseValue("modType").toString().toLower() == "translation";
return getBaseValue("modType").toString() == "Translation";
}
bool CModEntry::isSubmod() const
{
return getName().contains('.');
}
int CModEntry::getModStatus() const

View File

@ -60,10 +60,12 @@ public:
bool isEssential() const;
// checks if verison is compatible with vcmi
bool isCompatible() const;
// returns if has any data
bool isValid() const;
// returns true if mod should be visible in Launcher
bool isVisible() const;
// installed and enabled
bool isTranslation() const;
// returns true if this is a submod
bool isSubmod() const;
// see ModStatus enum
int getModStatus() const;

View File

@ -45,6 +45,7 @@ QString CModListModel::modTypeName(QString modTypeID) const
{"Templates", tr("Templates") },
{"Spells", tr("Spells") },
{"Music", tr("Music") },
{"Maps", tr("Maps") },
{"Sounds", tr("Sounds") },
{"Skills", tr("Skills") },
{"Other", tr("Other") },
@ -58,6 +59,7 @@ QString CModListModel::modTypeName(QString modTypeID) const
{"Graphical", tr("Graphical") },
{"Expansion", tr("Expansion") },
{"Creatures", tr("Creatures") },
{"Compatibility", tr("Compatibility") },
{"Artifacts", tr("Artifacts") },
{"AI", tr("AI") },
};
@ -257,7 +259,6 @@ bool CModFilterModel::filterMatchesThis(const QModelIndex & source) const
{
CModEntry mod = base->getMod(source.data(ModRoles::ModNameRole).toString());
return (mod.getModStatus() & filterMask) == filteredType &&
mod.isValid() &&
QSortFilterProxyModel::filterAcceptsRow(source.row(), source.parent());
}
@ -265,6 +266,10 @@ bool CModFilterModel::filterAcceptsRow(int source_row, const QModelIndex & sourc
{
QModelIndex index = base->index(source_row, 0, source_parent);
CModEntry mod = base->getMod(index.data(ModRoles::ModNameRole).toString());
if (!mod.isVisible())
return false;
if(filterMatchesThis(index))
{
return true;

View File

@ -332,7 +332,7 @@ QString CModListView::genModInfoText(CModEntry & mod)
if(mod.isInstalled())
notes += replaceIfNotEmpty(getModNames(findDependentMods(mod.getName(), false)), listTemplate.arg(hasDependentMods));
if(mod.getName().contains('.'))
if(mod.isSubmod())
notes += noteTemplate.arg(thisIsSubmod);
if(notes.size())
@ -374,8 +374,8 @@ void CModListView::selectMod(const QModelIndex & index)
ui->disableButton->setVisible(mod.isEnabled());
ui->enableButton->setVisible(mod.isDisabled());
ui->installButton->setVisible(mod.isAvailable() && !mod.getName().contains('.'));
ui->uninstallButton->setVisible(mod.isInstalled() && !mod.getName().contains('.'));
ui->installButton->setVisible(mod.isAvailable() && !mod.isSubmod());
ui->uninstallButton->setVisible(mod.isInstalled() && !mod.isSubmod());
ui->updateButton->setVisible(mod.isUpdateable());
// Block buttons if action is not allowed at this time
@ -921,7 +921,7 @@ void CModListView::on_allModsView_doubleClicked(const QModelIndex &index)
bool hasBlockingMods = !findBlockingMods(modName).empty();
bool hasDependentMods = !findDependentMods(modName, true).empty();
if(!hasInvalidDeps && mod.isAvailable() && !mod.getName().contains('.'))
if(!hasInvalidDeps && mod.isAvailable() && !mod.isSubmod())
{
on_installButton_clicked();
return;

View File

@ -154,7 +154,7 @@ bool CModManager::canInstallMod(QString modname)
{
auto mod = modList->getMod(modname);
if(mod.getName().contains('.'))
if(mod.isSubmod())
return addError(modname, "Can not install submod");
if(mod.isInstalled())
@ -169,7 +169,7 @@ bool CModManager::canUninstallMod(QString modname)
{
auto mod = modList->getMod(modname);
if(mod.getName().contains('.'))
if(mod.isSubmod())
return addError(modname, "Can not uninstall submod");
if(!mod.isInstalled())

View File

@ -128,8 +128,8 @@ std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModI
const CModInfo & brokenMod = allMods.at(brokenModID);
for(const TModID & dependency : brokenMod.dependencies)
{
if(!vstd::contains(resolvedModIDs, dependency))
logMod->error("Mod '%s' will not work: it depends on mod '%s', which is not installed.", brokenMod.getVerificationInfo().name, dependency);
if(!vstd::contains(resolvedModIDs, dependency) && brokenMod.config["modType"].String() != "Compatibility")
logMod->error("Mod '%s' has been disabled: dependency '%s' is missing.", brokenMod.getVerificationInfo().name, dependency);
}
}
return sortedValidMods;

View File

@ -32,7 +32,6 @@ CModInfo::CModInfo():
CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const JsonNode & config):
identifier(identifier),
description(config["description"].String()),
dependencies(config["depends"].convertTo<std::set<std::string>>()),
conflicts(config["conflicts"].convertTo<std::set<std::string>>()),
explicitlyEnabled(false),
@ -45,7 +44,7 @@ CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const
verificationInfo.parent = identifier.substr(0, identifier.find_last_of('.'));
if(verificationInfo.parent == identifier)
verificationInfo.parent.clear();
if(!config["compatibility"].isNull())
{
vcmiCompatibleMin = CModVersion::fromString(config["compatibility"]["min"].String());
@ -98,11 +97,7 @@ void CModInfo::loadLocalData(const JsonNode & data)
implicitlyEnabled = true;
explicitlyEnabled = !config["keepDisabled"].Bool();
verificationInfo.checksum = 0;
if (data.getType() == JsonNode::JsonType::DATA_BOOL)
{
explicitlyEnabled = data.Bool();
}
if (data.getType() == JsonNode::JsonType::DATA_STRUCT)
if (data.isStruct())
{
explicitlyEnabled = data["active"].Bool();
validated = data["validated"].Bool();
@ -116,7 +111,7 @@ void CModInfo::loadLocalData(const JsonNode & data)
if(!implicitlyEnabled)
logGlobal->warn("Mod %s is incompatible with current version of VCMI and cannot be enabled", verificationInfo.name);
if (boost::iequals(config["modType"].String(), "translation")) // compatibility code - mods use "Translation" type at the moment
if (config["modType"].String() == "Translation")
{
if (baseLanguage != VLC->generaltexth->getPreferredLanguage())
{
@ -124,12 +119,18 @@ void CModInfo::loadLocalData(const JsonNode & data)
implicitlyEnabled = false;
}
}
if (config["modType"].String() == "Compatibility")
{
// compatibility mods are always explicitly enabled
// however they may be implicitly disabled - if one of their dependencies is missing
explicitlyEnabled = true;
}
if (isEnabled())
validation = validated ? PASSED : PENDING;
else
validation = validated ? PASSED : FAILED;
verificationInfo.impactsGameplay = checkModGameplayAffecting();
}
@ -185,9 +186,4 @@ bool CModInfo::isEnabled() const
return implicitlyEnabled && explicitlyEnabled;
}
void CModInfo::setEnabled(bool on)
{
explicitlyEnabled = on;
}
VCMI_LIB_NAMESPACE_END

View File

@ -87,7 +87,6 @@ public:
void updateChecksum(ui32 newChecksum);
bool isEnabled() const;
void setEnabled(bool on);
static std::string getModDir(const std::string & name);
static JsonPath getModFile(const std::string & name);