public GeneralEventInfoData FindMatchingEventInfo(R1_EventData e) { byte[] compiledCmds; ushort[] labelOffsets; if (UsesLocalCommands) { var compiledData = e.Commands == null ? null : EventCommandCompiler.Compile(e.Commands, e.Commands.ToBytes(Context.Settings)); compiledCmds = compiledData?.Commands?.ToBytes(Context.Settings) ?? new byte[0]; labelOffsets = compiledData?.LabelOffsets ?? new ushort[0]; } else { compiledCmds = e.Commands?.ToBytes(Context.Settings) ?? new byte[0]; labelOffsets = e.LabelOffsets ?? new ushort[0]; } // Helper method for comparing the commands bool compareCommands(GeneralEventInfoData eventInfo) => eventInfo.LabelOffsets.SequenceEqual(labelOffsets) && eventInfo.Commands.SequenceEqual(compiledCmds); // Find a matching item var match = findMatch(EventMatchFlags.All) ?? findMatch(EventMatchFlags.All & ~EventMatchFlags.HitSprite & ~EventMatchFlags.Commands) ?? findMatch(EventMatchFlags.Type | EventMatchFlags.Etat | EventMatchFlags.SubEtat); GeneralEventInfoData findMatch(EventMatchFlags flags) { return(AvailableEvents.FindItem(x => (!flags.HasFlag(EventMatchFlags.Type) || x.Type == (ushort)e.Type) && (!flags.HasFlag(EventMatchFlags.Etat) || x.Etat == e.Etat) && (!flags.HasFlag(EventMatchFlags.SubEtat) || x.SubEtat == e.SubEtat) && (!flags.HasFlag(EventMatchFlags.OffsetBX) || x.OffsetBX == e.OffsetBX) && (!flags.HasFlag(EventMatchFlags.OffsetBY) || x.OffsetBY == e.OffsetBY) && (!flags.HasFlag(EventMatchFlags.OffsetHY) || x.OffsetHY == e.OffsetHY) && (!flags.HasFlag(EventMatchFlags.FollowSprite) || x.FollowSprite == e.FollowSprite) && (!flags.HasFlag(EventMatchFlags.HitPoints) || x.HitPoints == e.ActualHitPoints) && (!flags.HasFlag(EventMatchFlags.HitSprite) || x.HitSprite == e.HitSprite) && (!flags.HasFlag(EventMatchFlags.FollowEnabled) || x.FollowEnabled == e.GetFollowEnabled(Context.Settings)) && (!flags.HasFlag(EventMatchFlags.Commands) || compareCommands(x)))); } // Log if not found if (match == null && AvailableEvents.Any()) { Debug.LogWarning($"Matching event not found for event with type {e.Type}, etat {e.Etat} & subetat {e.SubEtat} in level {Settings.World}-{Settings.Level}"); } // Return the item return(match); }
public static async UniTask MapperToRDAsync(GameSettings inputSettings, GameSettings outputSettings) { using (var inputContext = new Context(inputSettings)) { using (var outputContext = new Context(outputSettings)) { // Create managers var mapperManager = new R1_Mapper_Manager(); var rdManager = new R1_Kit_Manager(); // Load files to context await mapperManager.LoadFilesAsync(inputContext); await rdManager.LoadFilesAsync(outputContext); // Load the mapper level var inputLev = (await mapperManager.LoadAsync(inputContext, false)); var inputMap = inputLev.Maps[0]; var inputObjManager = (Unity_ObjectManager_R1)inputLev.ObjManager; // Load the editor manager data for the output level var outData = await rdManager.LoadAsync(outputContext, true); var outputObjManager = (Unity_ObjectManager_R1)outData.ObjManager; // Load a dummy PC level as a base var outLev = FileFactory.Read <R1_PC_LevFile>(rdManager.GetLevelFilePath(outputSettings), outputContext); // TODO: Set background data // Set map data outLev.MapData.Width = inputMap.Width; outLev.MapData.Height = inputMap.Height; //outLev.MapData.ColorPalettes = new RGB666Color[][] //{ // FileFactory.Read<PCX>(mapperManager.GetPCXFilePath(inputSettings), inputContext).VGAPalette.Select(x => new RGB666Color(x.Red, x.Green, x.Blue)).ToArray() //}; // Set tiles while keeping track of the size changes var prevTileSize = outLev.MapData.Tiles.Length * 6; outLev.MapData.Tiles = inputMap.MapTiles.Select(x => x.Data).ToArray(); var newTileSize = outLev.MapData.Tiles.Length * 6; // Update pointers outLev.EventBlockPointer += newTileSize - prevTileSize; outLev.TextureBlockPointer += newTileSize - prevTileSize; // TODO: Set tilemap from .pcx file //outLev.TileTextureData = null; // Get the file tables var outputDesNames = FileFactory.Read <R1_PC_WorldFile>(rdManager.GetWorldFilePath(outputSettings), outputContext).DESFileNames; var outputEtaNames = FileFactory.Read <R1_PC_WorldFile>(rdManager.GetWorldFilePath(outputSettings), outputContext).ETAFileNames; // Set event data outLev.EventData.EventCount = (ushort)inputLev.EventData.Count; outLev.EventData.EventLinkingTable = inputObjManager.LinkTable; outLev.EventData.Events = inputLev.EventData.Cast <Unity_Object_R1>().Select(x => { var e = x.EventData; var newDesIndex = (uint)outputDesNames.FindItemIndex(y => y == inputObjManager.DES[x.DESIndex].Name); var newEtaIndex = (uint)outputEtaNames.FindItemIndex(y => y == inputObjManager.ETA[x.ETAIndex].Name); // Set DES and ETA indexes e.PC_ImageDescriptorsIndex = newDesIndex; e.PC_ImageBufferIndex = newDesIndex; e.PC_AnimationDescriptorsIndex = newDesIndex; e.PC_ETAIndex = newEtaIndex; // Set image and animation descriptor counts e.ImageDescriptorCount = (ushort)outputObjManager.DES[x.DESIndex].Data.Graphics.Sprites.Count; e.AnimDescriptorCount = (byte)outputObjManager.DES[x.DESIndex].Data.Graphics.Animations.Count; return(e); }).ToArray(); // Set event commands outLev.EventData.EventCommands = inputLev.EventData.Cast <Unity_Object_R1>().Select(x => { // Get the commands in the compiled format var cmds = EventCommandCompiler.Compile(x.EventData.Commands, x.EventData.Commands.ToBytes(inputSettings)); // Remove commands which only contain the invalid command if (cmds.Commands.Commands.Length == 1) { cmds = new EventCommandCompiler.CompiledEventCommandData(new R1_EventCommandCollection() { Commands = new R1_EventCommand[0] }, new ushort[0]); } // Create a command object return(new R1_PC_EventCommand { CommandLength = (ushort)cmds.Commands.Commands.Select(y => y.Length).Sum(), Commands = cmds.Commands, LabelOffsetCount = (ushort)cmds.LabelOffsets.Length, LabelOffsetTable = cmds.LabelOffsets }); }).ToArray(); // TODO: Get data from .ini file // Set profile define data outLev.ProfileDefine = new R1_PC_ProfileDefine { LevelName = "Test Export", LevelAuthor = "RayCarrot", LevelDescription = "This is a test export map", Power_Fist = true, Power_Hang = true, Power_Run = true, Power_Seed = false, Power_Helico = true, Power_SuperHelico = false }; // Write the changes to the file FileFactory.Write <R1_PC_LevFile>(rdManager.GetLevelFilePath(outputSettings), outputContext); } } }