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 override Unity_Object CreateObject(int index) { // Get the event var e = AvailableEvents[index]; // Get the commands and label offsets R1_EventCommandCollection cmds = null; ushort[] labelOffsets = null; // If local (non-compiled) commands are used, attempt to get them from the event info or decompile the compiled ones if (UsesLocalCommands) { cmds = EventCommandCompiler.Decompile(new EventCommandCompiler.CompiledEventCommandData(R1_EventCommandCollection.FromBytes(e.Commands, Context.Settings), e.LabelOffsets), e.Commands); } else if (e.Commands.Any()) { cmds = R1_EventCommandCollection.FromBytes(e.Commands, Context.Settings); labelOffsets = e.LabelOffsets.Any() ? e.LabelOffsets : null; } var eventData = new Unity_Object_R1(new R1_EventData() { Type = (R1_EventType)e.Type, Etat = e.Etat, SubEtat = e.SubEtat, OffsetBX = e.OffsetBX, OffsetBY = e.OffsetBY, OffsetHY = e.OffsetHY, FollowSprite = e.FollowSprite, DisplayPrio = 0, HitSprite = e.HitSprite, Commands = cmds, LabelOffsets = labelOffsets }, this, ETAIndex: ETA.FindItemIndex(x => x.Name == e.ETA)); eventData.EventData.SetFollowEnabled(Context.Settings, e.FollowEnabled); // We need to set the hit points after the type eventData.EventData.ActualHitPoints = e.HitPoints; // Set DES eventData.DESIndex = DES.FindItemIndex(x => x.Name == e.DES); return(eventData); }
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); } } }