예제 #1
0
        public static byte[] GetBytes(TileGroup obj, bool withTiles = false)
        {
            var data = new byte[4];

            BitConverter.GetBytes(obj.Unknown).CopyTo(data, 0);

            if (withTiles && (obj.LandTiles != null || obj.StaticTiles != null))
            {
                if (obj.LandTiles != null)
                {
                    foreach (var landTile in obj.LandTiles.OrderBy(kvPair => kvPair.Key))
                    {
                        var landTileData = LandTiledata.GetBytes(landTile.Value);
                        Array.Resize(ref data, data.Length + landTileData.Length);
                        landTileData.CopyTo(data, data.Length - landTileData.Length);
                    }
                }
                else if (obj.StaticTiles != null)
                {
                    foreach (var staticTile in obj.StaticTiles.OrderBy(kvPair => kvPair.Key))
                    {
                        var staticTileData = StaticTiledata.GetBytes(staticTile.Value);
                        Array.Resize(ref data, data.Length + staticTileData.Length);
                        staticTileData.CopyTo(data, data.Length - staticTileData.Length);
                    }
                }
            }
            return(data);
        }
예제 #2
0
        public static void Save(string filename, Dictionary <string, TileGroup> landTileGroupsDict, Dictionary <string, TileGroup> staticTileGroupsDict)
        {
            var landTileGroups   = GetList(landTileGroupsDict);
            var staticTileGroups = GetList(staticTileGroupsDict);
            var landTiles        = GetList(landTileGroups
                                           .SelectMany(landTileGroup => landTileGroup.LandTiles)
                                           .ToDictionary(kvPair => kvPair.Key, kvPair => kvPair.Value));
            var staticTiles = GetList(staticTileGroups
                                      .SelectMany(staticTileGroup => staticTileGroup.StaticTiles)
                                      .ToDictionary(kvPair => kvPair.Key, kvPair => kvPair.Value));

            if (landTiles.Count() != 512 * 32)
            {
                throw new ArgumentException("There must be exactly 512 * 32 land tiles.", nameof(landTiles));
            }
            if (staticTiles.Count() % 32 != 0)
            {
                throw new ArgumentException("Number of static tiles must be divisible by 32.", nameof(staticTiles));
            }

            var data = new List <byte>();

            foreach (var landTileGroup in landTileGroups.OrderBy(group => group.ID))
            {
                if (landTileGroup.LandTiles.Count != 32)
                {
                    throw new ArgumentException($"There are not 32 items{landTileGroup.LandTiles.Count} in land tile group {landTileGroup.HexID}");
                }
                data.AddRange(TileGroup.GetBytes(landTileGroup, true));
            }

            foreach (var staticTileGroup in staticTileGroups.OrderBy(group => group.ID))
            {
                if (staticTileGroup.StaticTiles.Count != 32)
                {
                    throw new ArgumentException($"There are not 32 items{staticTileGroup.StaticTiles.Count} in static tile group {staticTileGroup.HexID}");
                }
                data.AddRange(TileGroup.GetBytes(staticTileGroup, true));
            }

            File.WriteAllBytes(filename, data.ToArray());
        }
예제 #3
0
        public List <TileGroup> Load <T>(Action <int, int> progressCallback = null)
        {
            if (data == null)
            {
                throw new NullReferenceException("Data buffer is empty.");
            }

            var tileType = typeof(T);

            var blockSize     = 0;
            var startPosition = 0;
            var tiledataSize  = 0;
            var tileSize      = 0;

            if (tileType == typeof(LandTiledata))
            {
                blockSize    = landBlockSize;
                tileSize     = landTileSize;
                tiledataSize = landBlockCount * landBlockSize;
            }
            else if (tileType == typeof(StaticTiledata))
            {
                blockSize     = staticBlockSize;
                startPosition = landBlockCount * landBlockSize;
                tileSize      = staticTileSize;
                tiledataSize  = data.Length - (landBlockCount * landBlockSize);
            }
            else
            {
                throw new ArgumentException($"Only {nameof(LandTiledata)} or {nameof(StaticTiledata)} is acceptable.");
            }

            var groupTileList = new List <TileGroup>();

            try
            {
                var tiledata = data.GetSubArray(startPosition, tiledataSize);

                var progressTracking = 0;
                var progressFull     = (tiledata.Length / blockSize);
                var progressFraction = progressFull / 100;
                for (int block = 0; block < tiledata.Length / blockSize; block++)
                {
                    var tileGroup = TileGroup.Load(block, tiledata.GetSubArray(block * blockSize, 4));
                    var tileBlock = tiledata.GetSubArray(block * blockSize + 4, blockSize - 4);

                    var tileList       = new List <T>();
                    var landTileList   = new List <LandTiledata>();
                    var staticTileList = new List <StaticTiledata>();

                    for (int tileIndex = 0; tileIndex < 32; tileIndex++)
                    {
                        var tile       = tileBlock.GetSubArray(tileIndex * tileSize, tileSize);
                        var loadedTile = typeof(T).GetMethod("Load").Invoke(null, new object[] { block * 32 + tileIndex, tile });
                        if (tileType == typeof(LandTiledata))
                        {
                            landTileList.Add((LandTiledata)loadedTile);
                        }
                        else if (tileType == typeof(StaticTiledata))
                        {
                            staticTileList.Add((StaticTiledata)loadedTile);
                        }
                    }

                    if (tileType == typeof(LandTiledata))
                    {
                        tileGroup.LandTiles = GetDict(landTileList);
                    }
                    else if (tileType == typeof(StaticTiledata))
                    {
                        tileGroup.StaticTiles = GetDict(staticTileList);
                    }
                    groupTileList.Add(tileGroup);

                    progressTracking++;
                    if (progressTracking % progressFraction == 0)
                    {
                        progressCallback?.DynamicInvoke(progressTracking, progressFull);
                    }
                }
                progressCallback?.DynamicInvoke(progressFull, progressFull);
            }
            catch (Exception exception)
            {
                throw new Exception("MUL file corrupted", exception);
            }

            return(groupTileList);
        }