void C4SDefinitions::SetModules(const char *szList, const char *szRelativeToPath, const char *szRelativeToPath2) { int32_t cnt; // Empty list: local only if (!SModuleCount(szList)) { LocalOnly=true; for (cnt=0; cnt<C4S_MaxDefinitions; cnt++) Definition[cnt][0]=0; return; } // Set list LocalOnly=false; for (cnt=0; cnt<C4S_MaxDefinitions; cnt++) { SGetModule(szList,cnt,Definition[cnt],_MAX_PATH); // Make relative path if (szRelativeToPath && *szRelativeToPath) { if (GetRelativePathS(Definition[cnt],szRelativeToPath) != Definition[cnt]) { SCopy(GetRelativePathS(Definition[cnt],szRelativeToPath),Definition[cnt]); continue; } } if (szRelativeToPath2 && *szRelativeToPath2) { if (GetRelativePathS(Definition[cnt],szRelativeToPath2) != Definition[cnt]) { SCopy(GetRelativePathS(Definition[cnt],szRelativeToPath2),Definition[cnt]); continue; } } } }
C4GroupSet C4Language::GetPackGroups(C4Group & hGroup) { // Build a group set containing the provided group and // alternative groups for cross-loading from a language pack char strRelativePath[_MAX_PATH + 1]; char strTargetLocation[_MAX_PATH + 1]; char strPackPath[_MAX_PATH + 1]; char strPackGroupLocation[_MAX_PATH + 1]; char strAdvance[_MAX_PATH + 1]; // Store wanted target location SCopy(Config.AtRelativePath(hGroup.GetFullName().getData()), strRelativePath, _MAX_PATH); SCopy(strRelativePath, strTargetLocation, _MAX_PATH); // Adjust location by scenario origin if (Game.C4S.Head.Origin.getLength() && SEqualNoCase(GetExtension(Game.C4S.Head.Origin.getData()), "ocs")) { const char *szScenarioRelativePath = GetRelativePathS(strRelativePath, Config.AtRelativePath(Game.ScenarioFilename)); if (szScenarioRelativePath != strRelativePath) { // this is a path within the scenario! Change to origin. size_t iRestPathLen = SLen(szScenarioRelativePath); if (Game.C4S.Head.Origin.getLength() + 1 + iRestPathLen <= _MAX_PATH) { SCopy(Game.C4S.Head.Origin.getData(), strTargetLocation); if (iRestPathLen) { SAppendChar(DirectorySeparator, strTargetLocation); SAppend(szScenarioRelativePath, strTargetLocation); } } } } // Process all language packs (and their respective pack groups) C4Group *pPack, *pPackGroup; for (int iPack = 0; (pPack = Packs.GetGroup(iPack)) && (pPackGroup = PackGroups.GetGroup(iPack)); iPack++) { // Get current pack group position within pack SCopy(pPack->GetFullName().getData(), strPackPath, _MAX_PATH); GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation); // Pack group is at correct position within pack: continue with next pack if (SEqualNoCase(strPackGroupLocation, strTargetLocation)) continue; // Try to backtrack until we can reach the target location as a relative child while ( strPackGroupLocation[0] && !GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance) && pPackGroup->OpenMother() ) { // Update pack group location GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation); } // We can reach the target location as a relative child if (strPackGroupLocation[0] && GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance)) { // Advance pack group to relative child pPackGroup->OpenChild(strAdvance); } // Cannot reach by advancing: need to close and reopen (rewinding group file) else { // Close pack group (if it is open at all) pPackGroup->Close(); // Reopen pack group to relative position in language pack if possible pPackGroup->OpenAsChild(pPack, strTargetLocation); } } // Store new target location SCopy(strTargetLocation, PackGroupLocation, _MAX_FNAME); C4GroupSet r; // Provided group gets highest priority r.RegisterGroup(hGroup, false, 1000, C4GSCnt_Component); // register currently open pack groups r.RegisterGroups(PackGroups, C4GSCnt_Language); return r; }