123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- /*
- * ActiveModsInSaveList.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 "ActiveModsInSaveList.h"
- #include "../VCMI_Lib.h"
- #include "CModInfo.h"
- #include "CModHandler.h"
- #include "ModIncompatibility.h"
- VCMI_LIB_NAMESPACE_BEGIN
- std::vector<TModID> ActiveModsInSaveList::getActiveMods()
- {
- return VLC->modh->getActiveMods();
- }
- const ModVerificationInfo & ActiveModsInSaveList::getVerificationInfo(TModID mod)
- {
- return VLC->modh->getModInfo(mod).getVerificationInfo();
- }
- void ActiveModsInSaveList::verifyActiveMods(const std::vector<std::pair<TModID, ModVerificationInfo>> & modList)
- {
- auto searchVerificationInfo = [&modList](const TModID & m) -> const ModVerificationInfo*
- {
- for(auto & i : modList)
- if(i.first == m)
- return &i.second;
- return nullptr;
- };
- std::vector<TModID> missingMods, excessiveMods;
- ModIncompatibility::ModListWithVersion missingModsResult;
- ModIncompatibility::ModList excessiveModsResult;
- for(const auto & m : VLC->modh->getActiveMods())
- {
- if(searchVerificationInfo(m))
- continue;
- //TODO: support actual disabling of these mods
- if(VLC->modh->getModInfo(m).checkModGameplayAffecting())
- excessiveMods.push_back(m);
- }
- for(const auto & infoPair : modList)
- {
- auto & remoteModId = infoPair.first;
- auto & remoteModInfo = infoPair.second;
- bool modAffectsGameplay = remoteModInfo.impactsGameplay;
- //parent mod affects gameplay if child affects too
- for(const auto & subInfoPair : modList)
- modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
- if(!vstd::contains(VLC->modh->getAllMods(), remoteModId))
- {
- if(modAffectsGameplay)
- missingMods.push_back(remoteModId); //mod is not installed
- continue;
- }
- auto & localModInfo = VLC->modh->getModInfo(remoteModId).getVerificationInfo();
- modAffectsGameplay |= VLC->modh->getModInfo(remoteModId).checkModGameplayAffecting();
- bool modVersionCompatible = localModInfo.version.isNull()
- || remoteModInfo.version.isNull()
- || localModInfo.version.compatible(remoteModInfo.version);
- bool modLocalyEnabled = vstd::contains(VLC->modh->getActiveMods(), remoteModId);
- if(modVersionCompatible && modAffectsGameplay && modLocalyEnabled)
- continue;
- if(modAffectsGameplay)
- missingMods.push_back(remoteModId); //incompatible mod impacts gameplay
- }
- //filter mods
- for(auto & m : missingMods)
- {
- if(auto * vInfo = searchVerificationInfo(m))
- {
- assert(vInfo->parent != m);
- if(!vInfo->parent.empty() && vstd::contains(missingMods, vInfo->parent))
- continue;
- missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
- }
- }
- for(auto & m : excessiveMods)
- {
- auto & vInfo = VLC->modh->getModInfo(m).getVerificationInfo();
- assert(vInfo.parent != m);
- if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
- continue;
- excessiveModsResult.push_back(vInfo.name);
- }
- if(!missingModsResult.empty() || !excessiveModsResult.empty())
- throw ModIncompatibility(missingModsResult, excessiveModsResult);
- //TODO: support actual enabling of required mods
- }
- VCMI_LIB_NAMESPACE_END
|