/// <summary> /// Creates a list of the minimum set of maps that contain all of the specified tags. /// </summary> public List <TagSet> BuildTagLocationList(string[] tags, GameDefinition game) { ulong availableMapsBitmask = game.GetAvailableMapsBitmask(); List <TagSet> locationList = new List <TagSet>(); List <TagArchiveFileTableEntry> list = new List <TagArchiveFileTableEntry>(); List <string> unextractableTags = new List <string>(); foreach (string tag in tags) { TagArchiveFileTableEntry entry = (TagArchiveFileTableEntry)FileTable.GetEntry(tag, EntryType.File); if (entry == null) { throw new Exception("The specified tag was not found in the file table: " + tag); } list.Add(entry); } bool incompleteExtraction = false; while (list.Count > 0) { int[] maps = GetOptimalSourceMaps(list, availableMapsBitmask); // Get the smallest file. int smallestMapIndex = -1; for (int x = 0; x < maps.Length; x++) { if (smallestMapIndex == -1) { smallestMapIndex = maps[x]; } else if (game.Maps[maps[x]].FileSize < game.Maps[smallestMapIndex].FileSize) { smallestMapIndex = maps[x]; } } TagSet set = new TagSet(smallestMapIndex); if (set.MapIndex == -1) { foreach (TagArchiveFileTableEntry entry in list) { unextractableTags.Add(entry.FullPath); } list.Clear(); incompleteExtraction = true; } else { for (int x = 0; x < list.Count; x++) { TagArchiveFileTableEntry entry = list[x]; if (((ulong)(0x1 << set.MapIndex) & entry.MapsBitmask) != 0) { set.Tags.Add(entry.FullPath); list.Remove(entry); x--; } } locationList.Add(set); } } if (incompleteExtraction) { Output.Write(OutputTypes.Warning, "One or more of the specified tags do not exist in any of the available maps.", unextractableTags.ToArray()); } return(locationList); }
protected override void CreateRootEntry() { rootEntry = new TagArchiveFileTableEntry(EntryType.Folder); }