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); }
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()); }
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); }