Beispiel #1
0
        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;
        }
Beispiel #2
0
 /// <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);
        }