public async UniTask ImportDESETA(GameSettings settings, bool edu) { // TODO: Not hard-code these? const int desAllfixCount = 9; const int etaAllfixCount = 5; int otherDesAllfixCount = edu ? 8 : 7; int otherEtaAllfixCount = edu ? 5 : 4; // Load in the JSON files to get our mappings await LevelEditorData.InitAsync(settings, true); using (var context = new Context(settings)) { GameSettings otherSettings; if (!edu) { // Find the first Rayman 1 version that the user has actually set up. var mode = EnumHelpers.GetValues <GameModeSelection>().Where(x => x.GetAttribute <GameModeAttribute>().EngineVersion == EngineVersion.R1_PC).First(x => Settings.GameDirectories.ContainsKey(x) && Directory.Exists(Settings.GameDirectories[x])); otherSettings = new GameSettings(mode, Settings.GameDirectories[mode], settings.World, settings.Level); } else { otherSettings = new GameSettings(GameModeSelection.RaymanEducationalPC, Settings.GameDirectories[GameModeSelection.RaymanEducationalPC], settings.World, settings.Level); } using (var otherContext = new Context(otherSettings)) { // Create manager for the other game, and load its files. R1_PCBaseManager otherGame = (R1_PCBaseManager)otherSettings.GetGameManager; if (edu) { otherContext.Settings.EduVolume = otherGame.GetLevels(otherContext.Settings).First().Name; } // Loop through the worlds. for (int w = 1; w < 7; w++) { context.Settings.World = otherContext.Settings.World = w; var wldPath = GetWorldFilePath(context.Settings); await LoadFilesAsync(context); await otherGame.LoadFilesAsync(otherContext); // Load our WLD file and the other game's. var wld = FileFactory.Read <R1_PC_WorldFile>(wldPath, context); var otherWld = FileFactory.Read <R1_PC_WorldFile>(otherGame.GetWorldFilePath(otherContext.Settings), otherContext); // Get the list of existing ETA and DES files so we know what's missing. var desNames = wld.DESFileNames.ToArray(); var etaNames = wld.ETAFileNames.ToArray(); // Use the tables to get mappings from the other game onto this one. var desMappings = new Dictionary <int, string>(); var etaMappings = new Dictionary <int, string>(); var r1wld = otherContext.Settings.R1_World; var desNameTable = otherGame.GetDESNameTable(otherContext); var etaNameTable = otherGame.GetETANameTable(otherContext); // Go through the other game's DES and ETA name tables, and see if any one // is missing from Designer. for (int iDes = 0; iDes < desNameTable.Length; iDes++) { var desName = desNameTable[iDes]; if ((desName == null) || (desName == "N/A")) { continue; } if (!desNames.Contains($"{desName}.DES")) { // The DES is specified in the JSON file, but doesn't exist in the WLD file. // Add it to the copy list. desMappings[iDes] = $"{desName}.DES"; Debug.Log($"Mapping DES {iDes} to {desName}"); } } for (int iEta = 0; iEta < etaNameTable.Length; iEta++) { var etaName = etaNameTable[iEta]; if ((etaName == null) || (etaName == "N/A")) { continue; } if (!etaNames.Contains($"{etaName}.ETA")) { // The ETA is specified in the JSON file, but doesn't exist in the WLD file. // Add it to the copy list. etaMappings[iEta] = $"{etaName}.ETA"; Debug.Log($"Mapping ETA {iEta} to {etaName}"); } } // Now that we've set up the mappings, carry out the copies! var newDesItems = wld.DesItems.ToList(); foreach (var mapping in desMappings) { Debug.Log($"Attempting to port DES {mapping.Key} -> {mapping.Value}"); newDesItems.Add(otherWld.DesItems[mapping.Key - otherDesAllfixCount - 1]); wld.DesItemCount = (ushort)newDesItems.Count; wld.DESFileNames[wld.DesItemCount + desAllfixCount - 1] = mapping.Value; } wld.DesItems = newDesItems.ToArray(); var newEtaItems = wld.Eta.ToList(); foreach (var mapping in etaMappings) { Debug.Log($"Attempting to port ETA {mapping.Key} -> {mapping.Value}"); newEtaItems.Add(otherWld.Eta[mapping.Key - otherEtaAllfixCount]); wld.ETAFileNames[newEtaItems.Count + etaAllfixCount - 1] = mapping.Value; } wld.Eta = newEtaItems.ToArray(); // Save the WLD FileFactory.Write <R1_PC_WorldFile>(wldPath, context); } } } // Beef up the memory allocation if necessary. await IncreaseMemAlloc(settings); }
public static async UniTask BatchRandomizeAsync() { try { // Get the settings var settings = Settings.GetGameSettings; // Init await LevelEditorData.InitAsync(settings); var manager = Settings.GetGameManager; // Get the flags var flag = Settings.RandomizerFlags; // Enumerate every world int totalLevels = manager.GetLevels(settings).First().Worlds.Sum(w => w.Maps.Length); int progress = 0; var worlds = manager.GetLevels(settings).First().Worlds; foreach (var world in worlds) { // Set the world settings.World = world.Index; // Enumerate every level foreach (var lvl in world.Maps) { var progressObj = new { world = world.Index, level = lvl, progress = (float)progress / totalLevels }; Debug.Log("progress:" + JsonConvert.SerializeObject(progressObj)); // Save the level bool saveISO = world == worlds.Last() && lvl == world.Maps.Last(); if (flag > 0 || saveISO) { // Set the level settings.Level = lvl; // Create the context using (var context = new Context(settings)) { // Load the files await manager.LoadFilesAsync(context); // Load the level var level = await manager.LoadAsync(context, true); // Randomize (only first map for now) string seed = $"{world.Index},{lvl},{Settings.RandomizerSeed}"; int seedHashCode = seed.GetHashCode(); Debug.Log($"seed = {seed} (seedHashCode = {seedHashCode})"); Randomizer.Randomize(level, world.Index, lvl, flag, seedHashCode, 0); context.Close(); if (manager is R1_PS1_Manager ps1Manager) { await ps1Manager.SaveLevelAsync(context, level, false); if (saveISO) { Debug.Log("Saving ISO"); ps1Manager.CreateISO(context); } } else { await manager.SaveLevelAsync(context, level); } } } progress++; } } Debug.Log("Randomizer Success"); } catch (Exception ex) { Debug.LogError(ex); } }
public async UniTask LoadLevelAsync(IGameManager manager, Context context) { // Create the context serializeContext = context; // Make sure all the necessary files are downloaded Controller.LoadState = Controller.State.LoadingFiles; await manager.LoadFilesAsync(serializeContext); await Controller.WaitIfNecessary(); using (serializeContext) { // Init editor data await LevelEditorData.InitAsync(context.Settings); await Controller.WaitIfNecessary(); // Load the level Controller.LoadState = Controller.State.Loading; LevelEditorData.Level = await manager.LoadAsync(serializeContext, true); LevelEditorData.ShowEventsForMaps = LevelEditorData.Level.Maps.Select(x => true).ToArray(); await Controller.WaitIfNecessary(); if (Controller.LoadState == Controller.State.Error) { return; } Controller.LoadState = Controller.State.Initializing; await Controller.WaitIfNecessary(); LevelEditorData.CurrentMap = LevelEditorData.Level.DefaultMap; LevelEditorData.CurrentCollisionMap = LevelEditorData.Level.DefaultCollisionMap; Controller.DetailedState = $"Initializing tile maps"; await Controller.WaitIfNecessary(); // Init tilemaps controllerTilemap.InitializeTilemaps(); Controller.DetailedState = $"Initializing events"; await Controller.WaitIfNecessary(); // Add events Objects = LevelEditorData.Level.EventData.Select(x => controllerEvents.AddEvent(x)).ToList(); if (LevelEditorData.Level.Rayman != null) { RaymanObject = controllerEvents.AddEvent(LevelEditorData.Level.Rayman); } // Init event things controllerEvents.InitializeEvents(); await Controller.WaitIfNecessary(); // Set up history History = new EditorHistory <Ray1MapEditorHistoryItem>(x => { // Set tiles foreach (var tileItem in x.ModifiedTiles) { controllerTilemap.SetTileAtPos(tileItem.XPos, tileItem.YPos, tileItem.Item); } }); if (Settings.ScreenshotEnumeration) { ConvertLevelToPNG(); } } }