소스 검색

Show root mods only

nordsoft 2 년 전
부모
커밋
4691907f9c
6개의 변경된 파일43개의 추가작업 그리고 17개의 파일을 삭제
  1. 2 1
      client/CServerHandler.cpp
  2. 0 2
      client/NetPacksLobbyClient.cpp
  3. 2 0
      lib/mapping/MapFormatJson.cpp
  4. 32 14
      lib/modding/CModHandler.cpp
  5. 3 0
      lib/modding/CModInfo.cpp
  6. 4 0
      lib/modding/CModInfo.h

+ 2 - 1
client/CServerHandler.cpp

@@ -572,7 +572,8 @@ bool CServerHandler::validateGameStart(bool allowOnlyAI) const
 void CServerHandler::sendStartGame(bool allowOnlyAI) const
 {
 	verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool());
-
+	GH.windows().createAndPushWindow<CLoadingScreen>();
+	
 	LobbyStartGame lsg;
 	if(client)
 	{

+ 0 - 2
client/NetPacksLobbyClient.cpp

@@ -149,8 +149,6 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyLoadProgress(LobbyLoadProgress
 		w->tick(0);
 		w->redraw();
 	}
-	else
-		GH.windows().createAndPushWindow<CLoadingScreen>();
 }
 
 void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack)

+ 2 - 0
lib/mapping/MapFormatJson.cpp

@@ -958,6 +958,7 @@ void CMapLoaderJson::readHeader(const bool complete)
 			info.version = CModVersion::fromString(mod["version"].String());
 			info.checksum = mod["checksum"].Integer();
 			info.name = mod["name"].String();
+			info.parent = mod["parent"].String();
 			info.impactsGameplay = true;
 			
 			if(!mod["modId"].isNull())
@@ -1307,6 +1308,7 @@ void CMapSaverJson::writeHeader()
 		JsonNode modWriter;
 		modWriter["modId"].String() = mod.first;
 		modWriter["name"].String() = mod.second.name;
+		modWriter["parent"].String() = mod.second.parent;
 		modWriter["version"].String() = mod.second.version.toString();
 		modWriter["checksum"].Integer() = mod.second.checksum;
 		mods.Vector().push_back(modWriter);

+ 32 - 14
lib/modding/CModHandler.cpp

@@ -473,41 +473,46 @@ void CModHandler::afterLoad(bool onlyEssential)
 
 void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo::VerificationInfo>> & modList)
 {
-	auto hasMod = [&modList](const TModID & m) -> bool
+	auto searchVerificationInfo = [&modList](const TModID & m) -> const CModInfo::VerificationInfo*
 	{
 		for(auto & i : modList)
 			if(i.first == m)
-				return true;
-		return false;
+				return &i.second;
+		return nullptr;
 	};
 	
 	for(const auto & m : activeMods)
 	{
-		if(hasMod(m))
+		if(searchVerificationInfo(m))
 			continue;
 
+		//TODO: support actual disabling of these mods
 		if(getModInfo(m).checkModGameplayAffecting())
 			allMods[m].setEnabled(false);
 	}
 
-	std::vector<TModID> newActiveMods;
-	ModIncompatibility::ModList missingMods;
+	std::vector<TModID> newActiveMods, missingMods;
+	ModIncompatibility::ModList missingModsResult;
 	
 	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(!allMods.count(remoteModId))
 		{
-			if(remoteModInfo.impactsGameplay)
-				missingMods.push_back({remoteModInfo.name, remoteModInfo.version.toString()}); //mod is not installed
+			if(modAffectsGameplay)
+				missingMods.push_back(remoteModId); //mod is not installed
 			continue;
 		}
 		
 		auto & localModInfo = getModInfo(remoteModId).getVerificationInfo();
-
-		bool modAffectsGameplay = getModInfo(remoteModId).checkModGameplayAffecting();
+		modAffectsGameplay |= getModInfo(remoteModId).checkModGameplayAffecting();
 		bool modVersionCompatible = localModInfo.version.isNull()
 			|| remoteModInfo.version.isNull()
 			|| localModInfo.version.compatible(remoteModInfo.version);
@@ -519,13 +524,26 @@ void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo:
 			continue;
 		}
 		
-		if(modAffectsGameplay || remoteModInfo.impactsGameplay)
-			missingMods.push_back({remoteModInfo.name, remoteModInfo.version.toString()}); //incompatible mod impacts gameplay
+		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()});
+		}
 	}
 	
-	if(!missingMods.empty())
-		throw ModIncompatibility(std::move(missingMods));
+	if(!missingModsResult.empty())
+		throw ModIncompatibility(std::move(missingModsResult));
 	
+	//TODO: support actual enabling of these mods
 	for(auto & m : newActiveMods)
 		allMods[m].setEnabled(true);
 

+ 3 - 0
lib/modding/CModInfo.cpp

@@ -42,6 +42,9 @@ CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const
 {
 	verificationInfo.name = config["name"].String();
 	verificationInfo.version = CModVersion::fromString(config["version"].String());
+	verificationInfo.parent = identifier.substr(0, identifier.find_last_of('.'));
+	if(verificationInfo.parent == identifier)
+		verificationInfo.parent.clear();
 	
 	if(!config["compatibility"].isNull())
 	{

+ 4 - 0
lib/modding/CModInfo.h

@@ -41,6 +41,9 @@ public:
 		/// CRC-32 checksum of the mod
 		ui32 checksum = 0;
 		
+		/// parent mod ID, empty if root-level mod
+		TModID parent;
+		
 		/// for serialization purposes
 		bool impactsGameplay = true;
 		
@@ -50,6 +53,7 @@ public:
 			h & name;
 			h & version;
 			h & checksum;
+			h & parent;
 			h & impactsGameplay;
 		}
 	};