예제 #1
0
        public Control Show(Stream stream, string fileName)
        {
            m_fileName = fileName;
            m_mips.Clear();
            try
            {
                using (var blp = new BlpFile(stream))
                {
                    for (int i = 0; i < blp.MipMapCount; ++i)
                    {
                        var bmp = blp.GetBitmap(i);
                        if (bmp.Width > 0 && bmp.Height > 0)
                        {
                            m_mips.Add(bmp);
                        }
                    }
                }
            }
            catch// (System.Exception ex)
            {
                //MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            cbMipIndex.Items.Clear();
            cbMipIndex.Items.AddRange(Enumerable.Range(0, m_mips.Count).Select(m => m.ToString()).ToArray());
            if (cbMipIndex.Items.Count > 0)
            {
                cbMipIndex.SelectedIndex = 0;
            }
            return(this);
        }
예제 #2
0
 public void LoadBLP(uint fileDataID)
 {
     using (var blp = new BlpFile(CASC.OpenFile(fileDataID)))
     {
         bmp = blp.GetBitmap(0);
     }
 }
예제 #3
0
 public void LoadBLP(string filename)
 {
     using (var blp = new BlpFile(CASC.OpenFile(filename)))
     {
         bmp = blp.GetBitmap(0);
     }
 }
예제 #4
0
        public static int LoadTexture(uint filedataid, CacheStorage cache)
        {
            GL.ActiveTexture(TextureUnit.Texture0);

            if (cache.materials.ContainsKey(filedataid))
            {
                return(cache.materials[filedataid]);
            }

            int textureId = GL.GenTexture();

            using (var blp = new BlpFile(CASC.OpenFile(filedataid)))
            {
                var bmp = blp.GetBitmap(0);

                if (bmp == null)
                {
                    throw new Exception("BMP is null!");
                }

                GL.BindTexture(TextureTarget.Texture2D, textureId);
                cache.materials.Add(filedataid, textureId);
                var bmp_data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                bmp.UnlockBits(bmp_data);
            }

            return(textureId);
        }
예제 #5
0
 public void LoadBLP(Stream file)
 {
     using (var blp = new BlpFile(file))
     {
         bmp = blp.GetBitmap(0);
     }
 }
예제 #6
0
 public void LoadBLP(Stream filename)
 {
     var blp = new BlpFile(filename);
     {
         bmp = blp.GetBitmap(0);
     }
 }
예제 #7
0
        public override void Work()
        {
            bool success = false;

            try
            {
                foreach (string path in paths)
                {
                    string newFile = Path.Combine(dest, Path.GetFileNameWithoutExtension(path) + ".png");
                    Log.Write("Exporting {0} -> {1}", path, newFile);

                    using (BlpFile blp = new BlpFile(File.OpenRead(path)))
                    {
                        Bitmap bmp = blp.GetBitmap(0);
                        bmp.Save(newFile, ImageFormat.Png);
                        bmp.Dispose();
                    }
                }
                success = true;
            }
            catch (Exception e)
            {
                // We have failed, the elders will be disappointed.
                Log.Write("BLP to PNG export failed: {0}.", e.Message);
            }

            EventManager.Trigger_ExportBLPtoPNGComplete(success);
        }
예제 #8
0
        private void OpenClick(object sender, EventArgs e)
        {
            try
            {
                var dlg = openFileDialog.ShowDialog();
                if (dlg != DialogResult.OK)
                {
                    return;
                }

                var file = openFileDialog.OpenFile();

                using (var blp = new BlpFile(file))
                {
                    bmp = blp.GetBitmap(0);
                }

                var graphics = panel1.CreateGraphics();
                graphics.Clear(panel1.BackColor);
                graphics.DrawImage(bmp, 0, 0);

                button3.Enabled = true;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("The 'example.blp' was not found!");
            }
        }
예제 #9
0
        static void Draw(dynamic map, WDT.WDTFileDataId chunk, ref NetVips.Image canvas, int positionX, int positionY)
        {
            Stream chunkStream = null;

            try
            {
                var casc = new CASC();
                chunkStream = casc.File(BuildConfig, chunk.fileDataId);
            }
            catch
            {
                Console.WriteLine($"Failed to download chunk {chunk.x}_{chunk.y} for map {map.MapName_lang} ({map.ID})");
                return;
            }

            var blpStream = new MemoryStream();
            var blpFile   = new BlpFile(chunkStream);

            var bitmap = blpFile.GetBitmap(0);

            bitmap.Save(blpStream, System.Drawing.Imaging.ImageFormat.Png);

            var image = NetVips.Image.NewFromBuffer(blpStream.ToArray(), access: Enums.Access.Sequential);

            canvas = canvas.Insert(image, positionX * bitmap.Width, positionY * bitmap.Height, true);

            blpStream.Dispose();
            blpFile.Dispose();
            bitmap.Dispose();
            image.Dispose();;
        }
예제 #10
0
        public void DoPreview(string selectedFilePath)
        {
            //  Load the icons.
            try
            {
                Logging.Log("Displaying preview 1");
                using (var stream = File.OpenRead(selectedFilePath))
                    using (var blpFile = new BlpFile(stream))
                    {
                        Logging.Log("Displaying preview 2");
                        OriginalImage     = blpFile.GetBitmap(0);
                        pictureBox1.Image = OriginalImage;
                        label1.Text       = string.Format("Size: {0}x{1} Compression: {2}", OriginalImage.Width, OriginalImage.Height, blpFile.Compression);
                        Logging.Log("Displaying preview 3");
                    }

                /*
                 * using (var image = Blp2.FromFile(selectedFilePath))
                 * {
                 *  Logging.Log("Displaying preview 2");
                 *  OriginalImage = (Bitmap)image;
                 *  pictureBox1.Image = OriginalImage;
                 *  label1.Text = string.Format("Size: {0}x{1} Compression: {2}", OriginalImage.Width, OriginalImage.Height, image.Format);
                 *  Logging.Log("Displaying preview 3");
                 * }*/
            }
            catch (Exception ex)
            {
                //  Maybe we could show something to the user in the preview
                //  window, but for now we'll just ignore any exceptions.
                label1.Text = "Error: " + ex.Message;
                Logging.Error(ex.Message);
            }
        }
예제 #11
0
        public void TestGetBlpBitmap(string inputImagePath, string expectedImagePath, int mipMapLevel)
        {
            using (var fileStream = File.OpenRead(inputImagePath))
            {
                var expectedImage = new Bitmap(expectedImagePath);
                var blpFile       = new BlpFile(fileStream);
                var actualImage   = blpFile.GetBitmap(mipMapLevel);

                Assert.AreEqual(expectedImage.Width, actualImage.Width);
                Assert.AreEqual(expectedImage.Height, actualImage.Height);

                for (var y = 0; y < expectedImage.Height; y++)
                {
                    for (var x = 0; x < expectedImage.Width; x++)
                    {
                        // Allow pixel values to be slightly different, since some testcases were decoded with WPF (BitmapSource), not SkiaSharp.
                        const int delta = 1;

                        var expectedPixel = expectedImage.GetPixel(x, y);
                        var actualPixel   = actualImage.GetPixel(x, y);

                        var message = $"Expected:<{expectedPixel}>. Actual:<{actualPixel}>";

                        Assert.IsTrue(Math.Abs(expectedPixel.A - actualPixel.A) <= delta, message);
                        Assert.IsTrue(Math.Abs(expectedPixel.R - actualPixel.R) <= delta, message);
                        Assert.IsTrue(Math.Abs(expectedPixel.G - actualPixel.G) <= delta, message);
                        Assert.IsTrue(Math.Abs(expectedPixel.B - actualPixel.B) <= delta, message);
                    }
                }

                expectedImage.Dispose();
                blpFile.Dispose();
            }
        }
예제 #12
0
        private void PreviewBlp(string fullName)
        {
            var stream = cascHandler.OpenFile(fullName, LocaleFlags.All);
            var blp    = new BlpFile(stream);
            var bitmap = blp.GetBitmap(0);
            var form   = new ImagePreviewForm(bitmap);

            form.Show();
        }
예제 #13
0
 private void PreviewBlp(CASCFile file)
 {
     using (var stream = _casc.OpenFile(file.Hash))
     {
         var blp    = new BlpFile(stream);
         var bitmap = blp.GetBitmap(0);
         var form   = new ImagePreviewForm(bitmap);
         form.Show();
     }
 }
예제 #14
0
 public void LoadBLP(string filename)
 {
     using (FileStream reader = File.OpenRead(filename))
     {
         var blp = new BlpFile(reader);
         {
             bmp = blp.GetBitmap(0);
         }
         reader.Close();
     }
 }
예제 #15
0
        private static void ExportExtraMaterials(uint tex, WoWFormatLib.Structs.WMO.WMO wmo, List <Structs.Material> mats, int matIdx, string path)
        {
            Stream ms = null;

            if (CASC.FileExists(tex))
            {
                var mat = new Structs.Material();
                if (wmo.textures == null)
                {
                    if (Listfile.TryGetFilename(tex, out var textureFilename))
                    {
                        mat.filename = Path.GetFileNameWithoutExtension(textureFilename).Replace(" ", "");
                    }
                    else
                    {
                        mat.filename = tex.ToString();
                    }

                    ms = CASC.OpenFile(tex);
                }
                else
                {
                    for (var ti = 0; ti < wmo.textures.Count(); ti++)
                    {
                        if (wmo.textures[ti].startOffset == tex)
                        {
                            mat.filename = Path.GetFileNameWithoutExtension(wmo.textures[ti].filename).Replace(" ", "");
                            ms           = CASC.OpenFile(wmo.textures[ti].filename);
                        }
                    }
                }

                if (ms == null)
                {
                    return; // Can this even happen?
                }
                string saveLocation = Path.Combine(path, mat.filename + ".png");
                if (!File.Exists(saveLocation))
                {
                    try
                    {
                        using (BlpFile blp = new BlpFile(ms))
                            blp.GetBitmap(0).Save(saveLocation);
                    }
                    catch (Exception e)
                    {
                        CASCLib.Logger.WriteLine("Exception while saving BLP " + mat.filename + ": " + e.Message);
                    }
                }

                mats.Add(mat);
            }
        }
예제 #16
0
        protected override Icon GetIcon(bool smallIcon, uint iconSize)
        {
            if (!File.Exists(SelectedItemPath))
            {
                return(new Icon(SystemIcons.Exclamation, new Size((int)iconSize, (int)iconSize)));
            }

            using (var stream = File.OpenRead(SelectedItemPath))
                using (var blpFile = new BlpFile(stream))
                {
                    using (var bitmap = blpFile.GetBitmap(0))
                    {
                        return(Icon.FromHandle(bitmap.GetHicon()));
                    }
                }
        }
예제 #17
0
        private void displayImage(string file)
        {
            currentImage = null;
            UI_PreviewStatus.Hide();

            using (var blp = new BlpFile(File.OpenRead(file)))
                currentImage = blp.GetBitmap(0);

            Graphics gfx = UI_ImagePreview.CreateGraphics();

            gfx.Clear(UI_ImagePreview.BackColor);
            gfx.DrawImage(currentImage, 0, 0);
            UI_ExportButton.Show();

            currentImageName = file;
        }
예제 #18
0
 private void RedrawImage()
 {
     image = new Bitmap(canvasSize, canvasSize);
     using (Graphics g = Graphics.FromImage(image))
     {
         foreach (SubTile tile in tiles)
         {
             using (BlpFile blp = new BlpFile(File.OpenRead(tile.File)))
             {
                 g.DrawImage(
                     blp.GetBitmap(0),
                     new Rectangle(tile.DrawX, tile.DrawY, tileSize, tileSize),
                     new Rectangle(0, 0, tileSize, tileSize),
                     GraphicsUnit.Pixel
                     );
             }
         }
     }
 }
예제 #19
0
        public void LoadBLP(string filename)
        {
            if (!CASC.FileExists(filename))
            {
                new WoWFormatLib.Utils.MissingFile(filename);

                // @TODO Quick fix to get texture working when it doesn't exist. Happened because Blizzard accidentally referenced a texture on their shares instead of in files.
                using (var blp = new BlpFile(CASC.OpenFile(@"World\Expansion05\Doodads\IronHorde\Ember_Offset_Streak.blp")))
                {
                    bmp = blp.GetBitmap(0);
                }
            }
            else
            {
                using (var blp = new BlpFile(CASC.OpenFile(filename)))
                {
                    bmp = blp.GetBitmap(0);
                }
            }
        }
예제 #20
0
        public void addTexture(int extID, string file)
        {
            int width  = 0;
            int height = 0;

            byte[] data = null;

            fileMapping.Add(extID, file);

            using (BlpFile raw = new BlpFile(File.OpenRead(file)))
            {
                Bitmap bitmap = raw.GetBitmap(0);
                width  = bitmap.Width;
                height = bitmap.Height;

                int length  = width * height * 4;
                var rawData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                data = new byte[length];

                Marshal.Copy(rawData.Scan0, data, 0, length);
                bitmap.UnlockBits(rawData);
                bitmap.Dispose();
            }

            uint[] intID = new uint[1];
            gl.GenTextures(1, intID);

            gl.BindTexture(OpenGL.GL_TEXTURE_2D, intID[0]);
            gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA, width, height, 0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, data);

            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR_MIPMAP_LINEAR);

            mapping.Add(extID, intID);
            gl.GenerateMipmapEXT(OpenGL.GL_TEXTURE_2D);

            Log.Write("TextureManager: {0} assigned to GL with @ {1}", file, intID[0]);
        }
예제 #21
0
        protected override Document OnLoad(Stream input)
        {
            BlpFile b = new BlpFile(input);

            return(Document.FromImage(b.GetBitmap(0)));
        }
예제 #22
0
        public override void Work()
        {
            MapCanvasTile[,] tiles = canvas.Images;
            int rowCount = tiles.GetLength(1);
            int colCount = tiles.GetLength(0);

            ImageInfo info   = new ImageInfo((colCount * canvas.MaxTiles) * 256, (rowCount * canvas.MaxTiles) * 256, 8, false);
            PngWriter writer = new PngWriter(File.OpenWrite(fileName), info);

            int lineOfs    = 0;
            int tileLines  = 256 * canvas.MaxTiles;
            int canvasCols = (colCount * canvas.MaxTiles) * 256;

            for (int tileY = 0; tileY < rowCount; tileY++)
            {
                Color[,] rows = new Color[tileLines, canvasCols];
                for (int tileX = 0; tileX < colCount; tileX++)
                {
                    List <MapCanvasTile.SubTile> subTiles = tiles[tileX, tileY].tiles;
                    subTiles.Sort((a, b) => a.CompareTo(b));

                    for (int subTileY = 0; subTileY < canvas.MaxTiles; subTileY++)
                    {
                        for (int subTileX = 0; subTileX < canvas.MaxTiles; subTileX++)
                        {
                            int subTileIndex = (subTileX * canvas.MaxTiles) + subTileY;

                            if (subTileIndex < subTiles.Count)
                            {
                                using (BlpFile blp = new BlpFile(File.OpenRead(subTiles[subTileIndex].File)))
                                    using (Bitmap bmp = blp.GetBitmap(0))
                                    {
                                        for (int pY = 0; pY < 256; pY++)
                                        {
                                            for (int pX = 0; pX < 256; pX++)
                                            {
                                                rows[pY + (subTileY * 256), pX + (subTileX * 256) + (tileX * (256 * canvas.MaxTiles))] = bmp.GetPixel(pX, pY);
                                            }
                                        }
                                    }
                            }
                        }
                    }
                }

                for (int iLine = 0; iLine < tileLines; iLine++)
                {
                    byte[] compRow = new byte[canvasCols * 3];
                    for (int iCol = 0; iCol < canvasCols; iCol++)
                    {
                        Color color = rows[iLine, iCol];
                        int   ofs   = 3 * iCol;

                        compRow[ofs]     = color.R;
                        compRow[ofs + 1] = color.G;
                        compRow[ofs + 2] = color.B;
                    }

                    writer.WriteRowByte(compRow, lineOfs);
                    lineOfs++;
                }
            }

            writer.End();
            EventManager.Trigger_MapExportDone2D();
        }
예제 #23
0
        private static void Main(string[] args)
        {
            var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("settings.json", true, true).Build();

            var saveExplored   = bool.Parse(config["saveExploredMaps"]);
            var saveUnexplored = bool.Parse(config["saveUnexploredMaps"]);
            var saveLayers     = bool.Parse(config["saveMapLayers"]);

            if (saveExplored && !Directory.Exists("explored"))
            {
                Directory.CreateDirectory("explored");
            }

            if (saveUnexplored && !Directory.Exists("unexplored"))
            {
                Directory.CreateDirectory("unexplored");
            }

            if (saveLayers && !Directory.Exists("layers"))
            {
                Directory.CreateDirectory("layers");
            }

            var locale = CASCLib.LocaleFlags.enUS;

            if (config["locale"] != string.Empty)
            {
                switch (config["locale"])
                {
                case "deDE":
                    locale = CASCLib.LocaleFlags.deDE;
                    break;

                case "enUS":
                    locale = CASCLib.LocaleFlags.enUS;
                    break;

                case "ruRU":
                    locale = CASCLib.LocaleFlags.ruRU;
                    break;

                case "zhCN":
                    locale = CASCLib.LocaleFlags.zhCN;
                    break;

                case "zhTW":
                    locale = CASCLib.LocaleFlags.zhTW;
                    break;
                }
            }

            if (config["installDir"] != string.Empty && Directory.Exists(config["installDir"]))
            {
                CASC.InitCasc(null, config["installDir"], config["program"], locale);
            }
            else
            {
                CASC.InitCasc(null, null, config["program"], locale);
            }

            using (var UIMapStream = CASC.OpenFile("DBFilesClient\\UIMap.db2"))
                using (var UIMapXArtStream = CASC.OpenFile("DBFilesClient\\UIMapXMapArt.db2"))
                    using (var UIMapArtTileStream = CASC.OpenFile("DBFilesClient\\UIMapArtTile.db2"))
                        using (var WorldMapOverlayStream = CASC.OpenFile("DBFilesClient\\WorldMapOverlay.db2"))
                            using (var WorldMapOverlayTileStream = CASC.OpenFile("DBFilesClient\\WorldMapOverlayTile.db2"))
                            {
                                if (!Directory.Exists("dbcs"))
                                {
                                    Directory.CreateDirectory("dbcs");
                                }

                                var uimapfs = File.Create("dbcs/UIMap.db2");
                                UIMapStream.CopyTo(uimapfs);
                                uimapfs.Close();

                                var uimapxartfs = File.Create("dbcs/UIMapXMapArt.db2");
                                UIMapXArtStream.CopyTo(uimapxartfs);
                                uimapxartfs.Close();

                                var uimapatfs = File.Create("dbcs/UIMapArtTile.db2");
                                UIMapArtTileStream.CopyTo(uimapatfs);
                                uimapatfs.Close();

                                var wmofs = File.Create("dbcs/WorldMapOverlay.db2");
                                WorldMapOverlayStream.CopyTo(wmofs);
                                wmofs.Close();

                                var wmotfs = File.Create("dbcs/WorldMapOverlayTile.db2");
                                WorldMapOverlayTileStream.CopyTo(wmotfs);
                                wmotfs.Close();
                            }

            var UIMap               = DBCManager.LoadDBC("UIMap", CASC.BuildName);
            var UIMapXArt           = DBCManager.LoadDBC("UIMapXMapArt", CASC.BuildName);
            var UIMapArtTile        = DBCManager.LoadDBC("UIMapArtTile", CASC.BuildName);
            var WorldMapOverlay     = DBCManager.LoadDBC("WorldMapOverlay", CASC.BuildName);
            var WorldMapOverlayTile = DBCManager.LoadDBC("WorldMapOverlayTile", CASC.BuildName);

            Console.WriteLine(); // new line after wdc2 debug output

            foreach (dynamic mapRow in UIMap)
            {
                var mapName = mapRow.Value.Name_lang;

                Console.WriteLine(mapRow.Key + " = " + mapName);

                foreach (dynamic mxaRow in UIMapXArt)
                {
                    var uiMapArtID = mxaRow.Value.UiMapArtID;
                    var uiMapID    = mxaRow.Value.UiMapID;

                    if (mxaRow.Value.PhaseID != 0)
                    {
                        continue; // Skip phase stuff for now
                    }
                    if (uiMapID == mapRow.Key)
                    {
                        var maxRows  = uint.MinValue;
                        var maxCols  = uint.MinValue;
                        var tileDict = new Dictionary <string, int>();

                        foreach (dynamic matRow in UIMapArtTile)
                        {
                            var matUiMapArtID = matRow.Value.UiMapArtID;
                            if (matUiMapArtID == uiMapArtID)
                            {
                                var fdid       = matRow.Value.FileDataID;
                                var rowIndex   = matRow.Value.RowIndex;
                                var colIndex   = matRow.Value.ColIndex;
                                var layerIndex = matRow.Value.LayerIndex;

                                // Skip other layers for now
                                if (layerIndex != 0)
                                {
                                    continue;
                                }

                                if (rowIndex > maxRows)
                                {
                                    maxRows = rowIndex;
                                }

                                if (colIndex > maxCols)
                                {
                                    maxCols = colIndex;
                                }

                                tileDict.Add(rowIndex + "," + colIndex, fdid);
                            }
                        }

                        var res_x = (maxRows + 1) * 256;
                        var res_y = (maxCols + 1) * 256;

                        var bmp = new Bitmap((int)res_y, (int)res_x);

                        var g = Graphics.FromImage(bmp);

                        for (var cur_x = 0; cur_x < maxRows + 1; cur_x++)
                        {
                            for (var cur_y = 0; cur_y < maxCols + 1; cur_y++)
                            {
                                var fdid = tileDict[cur_x + "," + cur_y];

                                if (CASC.FileExists((uint)fdid))
                                {
                                    using (var stream = CASC.OpenFile((uint)fdid))
                                    {
                                        try
                                        {
                                            var blp = new BlpFile(stream);
                                            g.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                        }
                                        catch (Exception e)
                                        {
                                            Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                        }
                                    }
                                }
                            }
                        }

                        if (saveUnexplored)
                        {
                            bmp.Save("unexplored/ " + CleanFileName(mapRow.Key + " - " + mapName + ".png"));
                        }

                        if (!saveLayers && !saveExplored)
                        {
                            continue;
                        }

                        foreach (dynamic wmorow in WorldMapOverlay)
                        {
                            var WMOUIMapArtID = wmorow.Value.UiMapArtID;
                            var offsetX       = wmorow.Value.OffsetX;
                            var offsetY       = wmorow.Value.OffsetY;

                            uint maxWMORows  = 0;
                            uint maxWMOCols  = 0;
                            var  wmoTileDict = new Dictionary <string, int>();

                            if (WMOUIMapArtID == uiMapArtID)
                            {
                                foreach (dynamic wmotrow in WorldMapOverlayTile)
                                {
                                    var worldMapOverlayID = wmotrow.Value.WorldMapOverlayID;

                                    // something wrong in/around this check
                                    if (worldMapOverlayID == wmorow.Key)
                                    {
                                        var fdid       = wmotrow.Value.FileDataID;
                                        var rowIndex   = wmotrow.Value.RowIndex;
                                        var colIndex   = wmotrow.Value.ColIndex;
                                        var layerIndex = wmotrow.Value.LayerIndex;

                                        // Skip other layers for now
                                        if (layerIndex != 0)
                                        {
                                            continue;
                                        }

                                        if (rowIndex > maxWMORows)
                                        {
                                            maxWMORows = rowIndex;
                                        }

                                        if (colIndex > maxWMOCols)
                                        {
                                            maxWMOCols = colIndex;
                                        }

                                        wmoTileDict.Add(rowIndex + "," + colIndex, fdid);
                                    }
                                }
                            }

                            if (wmoTileDict.Count == 0)
                            {
                                continue;
                            }

                            var layerResX = (maxWMORows + 1) * 256;
                            var layerResY = (maxWMOCols + 1) * 256;

                            var layerBitmap   = new Bitmap((int)layerResY, (int)layerResX);
                            var layerGraphics = Graphics.FromImage(layerBitmap);

                            for (var cur_x = 0; cur_x < maxWMORows + 1; cur_x++)
                            {
                                for (var cur_y = 0; cur_y < maxWMOCols + 1; cur_y++)
                                {
                                    var fdid = wmoTileDict[cur_x + "," + cur_y];

                                    if (CASC.FileExists((uint)fdid))
                                    {
                                        using (var stream = CASC.OpenFile((uint)fdid))
                                        {
                                            try
                                            {
                                                var blp  = new BlpFile(stream);
                                                var posY = cur_y * 256 + offsetX;
                                                var posX = cur_x * 256 + offsetY;

                                                if (saveLayers)
                                                {
                                                    layerGraphics.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                                }
                                                g.DrawImage(blp.GetBitmap(0), posY, posX, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                            }
                                        }
                                    }
                                }
                            }

                            if (saveLayers)
                            {
                                if (!Directory.Exists("layers/" + CleanFileName(mapRow.Key + " - " + mapName) + "/"))
                                {
                                    Directory.CreateDirectory("layers/" + CleanFileName(mapRow.Key + " - " + mapName) + "/");
                                }
                                layerBitmap.Save("layers/" + CleanFileName(mapRow.Key + " - " + mapName) + "/" + wmorow.Key + ".png");
                            }
                        }

                        if (saveExplored)
                        {
                            bmp.Save("explored/ " + CleanFileName(mapRow.Key + " - " + mapName + ".png"));
                        }
                    }
                }
            }
        }
예제 #24
0
        static void Main(string[] args)
        {
            CASC.InitCasc(null, "S:\\World of Warcraft Public Test", "wowt");

            Console.WriteLine("CASC initialized for build " + CASC.cascHandler.Config.ActiveBuild);

            /*var reader = new DB6Reader(CASC.OpenFile("DBFilesClient\\Map.db2"));
             *
             * foreach (var row in reader)
             * {
             *  var map = row.Value.GetField<string>(1);
             *  Console.WriteLine(map);
             * }
             */

            var maps = new string[] { "Azeroth", "Kalimdor", "test", "ScottTest", "PVPZone01", "Shadowfang", "StormwindJail", "StormwindPrison", "DeadminesInstance", "PVPZone02", "Collin", "WailingCaverns", "Monastery", "RazorfenKraulInstance", "Blackfathom", "Uldaman", "GnomeragonInstance", "SunkenTemple", "RazorfenDowns", "EmeraldDream", "MonasteryInstances", "TanarisInstance", "BlackRockSpire", "BlackrockDepths", "OnyxiaLairInstance", "CavernsOfTime", "SchoolofNecromancy", "Zul'gurub", "Stratholme", "Mauradon", "DeeprunTram", "OrgrimmarInstance", "MoltenCore", "DireMaul", "AlliancePVPBarracks", "HordePVPBarracks", "development", "BlackwingLair", "PVPZone03", "AhnQiraj", "PVPZone04", "Expansion01", "AhnQirajTemple", "Karazahn", "Stratholme Raid", "HyjalPast", "HellfireMilitary", "HellfireDemon", "HellfireRampart", "HellfireRaid", "CoilfangPumping", "CoilfangMarsh", "CoilfangDraenei", "CoilfangRaid", "TempestKeepRaid", "TempestKeepArcane", "TempestKeepAtrium", "TempestKeepFactory", "AuchindounShadow", "AuchindounDemon", "AuchindounEthereal", "AuchindounDraenei", "PVPZone05", "HillsbradPast", "bladesedgearena", "BlackTemple", "GruulsLair", "NetherstormBG", "ZulAman", "Northrend", "PVPLordaeron", "ExteriorTest", "Valgarde70", "UtgardePinnacle", "Nexus70", "Nexus80", "SunwellPlateau", "Transport176244", "Transport176231", "Sunwell5ManFix", "Transport181645", "Transport177233", "Transport176310", "Transport175080", "Transport176495", "Transport164871", "Transport186238", "Transport20808", "Transport187038", "StratholmeCOT", "Transport187263", "CraigTest", "Sunwell5Man", "Ulduar70", "DrakTheronKeep", "Azjol_Uppercity", "Ulduar80", "UlduarRaid", "GunDrak", "development_nonweighted", "QA_DVD", "NorthrendBG", "DalaranPrison", "DeathKnightStart", "Transport_Tirisfal _Vengeance_Landing", "Transport_Menethil_Valgarde", "Transport_Orgrimmar_Warsong_Hold", "Transport_Stormwind_Valiance_Keep", "ChamberOfAspectsBlack", "NexusRaid", "DalaranArena", "OrgrimmarArena", "Azjol_LowerCity", "Transport_Moa'ki_Unu'pe", "Transport_Moa'ki_Kamagua", "Transport192241", "Transport192242", "WintergraspRaid", "unused", "IsleofConquest", "IcecrownCitadel", "IcecrownCitadel5Man", "AbyssalMaw", "Gilneas", "Transport_AllianceAirshipBG", "Transport_HordeAirshipBG", "AbyssalMaw_Interior", "Uldum", "BlackRockSpire_4_0", "Deephome", "Transport_Orgrimmar_to_Thunderbluff", "LostIsles", "ArgentTournamentRaid", "ArgentTournamentDungeon", "ElevatorSpawnTest", "Gilneas2", "GilneasPhase1", "GilneasPhase2", "SkywallDungeon", "QuarryofTears", "LostIslesPhase1", "Deephomeceiling", "LostIslesPhase2", "Transport197195", "HallsOfReflection", "BlackwingDescent", "GrimBatolDungeon", "GrimBatolRaid", "Transport197347", "Transport197348", "Transport197349-2", "Transport197349", "Transport197350", "Transport201834", "MountHyjalPhase1", "Firelands1", "Firelands2", "Stormwind", "ChamberofAspectsRed", "DeepholmeDungeon", "CataclysmCTF", "STV_Mine_BG", "TheBattleforGilneas", "MaelstromZone", "DesolaceBomb", "TolBarad", "AhnQirajTerrace", "TwilightHighlandsDragonmawPhase", "Transport200100", "Transport200101", "Transport200102", "Transport200103", "Transport203729", "Transport203730", "UldumPhaseOasis", "Transport 203732", "Transport203858", "Transport203859", "Transport203860", "RedgridgeOrcBomb", "RedridgeBridgePhaseOne", "RedridgeBridgePhaseTwo", "SkywallRaid", "UldumDungeon", "BaradinHold", "UldumPhasedEntrance", "TwilightHighlandsPhasedEntrance", "Gilneas_BG_2", "Transport 203861", "Transport 203862", "UldumPhaseWreckedCamp", "Transport203863", "Transport 2033864", "Transport 2033865", "Zul_Gurub5Man", "NewRaceStartZone", "FirelandsDailies", "HawaiiMainLand", "ScenarioAlcazIsland", "COTDragonblight", "COTWarOfTheAncients", "TheHourOfTwilight", "NexusLegendary", "ShadowpanHideout", "EastTemple", "StormstoutBrewery", "TheGreatWall", "DeathwingBack", "EyeoftheStorm2.0", "JadeForestAllianceHubPhase", "JadeForestBattlefieldPhase", "DarkmoonFaire", "TurtleShipPhase01", "TurtleShipPhase02", "MaelstromDeathwingFight", "TolVirArena", "MoguDungeon", "MoguInteriorRaid", "MoguExteriorRaid", "ValleyOfPower", "BFTAllianceScenario", "BFTHordeScenario", "ScarletSanctuaryArmoryAndLibrary", "ScarletMonasteryCathedralGY", "BrewmasterScenario01", "NewScholomance", "MogushanPalace", "MantidRaid", "MistsCTF3", "MantidDungeon", "MonkAreaScenario", "RuinsOfTheramore", "PandaFishingVillageScenario", "MoguRuinsScenario", "AncientMoguCryptScenario", "AncientMoguCyptDestroyedScenario", "ProvingGroundsScenario", "PetBattleJadeForest", "ValleyOfPowerScenario", "RingOfValorScenario", "BrewmasterScenario03", "BlackOxTempleScenario", "ScenarioKlaxxiIsland", "ScenarioBrewmaster04", "LevelDesignLand-DevOnly", "HordeBeachDailyArea", "AllianceBeachDailyArea", "MoguIslandDailyArea", "StormwindGunshipPandariaStartArea", "OrgrimmarGunshipPandariaStart", "TheramoreScenarioPhase", "JadeForestHordeStartingArea", "HordeAmbushScenario", "ThunderIslandRaid", "NavalBattleScenario", "DefenseOfTheAleHouseBG", "HordeBaseBeachScenario", "AllianceBaseBeachScenario", "ALittlePatienceScenario", "GoldRushBG", "JainaDalaranScenario", "WarlockArea", "BlackTempleScenario", "DarkmoonCarousel", "Draenor", "ThunderKingHordeHub", "ThunderIslandAllianceHub", "CitySiegeMoguIslandProgressionScenario", "LightningForgeMoguIslandProgressionScenario", "ShipyardMoguIslandProgressionScenario", "AllianceHubMoguIslandProgressionScenario", "HordeHubMoguIslandProgressionScenario", "FinalGateMoguIslandProgressionScenario", "MoguIslandEventsHordeBase", "MoguIslandEventsAllianceBase", "ShimmerRidgeScenario", "DarkHordeScenario", "Transport218599", "Transport218600", "ShadoPanArena", "MoguIslandLootRoom", "OrgrimmarRaid", "HeartOfTheOldGodScenario", "ProvingGrounds", "FWHordeGarrisonLevel1", "FWHordeGarrisonLevel2", "FWHordeGarrisonLevel3", "Stormgarde Keep", "HalfhillScenario", "SMVAllianceGarrisonLevel1", "SMVAllianceGarrisonLevel2", "SMVAllianceGarrisonLevel3", "CelestialChallenge", "SmallBattlegroundA", "ThePurgeOfGrommarScenario", "SmallBattlegroundB", "SmallBattlegroundC", "SmallBattlegroundD", "Transport_Siege_of_Orgrimmar_Alliance", "Transport_Siege_of_Orgrimmar_Horde", "OgreCompound", "MoonCultistHideout", "WarcraftHeroes", "PattyMackTestGarrisonBldgMap", "DraenorAuchindoun", "GORAllianceGarrisonLevel1", "GORAllianceGarrisonLevel2", "GORAllianceGarrisonLevel3", "BlastedLands", "Ashran", "Transport_Iron_Horde_Gorgrond_Train", "WarWharfSmackdown", "BonetownScenario", "FrostfireFinaleScenario", "BlackrockFoundryRaid", "TaladorIronHordeFinaleScenario", "BlackrockFoundryTrainDepot", "ArakkoaDungeon", "6HU_GARRISON_Blacksmithing_hub", "alliance_garrison_alchemy", "alliance_garrison_enchanting", "garrison_alliance_engineering", "garrison_alliance_farmhouse", "garrison_alliance_inscription", "garrison_alliance_jewelcrafting", "garrison_alliance_leatherworking", "Troll Raid", "garrison_alliance_mine_1", "garrison_alliance_mine_2", "garrison_alliance_mine_3", "garrison_alliance_stable_1", "garrison_alliance_stable_2", "garrison_alliance_stable_3", "garrison_alliance_tailoring", "HighmaulOgreRaid", "garrison_alliance_inn_1", "garrison_alliance_barn", "Transport227523", "GorHordeGarrisonLevel0", "GORHordeGarrisonLevel3", "TALAllianceGarrisonLevel0", "TALAllianceGarrisonLevel3", "TALHordeGarrisonLevel0", "TALHordeGarrisonLevel3", "SOAAllianceGarrison0", "SOAAllianceGarrison3", "SOAHordeGarrison0", "SOAHordeGarrison3", "NAGAllianceGarrisonLevel0", "NAGAllianceGarrisonLevel3", "NAGHordeGarrisonLevel0", "NAGHordeGarrisonLevel3", "garrison_alliance_armory1", "garrison_alliance_barracks1", "garrison_alliance_engineering1", "alliance_garrison_herb_garden1", "alliance_garrison_inn1", "garrison_alliance_lumbermill1", "alliance_garrison_magetower1", "garrison_alliance_pet_stable1", "garrison_alliance_salvageyard1", "garrison_alliance_storehouse1", "garrison_alliance_trading_post1", "garrison_alliance_tailoring1", "garrison_alliance_enchanting", "garrison_alliance_blacksmith1", "garrison_alliance_plot_small", "garrison_alliance_plot_medium", "garrison_alliance_plot_large", "Propland-DevOnly", "TanaanJungleIntro", "CircleofBloodScenario", "TerongorsConfrontation", "devland3", "nagrand_garrison_camp_stable_2", "DefenseOfKaraborScenario", "garrison_horde_barracks1", "ShaperDungeon", "TrollRaid2", "garrison_horde_alchemy1", "garrison_horde_armory1", "garrison_horde_barn1", "garrison_horde_blacksmith1", "garrison_horde_enchanting1", "garrison_horde_engineering1", "garrison_horde_inn1", "garrison_horde_inscription1", "garrison_horde_jewelcrafting1", "garrison_horde_leatherworking1", "garrison_horde_lumbermill1", "garrison_horde_magetower1", "garrison_horde_mine1", "garrison_alliance_petstabe", "garrison_horde_salvageyard1", "garrison_horde_sparringarena1", "garrison_horde_stable1", "garrison_horde_storehouse1", "garrison_horde_tailoring1", "garrison_horde_tradingpost1", "garrison_horde_workshop1", "garrison_alliance_workshop1", "garrison_horde_farm1", "garrison_horde_plot_large", "garrison_horde_plot_medium", "garrison_horde_plot_small", "TanaanJungleIntroForgePhase", "garrison_horde_fishing1", "garrison_alliance_fishing1", "Expansion5QAModelMap", "outdoorGarrisonArenaHorde", "outdoorGarrisonArenaAlliance", "outdoorGarrisonLumberMillAlliance", "outdoorGarrisonLumberMillHorde", "outdoorGarrisonArmoryHorde", "outdoorGarrisonArmoryAlliance", "outdoorGarrisonMageTowerHorde", "outdoorGarrisonMageTowerAlliance", "outdoorGarrisonStablesHorde", "outdoorGarrisonStablesAlliance", "outdoorGarrisonWorkshopHorde", "outdoorGarrisonWorkshopAlliance", "outdoorGarrisonInnHorde", "outdoorGarrisonInnAlliance", "outdoorGarrisonTradingPostHorde", "outdoorGarrisonTradingPostAlliance", "outdoorGarrisonConstructionPlotHorde", "outdoorGarrisonConstructionPlotAlliance", "GrommasharScenario", "FWHordeGarrisonLeve2new", "SMVAllianceGarrisonLevel2new", "garrison_horde_barracks2", "garrison_horde_armory2", "garrison_horde_barn2", "garrison_horde_inn2", "garrison_horde_lumbermill2", "garrison_horde_magetower2", "garrison_horde_petstable2", "garrison_horde_stable2", "garrison_horde_tradingpost2", "garrison_horde_workshop2", "garrison_horde_barracks3", "garrison_horde_armory3", "garrison_horde_barn3", "garrison_horde_inn3", "garrison_horde_magetower3", "garrison_horde_petstable3", "garrison_horde_stable3", "garrison_horde_tradingpost3", "garrison_horde_workshop3", "Garrison_Alliance_Large_Construction", "Garrison_Alliance_Medium_Construction", "Garrison_Horde_Large_Construction", "Garrison_Horde_Medium_Construction", "UpperBlackRockSpire", "garrisonAllianceMageTower2", "garrisonAllianceMageTower3", "garrison_horde_mine2", "garrison_horde_mine3", "garrison_alliance_workshop2", "garrison_alliance_workshop3", "garrison_alliance_lumbermill2", "garrison_alliance_lumbermill3", "Garrison_Horde_Small_Construction", "Garrison_Alliance_Small_Construction", "AuchindounQuest", "alliance_garrison_alchemy_rank2", "alliance_garrison_alchemy_rank3", "garrison_alliance_blacksmith2", "garrison_alliance_enchanting2", "garrison_alliance_engineering2", "garrison_alliance_inscription2", "garrison_alliance_inscription3", "garrison_alliance_jewelcrafting2", "garrison_alliance_jewelcrafting3", "garrison_alliance_leatherworking2", "garrison_alliance_leatherworking3", "garrison_alliance_tailoring2", "garrison_alliance_storehouse2", "garrison_alliance_storehouse3", "garrison_horde_storehouse2", "garrison_horde_storehouse3", "garrison_alliance_salvageyard2", "garrison_alliance_salvageyard3", "garrison_horde_lumbermill3", "garrison_alliance_pet_stable2", "garrison_alliance_pet_stable3", "garrison_alliance_trading_post2", "garrison_alliance_trading_post3", "garrison_alliance_barn2", "garrison_alliance_barn3", "garrison_alliance_inn_2", "garrison_alliance_inn_3", "GorgrondFinaleScenario", "garrison_alliance_barracks2", "garrison_alliance_barracks3", "garrison_alliance_armory2", "garrison_alliance_armory3", "GorgrondFinaleScenarioMap", "garrison_horde_sparringarena2", "garrison_horde_sparringarena3", "garrison_horde_alchemy2", "garrison_horde_alchemy3", "garrison_horde_blacksmith2", "garrison_horde_blacksmith3", "garrison_horde_enchanting2", "garrison_horde_enchanting3", "garrison_horde_inscription2", "garrison_horde_inscription3", "garrison_horde_leatherworking2", "garrison_horde_leatherworking3", "garrison_horde_jewelcrafting2", "garrison_horde_jewelcrafting3", "garrison_horde_tailoring2", "garrison_horde_tailoring3", "garrison_horde_salvageyard2", "garrison_horde_salvageyard3", "PattyMackTestGarrisonBldgMap2", "garrison_horde_engineering2", "garrison_horde_engineering3", "SparringArenaLevel3Stadium", "garrison_horde_fishing2", "garrison_horde_fishing3", "garrison_alliance_fishing2", "garrison_alliance_fishing3", "garrison_alliance_petstable1", "garrison_alliance_petstable2", "garrison_alliance_petstable3", "garrison_alliance_infirmary1", "garrison_alliance_infirmary2", "garrison_alliance_infirmary3", "outdoorGarrisonConstructionPlotAllianceLarge", "outdoorGarrisonConstructionPlotHordeLarge", "HellfireRaid62", "TanaanLegionTest", "ScourgeofNorthshire", "ArtifactAshbringerOrigin", "EdgeofRealityMount", "NagaDungeon", "FXlDesignLand-DevOnly", "7_DungeonExteriorNeltharionsLair", "Transport_The_Iron_Mountain", "BrokenShoreScenario", "AzsunaScenario", "IllidansRock", "HelhiemExteriorArea", "TanaanJungle", "TanaanJungleNoHubsPhase", "Emerald_Nightmare_ValSharah_exterior", "WardenPrison", "MaelstromShaman", "Legion Dungeon", "1466", "GarrisonAllianceShipyard", "GarrisonHordeShipyard", "TheMawofNashal", "Transport_The_Maw_of_Nashal", "Valhallas", "ValSharahTempleofEluneScenario", "WarriorArtifactArea", "DeathKnightArtifactArea", "legionnexus", "GarrisonShipyardAllianceSubmarine", "GarrisonShipyardAllianceDestroyer", "GarrisonShipyardTransport", "GarrisonShipyardDreadnaught", "GarrisonShipyardCarrier", "GarrisonShipyardHordeSubmarine", "GarrisonShipyardHordeDestroyer", "Artifact-PortalWorldAcqusition", "Helheim", "WardenPrisonDungeon", "AcquisitionVioletHold", "AcquisitionWarriorProt", "GarrisonShipyardCarrierAlliance", "GarrisonShipyardGalleonHorde", "AcquisitionHavoc", "Artifact-Warrior Fury Acquisition", "ArtifactPaladinRetAcquisition", "BlackRookHoldDungeon", "DalaranUnderbelly", "ArtifactShamanElementalAcquisition", "BlackrookHoldArena", "NagrandArena2", "BloodtotemCavernFelPhase", "BloodtotemCavernTaurenPhase", "Artifact-WarriorFuryAcquisition", "Artifact-PriestHunterOrderHall", "Artifact-MageOrderHall", "Artifact-MonkOrderHall", "HulnHighmountain", "SuramarCatacombsDungeon", "StormheimPrescenarioWindrunner", "StormheimPrescenarioSkyfire", "ArtifactsDemonHunterOrderHall", "NightmareRaid", "ArtifactWarlockOrderHallScenario", "MardumScenario", "Artifact-WhiteTigerTempleAcquisition", "HighMountain", "Artifact-SkywallAcquisition", "KarazhanScenario", "SuramarRaid", "HighMountainMesa", "Artifact-KarazhanAcquisition", "Artifact-DefenseofMoongladeScenario", "DefenseofMoongladeScenario", "UrsocsLairScenario", "BoostExperience", "Karazhan Scenario", "Artifact-AcquisitionArmsHolyShadow", "Artifact-Dreamway", "Artifact-TerraceofEndlessSpringAcquisition", "LegionVioletHoldDungeon", "Artifact-Acquisition-CombatResto", "Artifacts-CombatAcquisitionShip", "TechTestSeamlessWorldTransitionA", "TechTestSeamlessWorldTransitionB", "ValsharahArena", "Artifact-Acquisition-Underlight", "BoostExperience2", "TransportBoostExperienceAllianceGunship", "TransportBoostExperienceHordeGunship", "BoostExperience2Horde", "TransportBoostExperienceHordeGunship2", "TransportBoostExperienceAllianceGunship2", "TechTestCosmeticParentPerformance", "SuramarCityDungeon", "MaelstromShamanHubIntroScenario", "UdluarScenario", "MaelstromTitanScenario", "Artifact�DalaranVaultAcquisition", "Artifact-DalaranVaultAcquisition", "JulienTestLand-DevOnly", "AssualtOnStormwind", "DevMapA", "DevMapB", "DevMapC", "DevMapD", "DevMapE", "DevMapF", "DevMapG", "ArtifactRestoAcqusition", "ArtifactThroneoftheTides", "SkywallDungeon_OrderHall", "AbyssalMaw_Interior_Scenario", "Artifact-PortalWorldNaskora", "FirelandsArtifact", "ArtifactAcquisitionSubtlety", "Hyjal Instance", "AcquisitionTempleofstorms", "Artifact-SerenityLegionScenario", "DeathKnightCampaign-LightsHopeChapel", "TheRuinsofFalanaar", "Faronaar", "DeathKnightCampaign-Undercity", "DeathKnightCampaign-ScarletMonastery", "ArtifactStormwind", "BlackTemple-Legion", "IllidanTemp", "MageCampaign-TheOculus", "BattleofExodar", "TrialoftheSerpent", "TheCollapseSuramarScenario", "FelHammerDHScenario", "Transport251513", "NetherlightTemplePrison", "TolBarad1", "TheArcwaySuramarScenario", "TransportAllianceShipPhaseableMO", "TransportHordeShipPhaseableMO", "TransportKvaldirShipPhaseableMO", "BlackRookSenario", "VoljinsFuneralPyre", "Helhiem2", "Transport254124", "Acherus", "Karazahn1", "LightsHeart", "BladesEdgeArena2", "EnvironmentLandDevOnly", "SuramarEndScenario", "DungeonBlockout", "BrokenShoreIntro", "LegionShipVertical", "LegionShipHorizontal", "BrokenshorePristine", "BrokenShorePrepatch", "bladesedgearena2b", "EyeofEternityScenario", "TombofSargerasRaid", "TombofSargerasDeungeon", "ABWinter", "ArtifactsDemonHunterOrderHallPhase", "ArtifactGnomeregan", "dreadscarriftwarlockplatform", "WailingCavernsPetBattle", "DeadminesPetBattle", "EyeofEternityMageClassMount", "CookingImpossible", "PitofSaronDeathKnight", "MardumScenarioClientScene", "GnomereganPetBattle", "BrokenShoreBattleshipFinale", "LegionCommandCenter", "LegionSpiderCave", "ArtifactAcquisitionTank", "LegionFelCave", "LegionFelFirenovaArea", "LegionBarracks", "ArtifactHighmountainDualBoss", "HallsofValorScenario", "LegionShipHorizontalValsharah", "LegionShipHorizontalAzsuna", "LegionShipHorizontalHighMountain", "LegionShipHorizontalStormheim", "StratholmePaladinClassMount", "BlackRookHoldArtifactChallenge", "SouthseaPirateShip715BoatHoliday", "hearthstonetavern", "HallsOfValorWarriorClassMount", "BlackrockMountainBrawl", "brokenshorewardentower", "warlockmountscenario", "ColdridgeValley", "HallsofValorHunterScenario", "EyeofEternityMageClassMountShort", "ShrineofAvianaDefenseScenario", "DruidMountFinaleScenario", "FelwingLedgeDemonHunterClassMount", "ThroneoftheFourWindsShamanClassMounts", "DKMountScenario", "RubySanctumDKMountScenario", "AkazamarakHatScenario", "LostGlacierDKMountScenario" };

            //var maps = new string[] { "ABWinter" };
            foreach (var map in maps)
            {
                var mapname = map;

                var hasMinimaps = false;

                var min_x = 64;
                var min_y = 64;

                var max_x = 0;
                var max_y = 0;

                Console.WriteLine("[" + mapname + "] Loading tiles..");

                var bmpDict = new Dictionary <string, Bitmap>();

                for (int cur_x = 0; cur_x < 64; cur_x++)
                {
                    for (int cur_y = 0; cur_y < 64; cur_y++)
                    {
                        var tilename = "World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp";

                        if (CASC.cascHandler.FileExists(tilename))
                        {
                            hasMinimaps = true;

                            if (cur_x > max_x)
                            {
                                max_x = cur_x;
                            }
                            if (cur_y > max_y)
                            {
                                max_y = cur_y;
                            }

                            if (cur_x < min_x)
                            {
                                min_x = cur_x;
                            }
                            if (cur_y < min_y)
                            {
                                min_y = cur_y;
                            }

                            using (var blp = new BlpFile(CASC.cascHandler.OpenFile(tilename)))
                            {
                                bmpDict.Add(cur_x + "_" + cur_y, blp.GetBitmap(0));
                            }
                        }
                    }
                }

                if (hasMinimaps == false)
                {
                    Console.WriteLine("[" + mapname + "] " + "Skipping map, has no minimap tiles");
                    continue;
                }

                Console.WriteLine("[" + mapname + "] MIN: (" + min_x + " " + min_y + ") MAX: (" + max_x + " " + max_y + ")");

                var res_x = (((max_x - min_x) * 256) + 256);
                var res_y = (((max_y - min_y) * 256) + 256);

                if (res_x < 0 || res_y < 0)
                {
                    Console.WriteLine("Invalid resolution!");
                }

                Console.WriteLine("[" + mapname + "] " + "Image will be " + res_x + "x" + res_y);


                ImageInfo imi = new ImageInfo(res_x, res_y, 8, true);
                PngWriter png = FileHelper.CreatePngWriter("maps/" + mapname + ".png", imi, true);

                for (int row = 0; row < png.ImgInfo.Rows; row++)
                {
                    var blp_y       = min_y + (row / 256);
                    var blp_pixel_y = row - ((blp_y - min_y) * 256);

                    ImageLine iline = new ImageLine(imi);
                    for (int col = 0; col < imi.Cols; col++)
                    {
                        var blp_x       = min_x + (col / 256);
                        var blp_pixel_x = col - ((blp_x - min_x) * 256);

                        if (bmpDict.ContainsKey(blp_x + "_" + blp_y))
                        {
                            var pixel = bmpDict[blp_x + "_" + blp_y].GetPixel(blp_pixel_x, blp_pixel_y);
                            ImageLineHelper.SetPixel(iline, col, pixel.R, pixel.G, pixel.B, pixel.A);
                        }
                        else
                        {
                            ImageLineHelper.SetPixel(iline, col, 0x00, 0x00, 0x00, 0x00);
                        }
                    }
                    png.WriteRow(iline, row);
                    if (row % (png.ImgInfo.Rows / 100) == 0)
                    {
                        Console.Write("\r[" + mapname + "] Writing image: " + Math.Round((double)(100 * row) / png.ImgInfo.Rows) + "%");
                    }
                }

                png.End();
                GC.Collect();

                Console.WriteLine("\n[" + mapname + "] Done");
            }
            Console.ReadLine();
        }
예제 #25
0
        private static void Main(string[] args)
        {
            var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("settings.json", true, true).Build();

            var saveExplored   = bool.Parse(config["saveExploredMaps"]);
            var saveUnexplored = bool.Parse(config["saveUnexploredMaps"]);
            var saveLayers     = bool.Parse(config["saveMapLayers"]);
            var saveExploredMapsWithoutUnexplored = bool.Parse(config["saveExploredMapsWithoutUnexplored"]);

            if (saveExplored && !Directory.Exists("explored"))
            {
                Directory.CreateDirectory("explored");
            }

            if (saveUnexplored && !Directory.Exists("unexplored"))
            {
                Directory.CreateDirectory("unexplored");
            }

            if (saveLayers && !Directory.Exists("layers"))
            {
                Directory.CreateDirectory("layers");
            }

            if (saveExploredMapsWithoutUnexplored && !Directory.Exists("exploredNoUnexplored"))
            {
                Directory.CreateDirectory("exploredNoUnexplored");
            }

            var locale = CASCLib.LocaleFlags.enUS;

            if (config["locale"] != string.Empty)
            {
                switch (config["locale"])
                {
                case "deDE":
                    locale = CASCLib.LocaleFlags.deDE;
                    break;

                case "enUS":
                    locale = CASCLib.LocaleFlags.enUS;
                    break;

                case "ruRU":
                    locale = CASCLib.LocaleFlags.ruRU;
                    break;

                case "zhCN":
                    locale = CASCLib.LocaleFlags.zhCN;
                    break;

                case "zhTW":
                    locale = CASCLib.LocaleFlags.zhTW;
                    break;
                }
            }

            if (config["installDir"] != string.Empty && Directory.Exists(config["installDir"]))
            {
                CASC.InitCasc(null, config["installDir"], config["program"], locale);
            }
            else
            {
                CASC.InitCasc(null, null, config["program"], locale);
            }

            var dbcd = new DBCD.DBCD(new CASCDBCProvider(), new DBCD.Providers.GithubDBDProvider());

            string build;

            if (CASC.BuildName.StartsWith("WOW-"))
            {
                var buildNumber = CASC.BuildName.Split("patch")[0].Replace("WOW-", "");
                var buildName   = CASC.BuildName.Split("patch")[1].Split('_')[0];
                build = buildName + "." + buildNumber;
            }
            else
            {
                build = CASC.BuildName;
            }

            var UIMap               = dbcd.Load("UiMap", build);
            var UIMapXArt           = dbcd.Load("UiMapXMapArt", build);
            var UIMapArtTile        = dbcd.Load("UiMapArtTile", build);
            var UIMapArt            = dbcd.Load("UiMapArt", build);
            var UIMapArtStyleLayer  = dbcd.Load("UiMapArtStyleLayer", build);
            var WorldMapOverlay     = dbcd.Load("WorldMapOverlay", build);
            var WorldMapOverlayTile = dbcd.Load("WorldMapOverlayTile", build);

            Console.WriteLine(); // new line after wdc2 debug output

            foreach (dynamic mapRow in UIMap.Values.Reverse())
            {
                var mapName = mapRow.Name_lang;

                Console.WriteLine(mapRow.ID + " = " + mapName);

                foreach (dynamic mxaRow in UIMapXArt.Values)
                {
                    var uiMapArtID = mxaRow.UiMapArtID;
                    var uiMapID    = mxaRow.UiMapID;

                    if (mxaRow.PhaseID != 0)
                    {
                        continue; // Skip phase stuff for now
                    }
                    if (uiMapID == mapRow.ID)
                    {
                        var maxRows  = uint.MinValue;
                        var maxCols  = uint.MinValue;
                        var tileDict = new Dictionary <string, int>();

                        foreach (dynamic matRow in UIMapArtTile.Values)
                        {
                            var matUiMapArtID = matRow.UiMapArtID;
                            if (matUiMapArtID == uiMapArtID)
                            {
                                var fdid       = matRow.FileDataID;
                                var rowIndex   = matRow.RowIndex;
                                var colIndex   = matRow.ColIndex;
                                var layerIndex = matRow.LayerIndex;

                                // Skip other layers for now
                                if (layerIndex != 0)
                                {
                                    continue;
                                }

                                if (rowIndex > maxRows)
                                {
                                    maxRows = rowIndex;
                                }

                                if (colIndex > maxCols)
                                {
                                    maxCols = colIndex;
                                }

                                tileDict.Add(rowIndex + "," + colIndex, fdid);
                            }
                        }

                        uint res_x = 0;
                        uint res_y = 0;

                        foreach (dynamic maRow in UIMapArt.Values)
                        {
                            if (maRow.ID == uiMapArtID)
                            {
                                foreach (dynamic mastRow in UIMapArtStyleLayer.Values)
                                {
                                    if (mastRow.ID == maRow.UiMapArtStyleID)
                                    {
                                        res_x = mastRow.LayerHeight;
                                        res_y = mastRow.LayerWidth;
                                        continue;
                                    }
                                }
                                continue;
                            }
                        }

                        if (res_x == 0)
                        {
                            res_x = (maxRows + 1) * 256;
                        }

                        if (res_y == 0)
                        {
                            res_y = (maxCols + 1) * 256;
                        }

                        var bmp = new Bitmap((int)res_y, (int)res_x);
                        var g   = Graphics.FromImage(bmp);

                        var bmp2 = new Bitmap((int)res_y, (int)res_x);
                        var g2   = Graphics.FromImage(bmp2);

                        for (var cur_x = 0; cur_x < maxRows + 1; cur_x++)
                        {
                            for (var cur_y = 0; cur_y < maxCols + 1; cur_y++)
                            {
                                var fdid = tileDict[cur_x + "," + cur_y];

                                if (CASC.FileExists((uint)fdid))
                                {
                                    using (var stream = CASC.OpenFile((uint)fdid))
                                    {
                                        try
                                        {
                                            var blp = new BlpFile(stream);
                                            g.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                        }
                                        catch (Exception e)
                                        {
                                            Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                        }
                                    }
                                }
                            }
                        }

                        if (saveUnexplored)
                        {
                            bmp.Save("unexplored/ " + CleanFileName(mapRow.ID + " - " + mapName + ".png"));
                        }

                        if (!saveLayers && !saveExplored)
                        {
                            continue;
                        }

                        foreach (dynamic wmorow in WorldMapOverlay.Values)
                        {
                            var WMOUIMapArtID = wmorow.UiMapArtID;
                            var offsetX       = wmorow.OffsetX;
                            var offsetY       = wmorow.OffsetY;

                            uint maxWMORows  = 0;
                            uint maxWMOCols  = 0;
                            var  wmoTileDict = new Dictionary <string, int>();

                            if (WMOUIMapArtID == uiMapArtID)
                            {
                                foreach (dynamic wmotrow in WorldMapOverlayTile.Values)
                                {
                                    var worldMapOverlayID = wmotrow.WorldMapOverlayID;

                                    // something wrong in/around this check
                                    if (worldMapOverlayID == wmorow.ID)
                                    {
                                        var fdid       = wmotrow.FileDataID;
                                        var rowIndex   = wmotrow.RowIndex;
                                        var colIndex   = wmotrow.ColIndex;
                                        var layerIndex = wmotrow.LayerIndex;

                                        // Skip other layers for now
                                        if (layerIndex != 0)
                                        {
                                            continue;
                                        }

                                        if (rowIndex > maxWMORows)
                                        {
                                            maxWMORows = rowIndex;
                                        }

                                        if (colIndex > maxWMOCols)
                                        {
                                            maxWMOCols = colIndex;
                                        }

                                        wmoTileDict.Add(rowIndex + "," + colIndex, fdid);
                                    }
                                }
                            }

                            if (wmoTileDict.Count == 0)
                            {
                                continue;
                            }

                            var layerResX = (maxWMORows + 1) * 256;
                            var layerResY = (maxWMOCols + 1) * 256;

                            var layerBitmap   = new Bitmap((int)layerResY, (int)layerResX);
                            var layerGraphics = Graphics.FromImage(layerBitmap);

                            for (var cur_x = 0; cur_x < maxWMORows + 1; cur_x++)
                            {
                                for (var cur_y = 0; cur_y < maxWMOCols + 1; cur_y++)
                                {
                                    var fdid = wmoTileDict[cur_x + "," + cur_y];

                                    if (CASC.FileExists((uint)fdid))
                                    {
                                        using (var stream = CASC.OpenFile((uint)fdid))
                                        {
                                            try
                                            {
                                                var blp  = new BlpFile(stream);
                                                var posY = cur_y * 256 + offsetX;
                                                var posX = cur_x * 256 + offsetY;

                                                if (saveLayers)
                                                {
                                                    layerGraphics.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                                }

                                                var blpBMP = blp.GetBitmap(0);
                                                g.DrawImage(blpBMP, posY, posX, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);

                                                if (saveExploredMapsWithoutUnexplored)
                                                {
                                                    g2.DrawImage(blpBMP, posY, posX, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                            }
                                        }
                                    }
                                }
                            }

                            if (saveLayers)
                            {
                                if (!Directory.Exists("layers/" + CleanFileName(mapRow
                                                                                + " - " + mapName) + "/"))
                                {
                                    Directory.CreateDirectory("layers/" + CleanFileName(mapRow.ID + " - " + mapName) + "/");
                                }
                                layerBitmap.Save("layers/" + CleanFileName(mapRow.ID + " - " + mapName) + "/" + wmorow.ID + ".png");
                            }
                        }

                        if (saveExplored)
                        {
                            bmp.Save("explored/" + CleanFileName(mapRow.ID + ".png"));
                        }

                        if (saveExploredMapsWithoutUnexplored)
                        {
                            bmp2.Save("exploredNoUnexplored/ " + CleanFileName(mapRow.ID + " - " + mapName + ".png"));
                        }
                    }
                }
            }
        }
예제 #26
0
        public static int LoadTexture(string filename, CacheStorage cache)
        {
            GL.ActiveTexture(TextureUnit.Texture0);

            filename = filename.ToLower();

            if (cache.materials.ContainsKey(filename))
            {
                return(cache.materials[filename]);
            }

            int textureId = GL.GenTexture();

            using (var blp = new BlpFile(CASC.cascHandler.OpenFile(filename)))
            {
                switch (blp.encoding)
                {
                case 1:
                case 2:     // Temporary
                case 3:
                    var bmp = blp.GetBitmap(0);

                    if (bmp == null)
                    {
                        throw new Exception("BMP is null!");
                    }

                    GL.BindTexture(TextureTarget.Texture2D, textureId);
                    cache.materials.Add(filename, textureId);
                    System.Drawing.Imaging.BitmapData bmp_data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                    bmp.UnlockBits(bmp_data);

                    break;

                /*case 2:
                 *  DXTDecompression.DXTFlags flags = (blp.alphaDepth > 1) ? ((blp.alphaEncoding == 7) ? DXTDecompression.DXTFlags.DXT5 : DXTDecompression.DXTFlags.DXT3) : DXTDecompression.DXTFlags.DXT1;
                 *
                 *  var width = blp.width / (int)Math.Pow(2.0, blp.MipMapCount);
                 *  var height = blp.height / (int)Math.Pow(2.0, blp.MipMapCount);
                 *
                 *  int blockSize;
                 *  PixelInternalFormat format;
                 *
                 *  if ((flags & DXTDecompression.DXTFlags.DXT1) != 0)
                 *  {
                 *      blockSize = 8;
                 *      format = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                 *  }
                 *  else if((flags & DXTDecompression.DXTFlags.DXT3) != 0)
                 *  {
                 *      blockSize = 16;
                 *      format = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                 *  }
                 *  else if((flags & DXTDecompression.DXTFlags.DXT5) != 0)
                 *  {
                 *      blockSize = 16;
                 *      format = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                 *  }
                 *  else
                 *  {
                 *      throw new Exception("Unsupported DXT format!");
                 *  }
                 *
                 *  GL.BindTexture(TextureTarget.Texture2D, textureId);
                 *  cache.materials.Add(filename, textureId);
                 *
                 *  for (var i = blp.MipMapCount - 1; i >= 0; i--)
                 *  {
                 *      if ((width *= 2) == 0)
                 *      {
                 *          width = 1;
                 *      }
                 *
                 *      if ((height *= 2) == 0)
                 *      {
                 *          height = 1;
                 *      }
                 *
                 *      var size = ((width + 3) / 4) * ((height + 3) / 4) * blockSize;
                 *
                 *      var data = blp.GetPictureData(i);
                 *
                 *      GL.CompressedTexImage2D(TextureTarget.Texture2D, i, format, width, height, 0, size, );
                 *  }
                 *
                 *  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
                 *  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                 *  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                 *  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                 *
                 *  break;
                 */
                default:
                    throw new Exception("BLP error!");
                }
            }

            return(textureId);
        }
예제 #27
0
        public override void Work()
        {
            LogWrite("Beginning export of {0}...", mapName);

            TextureBox      texProvider = new TextureBox();
            WaveFrontWriter ob          = new WaveFrontWriter(fileName, texProvider, true, true, false);

            try
            {
                if (!Program.IsCASCReady)
                {
                    throw new MapExportException("CASC file engine is not loaded.");
                }

                string wdtPath = string.Format(@"World\Maps\{0}\{0}.wdt", mapName);
                Program.CASCEngine.SaveFileTo(wdtPath, Constants.TEMP_DIRECTORY);

                WDTFile headerFile = new WDTFile(Path.Combine(Constants.TEMP_DIRECTORY, wdtPath));
                headerFile.parse();

                if (!headerFile.Chunks.Any(c => c.ChunkID == Formats.WDT.Chunk_MPHD.Magic))
                {
                    throw new MapExportException("Invalid map header (WDT)");
                }

                // ToDo: Check if world WMO exists and load it.

                // Ensure we have a MAIN chunk before trying to process terrain.
                Formats.WDT.Chunk_MAIN mainChunk   = (Formats.WDT.Chunk_MAIN)headerFile.Chunks.Where(c => c.ChunkID == Formats.WDT.Chunk_MAIN.Magic).FirstOrDefault();
                Formats.WDT.Chunk_MPHD headerChunk = (Formats.WDT.Chunk_MPHD)headerFile.Chunks.Where(c => c.ChunkID == Formats.WDT.Chunk_MPHD.Magic).FirstOrDefault();

                if (mainChunk != null && headerChunk != null)
                {
                    // Pre-calculate UV mapping for terrain.
                    UV[,,] uvMaps = new UV[8, 8, 5];
                    for (int x = 0; x < 8; x++)
                    {
                        for (int y = 0; y < 8; y++)
                        {
                            float uTL = 1 - (0.125f * x);
                            float vTL = 1 - (0.125f * y);
                            float uBR = uTL - 0.125f;
                            float vBR = vTL - 0.125f;

                            int aX = 7 - x;
                            uvMaps[aX, y, 0] = new UV(uBR, vTL); // TL
                            uvMaps[aX, y, 1] = new UV(uBR, vBR); // TR
                            uvMaps[aX, y, 2] = new UV(uTL, vTL); // BL
                            uvMaps[aX, y, 3] = new UV(uTL, vBR); // BR
                            uvMaps[aX, y, 4] = new UV(uTL - 0.0625f, vTL - 0.0625f);
                        }
                    }

                    int meshIndex = 1;
                    int wmoIndex  = 1;

                    // Create a directory for map data (alpha maps, etc).
                    string dataDirRaw = string.Format("{0}.data", Path.GetFileNameWithoutExtension(fileName));
                    string dataDir    = Path.Combine(Path.GetDirectoryName(fileName), dataDirRaw);

                    if (!Directory.Exists(dataDir))
                    {
                        Directory.CreateDirectory(dataDir);
                    }

                    Dictionary <byte[], uint> texCache = new Dictionary <byte[], uint>(new ByteArrayComparer());

                    for (int y = 0; y < 64; y++)
                    {
                        for (int x = 0; x < 64; x++)
                        {
                            if (mainChunk.map[x, y] && ShouldInclude(x, y))
                            {
                                string pathBase = string.Format(@"World\Maps\{0}\{0}_{1}_{2}", mapName, x, y);
                                string adtPath  = pathBase + ".adt";
                                string texPath  = pathBase + "_tex0.adt";
                                string objPath  = pathBase + "_obj0.adt";

                                Program.CASCEngine.SaveFileTo(adtPath, Constants.TEMP_DIRECTORY);
                                Program.CASCEngine.SaveFileTo(texPath, Constants.TEMP_DIRECTORY);
                                Program.CASCEngine.SaveFileTo(objPath, Constants.TEMP_DIRECTORY);

                                string adtTempPath = Path.Combine(Constants.TEMP_DIRECTORY, adtPath);
                                string texTempPath = Path.Combine(Constants.TEMP_DIRECTORY, texPath);
                                string objTempPath = Path.Combine(Constants.TEMP_DIRECTORY, objPath);

                                try
                                {
                                    ADTFile adt = new ADTFile(adtTempPath, ADTFileType.ROOT);
                                    adt.parse();

                                    ADTFile tex = new ADTFile(texTempPath, ADTFileType.TEX);
                                    tex.parse();

                                    ADTFile obj = new ADTFile(objTempPath, ADTFileType.OBJ);
                                    obj.parse();

                                    // Textures
                                    Chunk_MTEX texChunk = (Chunk_MTEX)tex.getChunk(Chunk_MTEX.Magic);

                                    uint     texIndex    = 0;
                                    Bitmap[] textureData = new Bitmap[texChunk.textures.count()];
                                    foreach (KeyValuePair <int, string> texture in texChunk.textures.raw())
                                    {
                                        string texFile  = texture.Value;
                                        string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, texFile);

                                        if (!File.Exists(tempPath))
                                        {
                                            Program.CASCEngine.SaveFileTo(texFile, Constants.TEMP_DIRECTORY);
                                        }

                                        using (BlpFile blp = new BlpFile(File.OpenRead(tempPath)))
                                            textureData[texIndex] = blp.GetBitmap(0);

                                        texIndex++;
                                    }

                                    Chunk_MCNK[] soupChunks  = adt.getChunksByID(Chunk_MCNK.Magic).Cast <Chunk_MCNK>().ToArray();
                                    Chunk_MCNK[] layerChunks = tex.getChunksByID(Chunk_MCNK.Magic).Cast <Chunk_MCNK>().ToArray();

                                    // Terrain
                                    for (int i = 0; i < 256; i++)
                                    {
                                        Chunk_MCNK soupChunk  = soupChunks[i];
                                        Chunk_MCNK layerChunk = layerChunks[i];

                                        // Terrain chunks
                                        Chunk_MCVT hmChunk = (Chunk_MCVT)soupChunk.getChunk(Chunk_MCVT.Magic);
                                        Chunk_MCNR nChunk  = (Chunk_MCNR)soupChunk.getChunk(Chunk_MCNR.Magic);

                                        // Texture chunks
                                        Chunk_MCLY layers = (Chunk_MCLY)layerChunk.getChunk(Chunk_MCLY.Magic);

                                        // Alpha mapping
                                        Chunk_MCAL alphaMapChunk = (Chunk_MCAL)layerChunk.getChunk(Chunk_MCAL.Magic, false);

                                        string texFileName = string.Format("baked_{0}_{1}_{2}.png", x, y, i);
                                        string texFilePath = Path.Combine(dataDir, texFileName);

                                        EventManager.Trigger_LoadingPrompt(string.Format("Rendering tile {0} at {1},{2}...", i + 1, x, y));
                                        uint texFaceIndex = 0;

                                        if (!File.Exists(texFilePath))
                                        {
                                            Bitmap bmpBase = new Bitmap(layers.layers.Length > 0 ? textureData[layers.layers[0].textureID] : blank);
                                            using (Graphics baseG = Graphics.FromImage(bmpBase))
                                                using (ImageAttributes att = new ImageAttributes())
                                                {
                                                    att.SetWrapMode(WrapMode.TileFlipXY);
                                                    baseG.CompositingQuality = CompositingQuality.HighQuality;
                                                    baseG.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                                                    baseG.CompositingMode    = CompositingMode.SourceOver;

                                                    for (int mI = 1; mI < layers.layers.Length; mI++) // First layer never has an alpha map
                                                    {
                                                        byte[,] alphaMap;
                                                        MCLYLayer layer         = layers.layers[mI];
                                                        bool      headerFlagSet = ((headerChunk.flags & 0x4) == 0x4) || ((headerChunk.flags & 0x80) == 0x80);
                                                        bool      layerFlagSet  = ((layer.flags & 0x200) == 0x200);
                                                        bool      fixAlphaMap   = !((soupChunk.flags & 0x200) == 0x200);

                                                        if (layerFlagSet)
                                                        {
                                                            alphaMap = alphaMapChunk.parse(Chunk_MCAL.CompressType.COMPRESSED, layer.ofsMCAL, fixAlphaMap);
                                                        }
                                                        else
                                                        {
                                                            alphaMap = alphaMapChunk.parse(headerFlagSet ? Chunk_MCAL.CompressType.UNCOMPRESSED_4096 : Chunk_MCAL.CompressType.UNCOMPRESSED_2048, layer.ofsMCAL, fixAlphaMap);
                                                        }

                                                        Bitmap bmpRawTex   = textureData[layer.textureID];
                                                        Bitmap bmpAlphaMap = new Bitmap(64, 64);
                                                        for (int drawX = 0; drawX < 64; drawX++)
                                                        {
                                                            for (int drawY = 0; drawY < 64; drawY++)
                                                            {
                                                                bmpAlphaMap.SetPixel(drawX, drawY, Color.FromArgb(alphaMap[drawX, drawY], 0, 0, 0));
                                                            }
                                                        }

                                                        Bitmap bmpAlphaMapScaled = new Bitmap(bmpRawTex.Width, bmpRawTex.Height);
                                                        using (Graphics g = Graphics.FromImage(bmpAlphaMapScaled))
                                                        {
                                                            g.CompositingQuality = CompositingQuality.HighQuality;
                                                            g.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                                                            g.CompositingMode    = CompositingMode.SourceCopy;
                                                            g.DrawImage(bmpAlphaMap, new Rectangle(0, 0, bmpAlphaMapScaled.Width, bmpAlphaMapScaled.Height), 0, 0, bmpAlphaMap.Width, bmpAlphaMap.Height, GraphicsUnit.Pixel, att);
                                                        }
                                                        bmpAlphaMap.Dispose();

                                                        Bitmap bmpTex = new Bitmap(bmpRawTex.Width, bmpRawTex.Height);
                                                        for (int drawX = 0; drawX < bmpRawTex.Width; drawX++)
                                                        {
                                                            for (int drawY = 0; drawY < bmpRawTex.Height; drawY++)
                                                            {
                                                                // Hacky fix to flip the texture.
                                                                // Remove this if we fix the terrain read-order.
                                                                int sourceX = (bmpRawTex.Width - 1) - drawX;
                                                                //int sourceY = (bmpRawTex.Height - 1) - drawY;

                                                                bmpTex.SetPixel(sourceX, drawY, Color.FromArgb(
                                                                                    bmpAlphaMapScaled.GetPixel(drawX, drawY).A,
                                                                                    bmpRawTex.GetPixel(drawX, drawY).R,
                                                                                    bmpRawTex.GetPixel(drawX, drawY).G,
                                                                                    bmpRawTex.GetPixel(drawX, drawY).B
                                                                                    ));
                                                            }
                                                        }
                                                        bmpAlphaMapScaled.Dispose();
                                                        baseG.DrawImage(bmpTex, 0, 0, bmpBase.Width, bmpBase.Height);
                                                    }

                                                    using (MemoryStream str = new MemoryStream())
                                                        using (MD5 md5 = MD5.Create())
                                                        {
                                                            bmpBase.Save(str, ImageFormat.Png);
                                                            byte[] raw = md5.ComputeHash(str.ToArray());
                                                            uint   cacheID;

                                                            if (texCache.TryGetValue(raw, out cacheID))
                                                            {
                                                                // Cache found, use that instead.
                                                                texFaceIndex = cacheID;
                                                            }
                                                            else
                                                            {
                                                                // No cache found, store new.
                                                                bmpBase.Save(texFilePath);
                                                                texProvider.addTexture(-1, Path.Combine(dataDirRaw, texFileName));
                                                                cacheID = (uint)texProvider.LastIndex;

                                                                texFaceIndex = cacheID;
                                                                texCache.Add(raw, cacheID);
                                                            }
                                                        }
                                                    bmpBase.Dispose();
                                                }
                                        }

                                        Mesh mesh = new Mesh("Terrain Mesh #" + meshIndex);
                                        meshIndex++;

                                        int v = 0;

                                        float pX = soupChunk.position.X;
                                        float pY = -soupChunk.position.Y;
                                        float pZ = soupChunk.position.Z;

                                        int ofs = 10;
                                        for (int sX = 8; sX > 0; sX--)
                                        {
                                            for (int sY = 1; sY < 9; sY++)
                                            {
                                                int cIndex  = ofs - 1;
                                                int blIndex = cIndex - 9;
                                                int tlIndex = cIndex + 8;

                                                float tr = hmChunk.vertices[tlIndex + 1];
                                                float tl = hmChunk.vertices[tlIndex];
                                                float br = hmChunk.vertices[blIndex + 1];
                                                float bl = hmChunk.vertices[blIndex];
                                                float c  = hmChunk.vertices[cIndex];

                                                float oX = pX + (sX * ADTFile.TILE_SIZE);
                                                float oY = pY + (sY * ADTFile.TILE_SIZE);

                                                // Apply UV mapping
                                                for (int uv = 0; uv < 5; uv++)
                                                {
                                                    mesh.addUV(uvMaps[sX - 1, sY - 1, uv]);
                                                }

                                                // Apply verts
                                                mesh.addVert(new Position(oX, tl + pZ, oY));
                                                mesh.addVert(new Position(oX, tr + pZ, oY + ADTFile.TILE_SIZE));
                                                mesh.addVert(new Position(oX + ADTFile.TILE_SIZE, bl + pZ, oY));
                                                mesh.addVert(new Position(oX + ADTFile.TILE_SIZE, br + pZ, oY + ADTFile.TILE_SIZE));
                                                mesh.addVert(new Position(oX + (ADTFile.TILE_SIZE / 2), c + pZ, oY + (ADTFile.TILE_SIZE / 2)));

                                                // Normals
                                                mesh.addNormal(nChunk.normals[tlIndex]);
                                                mesh.addNormal(nChunk.normals[tlIndex + 1]);
                                                mesh.addNormal(nChunk.normals[blIndex]);
                                                mesh.addNormal(nChunk.normals[blIndex + 1]);
                                                mesh.addNormal(nChunk.normals[cIndex]);

                                                // Faces
                                                mesh.addFace(texFaceIndex, v, v + 2, v + 4);
                                                mesh.addFace(texFaceIndex, v + 1, v + 3, v + 4);
                                                mesh.addFace(texFaceIndex, v, v + 1, v + 4);
                                                mesh.addFace(texFaceIndex, v + 2, v + 3, v + 4);

                                                v   += 5;
                                                ofs += 1;
                                            }
                                            ofs += 9;
                                        }

                                        ob.addMesh(mesh);
                                    }

                                    // Parse WMO objects that appear in the world.
                                    EventManager.Trigger_LoadingPrompt("Constructing buildings...");

                                    Chunk_MWID wmoIndexChunk = (Chunk_MWID)obj.getChunk(Chunk_MWID.Magic, false);
                                    Chunk_MWMO wmoModelChunk = (Chunk_MWMO)obj.getChunk(Chunk_MWMO.Magic, false);
                                    Chunk_MODF wmoRefChunk   = (Chunk_MODF)obj.getChunk(Chunk_MODF.Magic, false);

                                    if (wmoIndexChunk != null && wmoModelChunk != null && wmoRefChunk != null)
                                    {
                                        foreach (Chunk_MODF.MODFEntry entry in wmoRefChunk.entries)
                                        {
                                            string          wmoModel    = wmoModelChunk.objects.get((int)wmoIndexChunk.offsets[entry.entry]);
                                            List <CASCFile> groupSearch = CASCSearch.Search(Path.Combine(Path.GetDirectoryName(wmoModel), Path.GetFileNameWithoutExtension(wmoModel)), CASCSearch.SearchType.STARTS_WITH);

                                            if (groupSearch.Count > 0)
                                            {
                                                // Set-up root/group files for the WMO.
                                                WMOFile        wmo        = null;
                                                List <WMOFile> groupFiles = new List <WMOFile>(groupSearch.Count - 1);
                                                string         rootName   = Path.GetFileName(wmoModel).ToLower();

                                                foreach (CASCFile file in groupSearch)
                                                {
                                                    Program.CASCEngine.SaveFileTo(file.FullName, Constants.TEMP_DIRECTORY);
                                                    string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, file.FullName);

                                                    if (file.FullName.ToLower().EndsWith(rootName))
                                                    {
                                                        wmo = new WMOFile(tempPath, true);
                                                    }
                                                    else
                                                    {
                                                        groupFiles.Add(new WMOFile(tempPath, false));
                                                    }
                                                }

                                                foreach (WMOFile groupFile in groupFiles)
                                                {
                                                    wmo.addGroupFile(groupFile);
                                                }

                                                groupFiles.Clear();
                                                wmo.parse();

                                                // Export/register textures needed for this WMO.
                                                Formats.WMO.Chunk_MOTX wmoTexChunk = (Formats.WMO.Chunk_MOTX)wmo.getChunk(Formats.WMO.Chunk_MOTX.Magic);
                                                Dictionary <int, int>  wmoTexMap   = new Dictionary <int, int>();

                                                foreach (KeyValuePair <int, string> node in wmoTexChunk.textures.raw())
                                                {
                                                    string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, node.Value);
                                                    string dumpPath = Path.Combine(Path.GetDirectoryName(node.Value), Path.GetFileNameWithoutExtension(node.Value) + ".png");

                                                    // Extract
                                                    if (!File.Exists(tempPath))
                                                    {
                                                        Program.CASCEngine.SaveFileTo(node.Value, Constants.TEMP_DIRECTORY);
                                                    }

                                                    // Convert
                                                    using (BlpFile blp = new BlpFile(File.OpenRead(tempPath)))
                                                        using (Bitmap bmp = blp.GetBitmap(0))
                                                        {
                                                            string dumpLoc = Path.Combine(dataDir, dumpPath);
                                                            Directory.CreateDirectory(Path.GetDirectoryName(dumpLoc));
                                                            bmp.Save(dumpLoc);
                                                        }

                                                    // Register
                                                    texProvider.addTexture(-1, Path.Combine(dataDirRaw, dumpPath));
                                                    wmoTexMap.Add(node.Key, texProvider.LastIndex);
                                                }

                                                Formats.WMO.Chunk_MOGN wmoNameChunk = (Formats.WMO.Chunk_MOGN)wmo.getChunk(Formats.WMO.Chunk_MOGN.Magic);
                                                Formats.WMO.Chunk_MOMT wmoMatChunk  = (Formats.WMO.Chunk_MOMT)wmo.getChunk(Formats.WMO.Chunk_MOMT.Magic);

                                                foreach (Chunk_Base rawChunk in wmo.getChunksByID(Formats.WMO.Chunk_MOGP.Magic))
                                                {
                                                    Formats.WMO.Chunk_MOGP chunk = (Formats.WMO.Chunk_MOGP)rawChunk;
                                                    string meshName = wmoNameChunk.data.get((int)chunk.groupNameIndex);

                                                    // Skip antiportals.
                                                    if (meshName.ToLower().Equals("antiportal"))
                                                    {
                                                        continue;
                                                    }

                                                    Mesh mesh = new Mesh(string.Format("WMO{0}_{1}", wmoIndex, meshName));

                                                    // Populate mesh with vertices.
                                                    Formats.WMO.Chunk_MOVT vertChunk = (Formats.WMO.Chunk_MOVT)chunk.getChunk(Formats.WMO.Chunk_MOVT.Magic);
                                                    foreach (Position vertPos in vertChunk.vertices)
                                                    {
                                                        mesh.addVert(new Position(entry.position.X + vertPos.X, entry.position.Y + vertPos.Y, entry.position.Z + vertPos.Z));
                                                    }

                                                    // Populate mesh with UVs.
                                                    Formats.WMO.Chunk_MOTV uvChunk = (Formats.WMO.Chunk_MOTV)chunk.getChunk(Formats.WMO.Chunk_MOTV.Magic);
                                                    foreach (UV uv in uvChunk.uvData)
                                                    {
                                                        mesh.addUV(uv);
                                                    }

                                                    // Populate mesh with normals.
                                                    Formats.WMO.Chunk_MONR normChunk = (Formats.WMO.Chunk_MONR)chunk.getChunk(Formats.WMO.Chunk_MONR.Magic);
                                                    foreach (Position norm in normChunk.normals)
                                                    {
                                                        mesh.addNormal(norm);
                                                    }

                                                    // Populate mesh with triangles (faces).
                                                    Formats.WMO.Chunk_MOVI faceChunk    = (Formats.WMO.Chunk_MOVI)chunk.getChunk(Formats.WMO.Chunk_MOVI.Magic);
                                                    Formats.WMO.Chunk_MOPY faceMatChunk = (Formats.WMO.Chunk_MOPY)chunk.getChunk(Formats.WMO.Chunk_MOPY.Magic);

                                                    for (int i = 0; i < faceChunk.positions.Length; i++)
                                                    {
                                                        Formats.WMO.FacePosition position = faceChunk.positions[i];
                                                        Formats.WMO.FaceInfo     info     = faceMatChunk.faceInfo[i];

                                                        if (info.materialID != 0xFF) // 0xFF (255) identifies a collision face.
                                                        {
                                                            Material mat   = wmoMatChunk.materials[info.materialID];
                                                            uint     texID = (uint)wmoTexMap[(int)mat.texture1.offset];

                                                            mesh.addFace(texID, mat.texture2.colour, position.point1, position.point2, position.point3);
                                                        }
                                                    }

                                                    Log.Write("CreateWMOMesh (ADT): " + mesh.ToAdvancedString());
                                                    ob.addMesh(mesh);
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (ADTException ex)
                                {
                                    LogWrite("Unable to process tile {0},{1} due to exception: {2}", x, y, ex.Message);
                                    LogWrite(ex.StackTrace);
                                }
                            }
                        }
                    }

                    EventManager.Trigger_LoadingPrompt(new Random().Next(100) == 42 ? "Reticulating splines..." : "Writing terrain data to file...");

                    ob.Write();
                    ob.Close();
                }

                // Job's done.
                EventManager.Trigger_MapExportDone(true);
            }
            catch (Exception e)
            {
                ob.Close();
                LogWrite("Unable to complete map extraction due to exception: {0}", e.Message);
                EventManager.Trigger_MapExportDone(false, e.Message + e.StackTrace);
            }
        }