public ParticleManifest(List <string> sourceDirectories, List <string> ignoreDirectories, List <string> excludedFiles, BSP map, string bspPath, string gameFolder) { CompilePalLogger.LogLine("Generating Particle Manifest..."); baseDirectory = gameFolder + "\\"; particles = new List <PCF>(); //Search directories for pcf and find particles that match used particle names //TODO multithread this? foreach (string sourceDirectory in sourceDirectories) { string externalPath = sourceDirectory + "\\" + internalPath; if (Directory.Exists(externalPath) && !ignoreDirectories.Contains(externalPath.Remove(externalPath.Length - 1, 1), StringComparer.OrdinalIgnoreCase)) { foreach (string file in Directory.GetFiles(externalPath)) { if (file.EndsWith(".pcf") && !excludedFiles.Contains(file.ToLower())) { PCF pcf = ParticleUtils.IsTargetParticle(file, map.ParticleList); if (pcf != null && !particles.Exists(p => p.FilePath == pcf.FilePath)) { particles.Add(pcf); } } } } } if (particles == null || particles.Count == 0) { CompilePalLogger.LogCompileError("Could not find any PCFs that contained used particles!\n", new Error("Could not find any PCFs that contained used particles!\n", ErrorSeverity.Warning)); return; } //Check for pcfs that contain the same particle name //List<ParticleConflict> conflictingParticles = new List<ParticleConflict>(); List <PCF> conflictingParticles = new List <PCF>(); if (particles.Count > 1) { for (int i = 0; i < particles.Count - 1; i++) { for (int j = i + 1; j < particles.Count; j++) { //Create a list of names that intersect between the 2 lists List <string> conflictingNames = particles[i].ParticleNames.Intersect(particles[j].ParticleNames).ToList(); if (conflictingNames.Count != 0 && particles[i].FilePath != particles[j].FilePath) { //pc.conflictingNames = conflictingNames; conflictingParticles.Add(particles[i]); conflictingParticles.Add(particles[j]); } } } } //Solve conflicts if (conflictingParticles.Count != 0) { //Remove particle if it is in a particle conflict, add back when conflict is manually resolved foreach (PCF conflictParticle in conflictingParticles) { particles.Remove(conflictParticle); } List <PCF> resolvedConflicts = new List <PCF>(); //Bring up conflict window //Have to run on STAthread Application.Current.Dispatcher.Invoke((Action) delegate { //Make taskbar icon red ProgressManager.ErrorProgress(); //Create window ConflictWindow cw = new ConflictWindow(conflictingParticles, map.ParticleList); cw.ShowDialog(); //Get resolved conflicts resolvedConflicts = cw.selectedPCFS; }); //Add resolved conflicts back into particle list particles.AddRange(resolvedConflicts); } //Remove duplicates particles = particles.Distinct().ToList(); //Dont create particle manifest if there is no particles if (particles.Count == 0) { return; } //Generate manifest file filepath = bspPath.Remove(bspPath.Length - 4, 4) + "_particles.txt"; //Write manifest using (StreamWriter sw = new StreamWriter(filepath)) { sw.WriteLine("particles_manifest"); sw.WriteLine("{"); foreach (string source in sourceDirectories) { foreach (PCF particle in particles) { if (particle.FilePath.StartsWith(source + "\\" + internalPath)) { // add 1 for the backslash between source dir and particle path string internalParticlePath = particle.FilePath.Remove(0, source.Length + 1); sw.WriteLine($" \"file\" \"!{internalParticlePath}\""); CompilePalLogger.LogLine($"PCF added to manifest: {internalParticlePath}"); } } } sw.WriteLine("}"); } string internalDirectory = filepath; if (filepath.ToLower().StartsWith(baseDirectory.ToLower())) { internalDirectory = filepath.Substring(baseDirectory.Length); } //Store internal/external dir so it can be packed particleManifest = new KeyValuePair <string, string>(internalDirectory, filepath); }