Ejemplo n.º 1
0
    public override bool IsOfType(ArchiveFileStream inputStream, IArchiveDataManager manager, TextureCooked?tex)
    {
        UbiArtSettings settings = manager.Context !.GetSettings <UbiArtSettings>();

        // TODO: Find better way to check this
        return(settings.Platform == Platform.Xbox360);
    }
        /// <summary>
        /// Converts from the format
        /// </summary>
        /// <returns>The task</returns>
        public override async Task ConvertFromAsync()
        {
            var attr     = GameModeSelection.SelectedValue.GetAttribute <UbiArtGameModeInfoAttribute>();
            var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform);

            if (GameModeSelection.SelectedValue == UbiArtGameMode.RaymanFiestaRunPC)
            {
                await ConvertFromAsync <FiestaRunLocalizationData>(settings, (data, filePath) =>
                {
                    // Save the data
                    SerializeJSON(data, filePath);
                }, new FileFilterItem("*.loc", "LOC").ToString(), new[]
                {
                    ".json"
                }, Games.RaymanFiestaRun.GetInstallDir(false));
            }
            else
            {
                var fileExtension = Equals(settings.StringEncoding, Encoding.UTF8) ? new FileFilterItem("*.loc8", "LOC8") : new FileFilterItem("*.loc", "LOC");

                await ConvertFromAsync <UbiArtLocalizationData>(settings, (data, filePath) =>
                {
                    // Save the data
                    SerializeJSON(data, filePath);
                }, fileExtension.ToString(), new[]
                {
                    ".json"
                }, GameModeSelection.SelectedValue.GetGame()?.GetInstallDir(false));
            }
        }
        /// <summary>
        /// Opens the archive explorer
        /// </summary>
        /// <returns>The task</returns>
        public async Task OpenAsync()
        {
            var attr     = GameMode.GetAttribute <UbiArtGameModeInfoAttribute>();
            var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform);

            // Show the archive explorer
            await RCPServices.UI.ShowArchiveExplorerAsync(new UbiArtIPKArchiveExplorerDataManager(settings), ArchiveFiles.Where(x => x.FileExists));
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="settings">The settings when serializing the data</param>
 /// <param name="compressionMode">The compression mode for files and the block</param>
 public UbiArtIPKArchiveConfigViewModel(UbiArtSettings settings, FileCompressionMode compressionMode)
 {
     CompressionMode      = compressionMode;
     Settings             = settings;
     CompressedExtensions = ".dtape.ckd," +
                            ".fx.fxb," +
                            ".m3d.ckd," +
                            ".png.ckd," +
                            ".tga.ckd";
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Converts to the format
        /// </summary>
        /// <returns>The task</returns>
        public override async Task ConvertToAsync()
        {
            var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, GameModeSelection.SelectedValue);

            await ConvertToAsync <OriginsPCSaveData>(settings, (filePath, format) =>
            {
                // Read the data
                return(DeserializeJSON <OriginsPCSaveData>(filePath));
            }, new FileFilterItem("*.json", "JSON").ToString(), new FileExtension(String.Empty));
        }
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="fileEntry">The file data</param>
 /// <param name="settings">The settings when serializing the data</param>
 /// <param name="baseOffset">The base offset to use when reading the files</param>
 public UbiArtIPKArchiveFileData(UbiArtIPKFileEntry fileEntry, UbiArtSettings settings, uint baseOffset)
 {
     // Get the file properties
     Directory     = fileEntry.Path.DirectoryPath;
     FileExtension = new FileExtension(fileEntry.Path.GetFileExtensions());
     FileName      = fileEntry.Path.FileName;
     FileEntry     = fileEntry;
     BaseOffset    = baseOffset;
     Settings      = settings;
 }
    /// <summary>
    /// Default constructor
    /// </summary>
    /// <param name="settings">The settings when serializing the data</param>
    /// <param name="compressionMode">The file compression mode</param>
    public UbiArtIPKArchiveDataManager(UbiArtSettings settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode compressionMode)
    {
        Context = new RCPContext(String.Empty, new RCPSerializerSettings()
        {
            DefaultEndianness = settings.GetEndian
        });
        Context.AddSettings(settings);

        Config = new UbiArtIPKArchiveConfigViewModel(settings, compressionMode);
    }
        /// <summary>
        /// Serializes the data to the localization file
        /// </summary>
        /// <param name="file">The localization file</param>
        /// <param name="data">The data</param>
        protected override void Serialize(FileSystemPath file, UbiArtLocStringValuePair[] data)
        {
            // Read the current data to get the remaining bytes
            var currentData = BinarySerializableHelpers.ReadFromFile <UbiArtLocalizationData>(file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger());

            // Replace the string data
            currentData.Strings = data;

            // Serialize the data
            BinarySerializableHelpers.WriteToFile(currentData, file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger());
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Converts from the format
        /// </summary>
        /// <returns>The task</returns>
        public override async Task ConvertFromAsync()
        {
            var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, GameModeSelection.SelectedValue);

            await ConvertFromAsync <JungleRunPCSaveData>(settings, (data, filePath) =>
            {
                // Save the data
                SerializeJSON(data, filePath);
            }, new FileFilterItem("*.dat", "DAT").ToString(), new[]
            {
                ".json"
            }, Environment.SpecialFolder.LocalApplicationData.GetFolderPath() + "Packages" + Games.RaymanJungleRun.GetManager <RCPWinStoreGame>().FullPackageName + "LocalState");
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Converts from the format
        /// </summary>
        /// <returns>The task</returns>
        public override async Task ConvertFromAsync()
        {
            var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, GameModeSelection.SelectedValue);

            await ConvertFromAsync <OriginsPCSaveData>(settings, (data, filePath) =>
            {
                // Save the data
                SerializeJSON(data, filePath);
            }, new FileFilterItem("*", String.Empty).ToString(), new[]
            {
                ".json"
            }, Environment.SpecialFolder.MyDocuments.GetFolderPath() + "My games" + "Rayman origins");
        }
        /// <summary>
        /// Imports an exported save slot to the save slot from the specified path
        /// </summary>
        /// <param name="inputFilePath">The input file path</param>
        /// <returns>The task</returns>
        protected override Task ImportSaveDataAsync(FileSystemPath inputFilePath)
        {
            // Get the serialized data
            var data = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger());

            // Deserialize the input data
            data.Levels = JsonHelpers.DeserializeFromFile <JungleRunPCSaveDataLevel[]>(inputFilePath);

            // Import the data
            BinarySerializableHelpers.WriteToFile(data, SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger());

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Converts to the format
        /// </summary>
        /// <returns>The task</returns>
        public override async Task ConvertToAsync()
        {
            var attr     = GameModeSelection.SelectedValue.GetAttribute <UbiArtGameModeInfoAttribute>();
            var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform);

            if (GameModeSelection.SelectedValue == UbiArtGameMode.RaymanFiestaRunPC)
            {
                await ConvertToAsync <FiestaRunLocalizationData>(settings, (filePath, format) =>
                {
                    // Read the data
                    return(DeserializeJSON <FiestaRunLocalizationData>(filePath));
                }, new FileFilterItem("*.json", "JSON").ToString(), new FileExtension(".loc"));
            }
            else
            {
                var fileExtension = new FileExtension(Equals(settings.StringEncoding, Encoding.UTF8) ? ".loc8" : ".loc");

                await ConvertToAsync <UbiArtLocalizationData>(settings, (filePath, format) =>
                {
                    // Read the data
                    return(DeserializeJSON <UbiArtLocalizationData>(filePath));
                }, new FileFilterItem("*.json", "JSON").ToString(), fileExtension);
            }
        }
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="settings">The settings when serializing the data</param>
 public UbiArtIPKArchiveExplorerDataManager(UbiArtSettings settings) : base(new UbiArtIPKArchiveConfigViewModel(settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode.WasCompressed))
 {
 }
 /// <summary>
 /// Deserializes the localization file
 /// </summary>
 /// <param name="file">The localization file</param>
 /// <returns>The data</returns>
 protected override UbiArtLocStringValuePair[] Deserialize(FileSystemPath file)
 {
     return(BinarySerializableHelpers.ReadFromFile <UbiArtLocalizationData>(file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).Strings);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Get the progression slot view model for the save data from the specified file
        /// </summary>
        /// <param name="filePath">The slot file path</param>
        /// <returns>The progression slot view model</returns>
        protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath filePath)
        {
            RL.Logger?.LogInformationSource($"Legends slot {filePath.Parent.Name} is being loaded...");

            // Make sure the file exists
            if (!filePath.FileExists)
            {
                RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found");

                return(null);
            }

            // Deserialize and return the data
            var saveData = BinarySerializableHelpers.ReadFromFile <LegendsPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanLegends, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).SaveData;

            RL.Logger?.LogInformationSource($"Slot has been deserialized");

            // Create the collection with items for each time trial level + general information
            var progressItems = new List <ProgressionInfoItemViewModel>();

            // Create the number format info to use
            var formatInfo = new NumberFormatInfo()
            {
                NumberGroupSeparator = " ",
                NumberDecimalDigits  = 0
            };

            // Get the total amount of freed teensies
            var teensies = saveData.Levels.Select(x => x.Value.Object.FreedPrisoners.Length).Sum() + saveData.LuckyTicketRewardList.Count(x => x.Type == 5);

            // Set general progress info
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Teensy, new LocalizedString(() => $"{teensies}/700")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Lum, new LocalizedString(() => $"{saveData.Score.LocalLumsCount.ToString("n", formatInfo)}")));

            // Set rank
            progressItems.Add(new ProgressionInfoItemViewModel(Enum.Parse(typeof(ProgressionIcons), $"RL_Rank{saveData.Profile.StatusIcon}").CastTo <ProgressionIcons>(), new LocalizedString(() => $"{saveData.Profile.StatusIcon}")));

            // Set cups
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Bronze, new LocalizedString(() => $"{saveData.Profile.BronzeMedals.ToString("n", formatInfo)}")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Silver, new LocalizedString(() => $"{saveData.Profile.SilverMedals.ToString("n", formatInfo)}")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Gold, new LocalizedString(() => $"{saveData.Profile.GoldMedals.ToString("n", formatInfo)}")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Diamond, new LocalizedString(() => $"{saveData.Profile.DiamondMedals.ToString("n", formatInfo)}")));

            RL.Logger?.LogInformationSource($"General progress info has been set");

            // Get the level IDs
            var lvlIds = GetLevelIDs;

            // Set invasion times
            progressItems.AddRange(saveData.Levels.
                                   Select(x => x.Value.Object).
                                   Where(x => x.BestTime > 0).
                                   Select(x => (lvlIds[x.Id.ID], x.BestTime)).
                                   Select(x => new ProgressionInfoItemViewModel(
                                              Enum.Parse(typeof(ProgressionIcons), $"RL_Inv_{x.Item1.Replace("-", "_")}").CastTo <ProgressionIcons>(),
                                              new LocalizedString(() => $"{x.Item1}: {x.BestTime:0.000}"),
                                              new LocalizedString(() => Resources.ResourceManager.GetString($"RL_LevelName_{x.Item1.Replace("-", "_")}")))).
                                   OrderBy(x => x.Content.Value));

            RL.Logger?.LogInformationSource($"Invasion progress info has been set");

            // Calculate the percentage
            var percentage = ((teensies / 700d * 100)).ToString("0.##");

            RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%");

            // Return the data with the collection
            return(new LegendsProgressionSlotViewModel(new LocalizedString(() => $"{saveData.Profile.Name} ({percentage}%)"), progressItems.ToArray(), filePath, this));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Gets the patch infos for each <see cref="Patch"/>
        /// </summary>
        /// <param name="ipkStream">The IPK file stream</param>
        /// <returns>The patch infos</returns>
        protected IEnumerable <PatchInfo> GetPatchInfos(Stream ipkStream)
        {
            // Deserialize the IPK file
            var ipk = BinarySerializableHelpers.ReadFromStream <UbiArtIpkData>(ipkStream, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanLegends, Platform.PC), RCPServices.App.GetBinarySerializerLogger());

            // Enumerate every patch
            foreach (var patchGroup in GetPatches.GroupBy(x => x.FileName))
            {
                // Get the file
                var file = ipk.Files.FindItem(x => x.Path.FileName == patchGroup.Key);

                // Make sure we found the file
                if (file == null)
                {
                    throw new Exception("Patch file not found");
                }

                // Make sure it's not compressed
                if (file.IsCompressed)
                {
                    throw new Exception("The configuration file is compressed and can not be edited");
                }

                // Get the offsets
                foreach (Patch patch in patchGroup)
                {
                    // Get the offset of the byte in the file to change
                    yield return(new PatchInfo(patch, (long)(ipk.BaseOffset + file.Offsets.First() + (uint)patch.FileOffset)));
                }
            }
        }
        /// <summary>
        /// Exports the save slot from the specified path
        /// </summary>
        /// <param name="outputFilePath">The output file path</param>
        /// <returns>The task</returns>
        protected override Task ExportSaveDataAsync(FileSystemPath outputFilePath)
        {
            // Get the serialized level data
            var data = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).Levels;

            // Export the data
            JsonHelpers.SerializeToFile(data, outputFilePath);

            return(Task.CompletedTask);
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="settings">The settings when serializing the data</param>
 public UbiArtIPKArchiveCreatorDataManager(UbiArtSettings settings) : base(new UbiArtIPKArchiveConfigViewModel(settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode.MatchesSetting))
 {
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Get the progression slot view model for the save data from the specified file
        /// </summary>
        /// <param name="fileName">The slot file name, relative to the save directory</param>
        /// <param name="slotNamegenerator">The generator for the name of the save slot</param>
        /// <returns>The progression slot view model</returns>
        protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath fileName, Func <string> slotNamegenerator)
        {
            RL.Logger?.LogInformationSource($"Jungle Run slot {fileName.Name} is being loaded...");

            // Get the file path
            var filePath = SaveDir + fileName;

            // Make sure the file exists
            if (!filePath.FileExists)
            {
                RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found");

                return(null);
            }

            // Deserialize and return the data
            var saveData = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger());

            RL.Logger?.LogInformationSource($"Slot has been deserialized");

            // Create the collection with items for each time trial level + general information
            var progressItems = new ProgressionInfoItemViewModel[(saveData.Levels.Length / 10) + 2];

            // Get data values
            int collectedLums  = 0;
            int availableLums  = 0;
            int collectedTeeth = 0;
            int availableTeeth = saveData.Levels.Length;

            RL.Logger?.LogTraceSource($"Levels are being enumerated...");

            // Enumerate each level
            for (int i = 0; i < saveData.Levels.Length; i++)
            {
                // Get the level data
                var levelData = saveData.Levels[i];

                // Check if the level is a normal level
                if ((i + 1) % 10 != 0)
                {
                    RL.Logger?.LogTraceSource($"Level index {i} is a normal level");

                    // Get the collected lums
                    collectedLums += levelData.LumsRecord;
                    availableLums += 100;

                    RL.Logger?.LogTraceSource($"{levelData.LumsRecord} Lums have been collected");

                    // Check if the level is 100% complete
                    if (levelData.LumsRecord >= 100)
                    {
                        collectedTeeth++;
                    }

                    continue;
                }

                RL.Logger?.LogTraceSource($"Level index {i} is a time trial level");

                // Make sure the level has been completed
                if (levelData.RecordTime == 0)
                {
                    RL.Logger?.LogTraceSource($"Level has not been completed");

                    continue;
                }

                RL.Logger?.LogTraceSource($"Level has been completed with the record time {levelData.RecordTime}");

                collectedTeeth++;

                // Get the level number, starting at 10
                var fullLevelNumber = (i + 11).ToString();

                // Get the world and level numbers
                var worldNum = fullLevelNumber[0].ToString();
                var lvlNum   = fullLevelNumber[1].ToString();

                // If the level is 0, correct the numbers to be level 10
                if (lvlNum == "0")
                {
                    worldNum = (Int32.Parse(worldNum) - 1).ToString();
                    lvlNum   = "10";
                }

                // Create the view model
                progressItems[((i + 1) / 10) - 1 + 2] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_Clock, new LocalizedString(() => $"{worldNum}-{lvlNum}: {new TimeSpan(0, 0, 0, 0, (int)levelData.RecordTime):mm\\:ss\\:fff}"));
            }

            // Set general progress info
            progressItems[0] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_Lum, new LocalizedString(() => $"{collectedLums}/{availableLums}"));
            progressItems[1] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_RedTooth, new LocalizedString(() => $"{collectedTeeth}/{availableTeeth}"));

            RL.Logger?.LogInformationSource($"General progress info has been set");

            // Calculate the percentage
            var percentage = ((collectedLums / (double)availableLums * 50) + (collectedTeeth / (double)availableTeeth * 50)).ToString("0.##");

            RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%");

            // Return the data with the collection
            return(new JungleRunProgressionSlotViewModel(new LocalizedString(() => $"{slotNamegenerator()} ({percentage}%)"), progressItems, filePath, this));
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Get the progression slot view model for the save data from the specified file
        /// </summary>
        /// <param name="filePath">The slot file path</param>
        /// <param name="slotNamegenerator">The generator for the name of the save slot</param>
        /// <returns>The progression slot view model</returns>
        protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath filePath, Func <string> slotNamegenerator)
        {
            RL.Logger?.LogInformationSource($"Origins slot {filePath.Name} is being loaded...");

            // Make sure the file exists
            if (!filePath.FileExists)
            {
                RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found");

                return(null);
            }

            // Deserialize and get the data
            var saveData = BinarySerializableHelpers.ReadFromFile <OriginsPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).SaveData;

            RL.Logger?.LogInformationSource($"Slot has been deserialized");

            // Get the level configuration
            var lvlConfig = JsonConvert.DeserializeObject <ROLevelConfig>(Files.RO_LevelConfig);

            int completed   = 0;
            int cageMaps    = 0;
            int lumAttack1  = 0;
            int lumAttack2  = 0;
            int lumAttack3  = 0;
            int timeAttack1 = 0;
            int timeAttack2 = 0;

            // Get number of levels where each mission has been completed
            foreach (var lvl in saveData.Levels)
            {
                // Get the configuration for the level
                var level   = lvlConfig.GetLevel(lvl.Key.ID);
                var mission = lvlConfig.GetMission(lvl.Key.ID);

                // Make sure it's a normal level, i.e. it has a medallion
                if (level == null || mission == null)
                {
                    continue;
                }

                // Check if the level has been completed
                if (lvl.Value.Object.LevelState == OriginsPCSaveData.SPOT_STATE.COMPLETED)
                {
                    completed++;
                }

                // Get the number of completed cage maps (between 0-2)
                cageMaps += lvl.Value.Object.CageMapPassedDoors.Length;

                // Get the best time attack score
                var timeAttack = lvl.Value.Object.BestTimeAttack;

                // Compare the time attack score with the targets
                if (timeAttack <= level.Time1)
                {
                    timeAttack1++;
                }
                if (timeAttack <= level.Time2)
                {
                    timeAttack2++;
                }

                // Get the best lum attack score
                var lumAttack = lvl.Value.Object.BestLumAttack;

                // Compare the lum attack score with the targets
                if (lumAttack >= mission.LumAttack1)
                {
                    lumAttack1++;
                }
                if (lumAttack >= mission.LumAttack2)
                {
                    lumAttack2++;
                }
                if (lumAttack >= mission.LumAttack3)
                {
                    lumAttack3++;
                }
            }

            // Create the collection with items for each time trial level + general information
            var progressItems = new List <ProgressionInfoItemViewModel>();

            // Get the number of Electoons
            var electoons =
                // Cages
                cageMaps +
                // Levels completed
                completed +
                // Lum attack 1
                lumAttack1 +
                // Lum attack 2
                lumAttack2 +
                // Time attack 1
                timeAttack1;
            var teeth = saveData.Levels.Select(x => x.Value.Object.ISDs.Select(y => y.Value.Object.TakenTooth.Length)).SelectMany(x => x).Sum();

            // Set general progress info
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Electoon, new LocalizedString(() => $"{electoons}/246")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_RedTooth, new LocalizedString(() => $"{teeth}/10")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Medal, new LocalizedString(() => $"{lumAttack3}/51")));
            progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Trophy, new LocalizedString(() => $"{timeAttack2}/31")));

            RL.Logger?.LogInformationSource($"General progress info has been set");

            // Calculate the percentage
            var percentage = ((electoons / 246d * 25) + (teeth / 10d * 25) + (lumAttack3 / 51d * 25) + (timeAttack2 / 31d * 25)).ToString("0.##");

            RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%");

            // Return the data with the collection
            return(new OriginsProgressionSlotViewModel(new LocalizedString(() => $"{slotNamegenerator()} ({percentage}%)"), progressItems.ToArray(), filePath, this));
        }
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="fileEntry">The file data</param>
 /// <param name="settings">The settings when serializing the data</param>
 /// <param name="baseOffset">The base offset to use when reading the files</param>
 public UbiArtIPKArchiveImageFileData(UbiArtIPKFileEntry fileEntry, UbiArtSettings settings, uint baseOffset) : base(fileEntry, settings, baseOffset)
 {
 }