public Unity_Object_R2(R1_R2EventData eventData, Unity_ObjectManager_R2 objManager) { // Set properties EventData = eventData; ObjManager = objManager; TypeInfo = EventData.EventType.GetAttribute <ObjTypeInfoAttribute>(); // Set editor states EventData.InitialEtat = EventData.Etat; EventData.InitialSubEtat = EventData.SubEtat; EventData.InitialDisplayPrio = EventData.DisplayPrio; EventData.InitialXPosition = EventData.XPosition; EventData.InitialYPosition = EventData.YPosition; EventData.RuntimeCurrentAnimIndex = 0; EventData.RuntimeMapLayer = EventData.MapLayer; }
/// <summary> /// Gets a new event instance for Rayman /// </summary> public static R1_R2EventData GetRayman(R1_R2EventData rayPos, R1_R2AllfixFooter data) => new R1_R2EventData() { // Gets loaded at 0x80178DF0 during runtime ObjParamsPointer = data.RaymanBehaviorPointer, CollisionDataPointer = data.RaymanCollisionDataPointer, AnimGroupPointer = data.RaymanAnimGroupPointer, XPosition = (short)(rayPos != null ? (rayPos.XPosition + rayPos.CollisionData.OffsetBX - data.RaymanCollisionData.OffsetBX) : 100), YPosition = (short)(rayPos != null ? (rayPos.YPosition + rayPos.CollisionData.OffsetBY - data.RaymanCollisionData.OffsetBY) : 10), Etat = 0, // It's supposed to be Etat 2, SubEtat 2, but the ray pos state has a better looking speed SubEtat = 19, MapLayer = ObjMapLayer.Front, Unk2 = new byte[17], EventType = R1_R2EventType.Rayman, DisplayPrio = 7, Bytes_5B = new byte[10], Bytes_65 = new byte[3], Unk5 = new byte[2], CollisionData = data.RaymanCollisionData, AnimGroup = data.RaymanAnimGroup };
/// <summary> /// Loads the specified level for the editor /// </summary> /// <param name="context">The serialization context</param> /// <param name="loadTextures">Indicates if textures should be loaded</param> /// <returns>The level</returns> public override async UniTask <Unity_Level> LoadAsync(Context context, bool loadTextures) { await Controller.WaitIfNecessary(); Controller.DetailedState = $"Loading files"; uint baseAddress = 0x80018000; var fixDTAPath = FixDataPath; var fixGRPPath = FixGraphicsPath; var sprPLSPath = SpritePalettesPath; var levelDTAPath = GetLevelDataPath(context.Settings); var levelSPRPath = GetLevelImageDescriptorsPath(context.Settings); var levelGRPPath = GetLevelGraphicsPath(context.Settings); baseAddress += await LoadFile(context, fixDTAPath, baseAddress); baseAddress -= 94; // FIX.DTA header size Pointer fixDTAHeader = new Pointer(baseAddress, context.FilePointer(fixDTAPath).file); R1_R2AllfixFooter footer = null; context.Deserializer.DoAt(fixDTAHeader, () => footer = context.Deserializer.SerializeObject <R1_R2AllfixFooter>(null, name: "AllfixFooter")); await LoadFile(context, fixGRPPath, 0); await LoadFile(context, sprPLSPath, 0); baseAddress += await LoadFile(context, levelSPRPath, baseAddress); baseAddress += await LoadFile(context, levelDTAPath, baseAddress); await LoadFile(context, levelGRPPath, 0); // Load every map for (int i = 0; i < 4; i++) { await LoadFile(context, GetSubMapPalettePath(i), 0); await LoadFile(context, GetSubMapTilesetPath(i), 0); await LoadFile(context, GetSubMapPath(i), 0); } await Controller.WaitIfNecessary(); Controller.DetailedState = $"Loading level data"; // Read the level data var lvlData = FileFactory.Read <R1_R2LevDataFile>(levelDTAPath, context); // Read the map blocks var maps = Enumerable.Range(0, MapCount).Select(x => FileFactory.Read <MapData>(GetSubMapPath(x), context)).ToArray(); await Controller.WaitIfNecessary(); Controller.DetailedState = $"Loading sprite data"; var commonEvents = new List <Unity_Object>(); if (loadTextures) { // Get the v-ram FillVRAM(context, VRAMMode.Level); } // Create the global design list var lvlImgDescriptors = FileFactory.Read <ObjectArray <R1_ImageDescriptor> >(levelSPRPath, context, onPreSerialize: (s, a) => a.Length = s.CurrentLength / 0xC).Value; var imgDescriptors = lvlData.FixImageDescriptors.Concat(lvlImgDescriptors).ToArray(); // Get every sprite var globalDesigns = imgDescriptors.Select(img => GetSpriteTexture(context, null, img)).Select(tex => tex == null ? null : tex.CreateSprite()).ToArray(); // Get the events var events = lvlData.Events.Concat(lvlData.AlwaysEvents).ToArray(); Controller.DetailedState = $"Loading animations"; await Controller.WaitIfNecessary(); // Get the animation groups var r2AnimGroups = events.Select(x => x.AnimGroup).Append(footer.RaymanAnimGroup).Where(x => x != null).Distinct().ToArray(); Unity_ObjectManager_R2.AnimGroup[] animGroups = new Unity_ObjectManager_R2.AnimGroup[r2AnimGroups.Length]; for (int i = 0; i < animGroups.Length; i++) { animGroups[i] = await getGroupAsync(r2AnimGroups[i]); await Controller.WaitIfNecessary(); } async UniTask <Unity_ObjectManager_R2.AnimGroup> getGroupAsync(R1_R2EventAnimGroup animGroup) { await UniTask.CompletedTask; // Add DES and ETA return(new Unity_ObjectManager_R2.AnimGroup( pointer: animGroup?.Offset, eta: animGroup?.ETA.EventStates ?? new R1_EventState[0][], animations: animGroup?.AnimationDecriptors?.Select(x => x.ToCommonAnimation()).ToArray(), filePath: animGroup?.AnimationDescriptorsPointer?.file.filePath)); } var objManager = new Unity_ObjectManager_R2( context: context, linkTable: lvlData.EventLinkTable, animGroups: animGroups, sprites: globalDesigns, imageDescriptors: imgDescriptors, levData: lvlData); Controller.DetailedState = $"Loading events"; await Controller.WaitIfNecessary(); // Add every event foreach (var e in events) { // Add the event commonEvents.Add(new Unity_Object_R2(e, objManager) { IsAlwaysEvent = lvlData.AlwaysEvents.Contains(e) }); } await Controller.WaitIfNecessary(); Controller.DetailedState = $"Loading tiles"; var levelMaps = maps.Select((x, i) => new Unity_Map() { Type = Unity_Map.MapType.Graphics | Unity_Map.MapType.Collision, Layer = i < 3 ? Unity_Map.MapLayer.Back : Unity_Map.MapLayer.Middle, // Set the dimensions Width = x.Width, Height = x.Height, // Create the tile array TileSet = new Unity_TileSet[1], TileSetWidth = TileSetWidth }).ToArray(); // Convert levelData to common level format Unity_Level level = new Unity_Level( maps: levelMaps, objManager: objManager, eventData: commonEvents, rayman: new Unity_Object_R2(R1_R2EventData.GetRayman(events.FirstOrDefault(x => x.EventType == R1_R2EventType.RaymanPosition), footer), objManager), getCollisionTypeNameFunc: x => ((R2_TileCollisionType)x).ToString(), getCollisionTypeGraphicFunc: x => ((R2_TileCollisionType)x).GetCollisionTypeGraphic()); await Controller.WaitIfNecessary(); // Load maps for (int i = 0; i < MapCount; i++) { // Get the tile set Unity_TileSet tileSet = GetTileSet(context, i); level.Maps[i].TileSet[0] = tileSet; // Set the tiles level.Maps[i].MapTiles = maps[i].Tiles.Select(x => new Unity_Tile(x)).ToArray(); } // Return the level return(level); }