Exemple #1
0
        public static void exportADT(string file, BackgroundWorker exportworker = null)
        {
            if (exportworker == null)
            {
                exportworker = new BackgroundWorker();
            }

            var outdir = ConfigurationManager.AppSettings["outdir"];

            float TileSize = 1600.0f / 3.0f; //533.333
            float ChunkSize = TileSize / 16.0f; //33.333
            float UnitSize = ChunkSize / 8.0f; //4.166666 // ~~fun fact time with marlamin~~ this /2 ends up being pixelspercoord on minimap
            float MapMidPoint = 32.0f / ChunkSize;

            var mapname = file.Replace("world\\maps\\", "").Substring(0, file.Replace("world\\maps\\", "").IndexOf("\\"));
            var coord = file.Replace("world\\maps\\" + mapname + "\\" + mapname, "").Replace(".adt", "").Split('_');

            var centerx = int.Parse(coord[1]);
            var centery = int.Parse(coord[2]);

            List<Structs.RenderBatch> renderBatches = new List<Structs.RenderBatch>();
            List<Structs.Vertex> verticelist = new List<Structs.Vertex>();
            List<int> indicelist = new List<Int32>();
            Dictionary<int, string> materials = new Dictionary<int, string>();

            var distance = 1;

            // Create output directory
            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file))))
            {
                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));
            }

            for (int y = centery; y < centery + distance; y++)
            {
                for (int x = centerx; x < centerx + distance; x++)
                {
                    var curfile = "world\\maps\\" + mapname + "\\" + mapname + "_" + x + "_" + y + ".adt";

                    if (!CASC.FileExists(file))
                    {
                        Console.WriteLine("File " + file + " does not exist");
                        continue;
                    }

                    exportworker.ReportProgress(0, "Loading ADT " + curfile);

                    ADTReader reader = new ADTReader();
                    reader.LoadADT(curfile);

                    // No chunks? Let's get the hell out of here
                    if (reader.adtfile.chunks == null)
                    {
                        continue;
                    }
                    if (CASC.FileExists("world\\maptextures\\" + mapname + "\\" + mapname + "_" + y + "_" + x + ".blp"))
                    {
                        materials.Add(materials.Count() + 1, "mat" + y.ToString() + x.ToString());

                        var blpreader = new BLPReader();

                        blpreader.LoadBLP(curfile.Replace("maps", "maptextures").Replace(".adt", ".blp"));

                        try
                        {
                            blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file), "mat" + y.ToString() + x.ToString() + ".png"));
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }

                    //List<Material> materials = new List<Material>();

                    //for (int ti = 0; ti < reader.adtfile.textures.filenames.Count(); ti++)
                    //{
                    //    Material material = new Material();
                    //    material.filename = reader.adtfile.textures.filenames[ti];

                    //    //if (!WoWFormatLib.Utils.CASC.FileExists(material.filename)) { continue; }

                    //    material.textureID = BLPLoader.LoadTexture(reader.adtfile.textures.filenames[ti], cache);

                    //    materials.Add(material);
                    //}

                    var initialChunkY = reader.adtfile.chunks[0].header.position.Y;
                    var initialChunkX = reader.adtfile.chunks[0].header.position.X;

                    for (uint c = 0; c < reader.adtfile.chunks.Count(); c++)
                    {
                        var chunk = reader.adtfile.chunks[c];

                        int off = verticelist.Count();

                        Structs.RenderBatch batch = new Structs.RenderBatch();

                        for (int i = 0, idx = 0; i < 17; i++)
                        {
                            for (int j = 0; j < (((i % 2) != 0) ? 8 : 9); j++)
                            {
                                Structs.Vertex v = new Structs.Vertex();
                                v.Normal = new OpenTK.Vector3(chunk.normals.normal_2[idx] / 127f, chunk.normals.normal_0[idx] / 127f, chunk.normals.normal_1[idx] / 127f);
                                v.Position = new OpenTK.Vector3(chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z, chunk.header.position.X - (i * UnitSize * 0.5f));
                                if ((i % 2) != 0) v.Position.X -= 0.5f * UnitSize;
                                v.TexCoord = new Vector2(-(v.Position.X - initialChunkX) / TileSize, -(v.Position.Z - initialChunkY) / TileSize);
                                verticelist.Add(v);
                            }
                        }

                        batch.firstFace = (uint)indicelist.Count();

                        for (int j = 9; j < 145; j++)
                        {
                            indicelist.AddRange(new Int32[] { off + j + 8, off + j - 9, off + j });
                            indicelist.AddRange(new Int32[] { off + j - 9, off + j - 8, off + j });
                            indicelist.AddRange(new Int32[] { off + j - 8, off + j + 9, off + j });
                            indicelist.AddRange(new Int32[] { off + j + 9, off + j + 8, off + j });
                            if ((j + 1) % (9 + 8) == 0) j += 9;
                        }

                        batch.materialID = (uint)materials.Count();

                        batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace;

                        //var layermats = new List<uint>();
                        //var alphalayermats = new List<int>();

                        //for (int li = 0; li < reader.adtfile.texChunks[c].layers.Count(); li++)
                        //{
                        //    if (reader.adtfile.texChunks[c].alphaLayer != null)
                        //    {
                        //        alphalayermats.Add(BLPLoader.GenerateAlphaTexture(reader.adtfile.texChunks[c].alphaLayer[li].layer));
                        //    }
                        //    layermats.Add((uint)cache.materials[reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[li].textureId].ToLower()]);
                        //}

                        //batch.materialID = layermats.ToArray();
                        //batch.alphaMaterialID = alphalayermats.ToArray();

                        renderBatches.Add(batch);
                    }
                }
            }

            var mtlsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl"));

            //No idea how MTL files really work yet. Needs more investigation.
            foreach (var material in materials)
            {
                mtlsw.WriteLine("newmtl " + material.Value);
                mtlsw.WriteLine("Ka 1.000000 1.000000 1.000000");
                mtlsw.WriteLine("Kd 0.640000 0.640000 0.640000");
                mtlsw.WriteLine("map_Ka " + material.Value + ".png");
                mtlsw.WriteLine("map_Kd " + material.Value + ".png");
            }

            mtlsw.Close();

            var indices = indicelist.ToArray();

            var adtname = Path.GetFileNameWithoutExtension(file);

            var objsw = new StreamWriter(Path.Combine(outdir, file.Replace(".adt", ".obj")));

            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl");
            objsw.WriteLine("g " + adtname);

            foreach (var vertex in verticelist)
            {
                objsw.WriteLine("v " + vertex.Position.X + " " + vertex.Position.Y + " " + vertex.Position.Z);
                objsw.WriteLine("vt " + vertex.TexCoord.X + " " + -vertex.TexCoord.Y);
                objsw.WriteLine("vn " + vertex.Normal.X + " " + vertex.Normal.Y + " " + vertex.Normal.Z);
            }

            foreach (var renderBatch in renderBatches)
            {
                var i = renderBatch.firstFace;
                if (materials.ContainsKey((int)renderBatch.materialID)) { objsw.WriteLine("usemtl " + materials[(int)renderBatch.materialID]); objsw.WriteLine("s 1"); }
                while (i < (renderBatch.firstFace + renderBatch.numFaces))
                {
                    objsw.WriteLine("f " + (indices[i] + 1) + "/" + (indices[i] + 1) + "/" + (indices[i] + 1) + " " + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + " " + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1));
                    i = i + 3;
                }
            }

            objsw.Close();
        }
        private void LoadMap(string map, int centerx, int centery, int distance)
        {
            float TileSize = 1600.0f / 3.0f; //533.333
            float ChunkSize = TileSize / 16.0f; //33.333
            float UnitSize = ChunkSize / 8.0f; //4.166666 // ~~fun fact time with marlamin~~ this times 0.5 ends up being pixelspercoord on minimap
            float MapMidPoint = 32.0f / ChunkSize;

            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.NormalArray);

            List<Vertex> verticelist = new List<Vertex>();
            List<Int32> indicelist = new List<Int32>();

            GL.Enable(EnableCap.Texture2D);

            for (int x = centerx; x < centerx + distance; x++)
            {
                for (int y = centery; y < centery + distance; y++)
                {
                    string filename = "World/Maps/" + map + "/" + map + "_" + y + "_" + x + ".adt";

                    if (WoWFormatLib.Utils.CASC.FileExists(filename))
                    {
                        ADTReader reader = new ADTReader();
                        reader.LoadADT(filename);

                        Terrain adt = new Terrain();

                        adt.vertexBuffer = GL.GenBuffer();
                        adt.indiceBuffer = GL.GenBuffer();

                        GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer);
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer);

                        List<Material> materials = new List<Material>();

                        //Check if textures are already loaded or not, multiple ADTs close together probably use the same ones mostly
                        for (int ti = 0; ti < reader.adtfile.textures.filenames.Count(); ti++)
                        {
                            Material material = new Material();
                            material.filename = reader.adtfile.textures.filenames[ti];

                            //if (!WoWFormatLib.Utils.CASC.FileExists(material.filename)) { continue; }

                            material.textureID = BLPLoader.LoadTexture(reader.adtfile.textures.filenames[ti], cache);

                            materials.Add(material);
                        }

                        var initialChunkY = reader.adtfile.chunks[0].header.position.Y;
                        var initialChunkX = reader.adtfile.chunks[0].header.position.X;

                        /*  if(firstLocation.X == 0)
                          {
                              firstLocation = new Vector3(initialChunkY, initialChunkX, 1.0f);
                              Console.WriteLine("Setting first location to " + firstLocation.ToString());
                          }
                          */
                        List<RenderBatch> renderBatches = new List<RenderBatch>();

                        for (uint c = 0; c < reader.adtfile.chunks.Count(); c++)
                        {
                            var chunk = reader.adtfile.chunks[c];

                            int off = verticelist.Count();

                            RenderBatch batch = new RenderBatch();

                            for (int i = 0, idx = 0; i < 17; i++)
                            {
                                for (int j = 0; j < (((i % 2) != 0) ? 8 : 9); j++)
                                {
                                    //var v = new Vector3(chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z, -(chunk.header.position.X - (i * UnitSize * 0.5f)));
                                    Vertex v = new Vertex();
                                    v.Normal = new Vector3(chunk.normals.normal_0[idx], chunk.normals.normal_1[idx], chunk.normals.normal_2[idx]);
                                    if (chunk.vertexShading.red != null && chunk.vertexShading.red[idx] != 127)
                                    {
                                        v.Color = new Vector3(chunk.vertexShading.blue[idx] / 255.0f, chunk.vertexShading.green[idx] / 255.0f, chunk.vertexShading.red[idx] / 255.0f);
                                        //v.Color = new Vector3(1.0f, 1.0f, 1.0f);
                                    }
                                    else
                                    {
                                        v.Color = new Vector3(1.0f, 1.0f, 1.0f);
                                    }

                                    v.TexCoord = new Vector2(((float)j + (((i % 2) != 0) ? 0.5f : 0f)) / 8f, ((float)i * 0.5f) / 8f);

                                    v.Position = new Vector3(chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z, chunk.header.position.X - (i * UnitSize * 0.5f));

                                    if ((i % 2) != 0) v.Position.X -= 0.5f * UnitSize;
                                    verticelist.Add(v);
                                }
                            }

                            batch.firstFace = (uint)indicelist.Count();
                            for (int j = 9; j < 145; j++)
                            {
                                indicelist.AddRange(new Int32[] { off + j + 8, off + j - 9, off + j });
                                indicelist.AddRange(new Int32[] { off + j - 9, off + j - 8, off + j });
                                indicelist.AddRange(new Int32[] { off + j - 8, off + j + 9, off + j });
                                indicelist.AddRange(new Int32[] { off + j + 9, off + j + 8, off + j });
                                if ((j + 1) % (9 + 8) == 0) j += 9;
                            }
                            batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace;

                            if (!cache.materials.ContainsKey(reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower()))
                            {
                                throw new Exception("MaterialCache does not have texture " + reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower());
                            }

                            var layermats = new List<uint>();
                            var alphalayermats = new List<int>();

                            for (int li = 0; li < reader.adtfile.texChunks[c].layers.Count(); li++)
                            {
                                if(reader.adtfile.texChunks[c].alphaLayer != null){
                                    alphalayermats.Add(BLPLoader.GenerateAlphaTexture(reader.adtfile.texChunks[c].alphaLayer[li].layer));

                                }
                                layermats.Add((uint)cache.materials[reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[li].textureId].ToLower()]);
                            }

                            batch.materialID = layermats.ToArray();
                            batch.alphaMaterialID = alphalayermats.ToArray();
                            renderBatches.Add(batch);
                        }

                        List<Doodad> doodads = new List<Doodad>();

                        for (int mi = 0; mi < reader.adtfile.objects.models.entries.Count(); mi++)
                        {
                            Console.WriteLine("Loading model #" + mi);

                            var modelentry = reader.adtfile.objects.models.entries[mi];
                            var mmid = reader.adtfile.objects.m2NameOffsets.offsets[modelentry.mmidEntry];

                            var modelfilename = "";
                            for (int mmi = 0; mmi < reader.adtfile.objects.m2Names.offsets.Count(); mmi++)
                            {
                                if (reader.adtfile.objects.m2Names.offsets[mmi] == mmid)
                                {
                                    modelfilename = reader.adtfile.objects.m2Names.filenames[mmi].ToLower();
                                }
                            }

                            var doodad = new Doodad();
                            doodad.filename = modelfilename;
                            doodad.position = new Vector3(-(modelentry.position.X - 17066), modelentry.position.Y, -(modelentry.position.Z - 17066));
                            doodad.rotation = new Vector3(modelentry.rotation.X, modelentry.rotation.Y, modelentry.rotation.Z);
                            doodad.scale = modelentry.scale;
                            doodads.Add(doodad);

                            if (cache.doodadBatches.ContainsKey(modelfilename))
                            {
                                continue;
                            }

                            M2Loader.LoadM2(modelfilename, cache);
                        }

                        List<WorldModelBatch> worldModelBatches = new List<WorldModelBatch>();

                        // WMO loading goes here
                        for (int wmi = 0; wmi < reader.adtfile.objects.worldModels.entries.Count(); wmi++)
                        {
                            Console.WriteLine("Loading WMO #" + wmi);
                            string wmofilename = "";

                            var wmodelentry = reader.adtfile.objects.worldModels.entries[wmi];
                            var mwid = reader.adtfile.objects.wmoNameOffsets.offsets[wmodelentry.mwidEntry];

                            for (int wmfi = 0; wmfi < reader.adtfile.objects.wmoNames.offsets.Count(); wmfi++)
                            {
                                if (reader.adtfile.objects.wmoNames.offsets[wmfi] == mwid)
                                {
                                    wmofilename = reader.adtfile.objects.wmoNames.filenames[wmfi].ToLower();
                                }

                            }

                            if (wmofilename.Length == 0)
                            {
                                throw new Exception("Unable to find filename for WMO!");
                            }

                            WorldModelBatch wmobatch = new WorldModelBatch();
                            wmobatch.position = new Vector3(-(wmodelentry.position.X - 17066), wmodelentry.position.Y, -(wmodelentry.position.Z - 17066));
                            wmobatch.rotation = new Vector3(wmodelentry.rotation.X, wmodelentry.rotation.Y, wmodelentry.rotation.Z);
                            wmobatch.worldModel = WMOLoader.LoadWMO(wmofilename, cache);
                            worldModelBatches.Add(wmobatch);
                        }

                        adt.renderBatches = renderBatches.ToArray();
                        adt.doodads = doodads.ToArray();
                        adt.worldModelBatches = worldModelBatches.ToArray();

                        int[] indices = indicelist.ToArray();
                        Vertex[] vertices = verticelist.ToArray();

                        Console.WriteLine("Vertices in array: " + vertices.Count()); //37120, correct

                        //indices = indicelist.ToArray();
                        Console.WriteLine("Indices in array: " + indices.Count()); //196608, should be 65.5k which is 196608 / 3. in triangles so its correct?

                        GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer);
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count() * 11 * sizeof(float)), vertices, BufferUsageHint.StaticDraw);

                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer);
                        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw);

                        int verticeBufferSize = 0;
                        int indiceBufferSize = 0;

                        GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer);
                        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out verticeBufferSize);

                        GL.BindBuffer(BufferTarget.ArrayBuffer, adt.indiceBuffer);
                        GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out indiceBufferSize);

                        Console.WriteLine("Vertices in buffer: " + verticeBufferSize / 11 / sizeof(float));
                        Console.WriteLine("Indices in buffer: " + indiceBufferSize / sizeof(int));

                        adts.Add(adt);
                    }
                }
            }
        }
Exemple #3
0
        static void Main(string[] args)
        {
            Console.WriteLine("Initializing CASC..");
            CASC.InitCasc(null, @"C:\World of Warcraft", "wow");
            Console.WriteLine("CASC initialized!");

            var dbcreader = new DBCReader<MapRecord>("DBFilesClient\\Map.dbc");

            string mapfilter = "Draenor";
            //string mapfilter = null;
            for (int mi = 0; mi < dbcreader.recordCount; mi++)
            {
                string mapname = dbcreader[mi].Directory;
                if (mapfilter != null)
                {
                    if (mapname != mapfilter) { continue; }
                }
                Console.WriteLine("Creating image for map " + mapname + " (" + dbcreader[mi].Mapname_lang + ")");

                if (File.Exists("done/" + mapname + ".png"))
                {
                    continue;
                }

                float lowest = float.MaxValue;
                float highest = float.MinValue;

                float lowest_chunkpos = float.MaxValue;
                float highest_chunkpos = float.MinValue;

                var min_x = 64;
                var min_y = 64;

                var max_x = 0;
                var max_y = 0;

                Console.Write("Calculating heights..");
                for (int x = 0; x < 63; x++)
                {
                    for (int y = 0; y < 63; y++)
                    {
                        string filename = "World/Maps/" + mapname + "/" + mapname + "_" + y + "_" + x + ".adt";

                        if (CASC.FileExists(filename))
                        {
                            if (x > max_x) { max_x = x; }
                            if (y > max_y) { max_y = y; }

                            if (x < min_x) { min_x = x; }
                            if (y < min_y) { min_y = y; }

                            ADTReader reader = new ADTReader();
                            reader.LoadADT(filename);
                            for (var i = 0; i < 256; i++)
                            {
                                if (reader.adtfile.chunks[i].header.position.Z < lowest_chunkpos) { lowest_chunkpos = reader.adtfile.chunks[i].header.position.Z; }
                                if (reader.adtfile.chunks[i].header.position.Z > highest_chunkpos) { highest_chunkpos = reader.adtfile.chunks[i].header.position.Z; }

                                for (var j = 0; j < 145; ++j)
                                {
                                    //Console.WriteLine(reader.adtfile.chunks[i].vertices.vertices[j]);
                                    if (reader.adtfile.chunks[i].vertices.vertices[j] < lowest) { lowest = reader.adtfile.chunks[i].vertices.vertices[j]; }
                                    if (reader.adtfile.chunks[i].vertices.vertices[j] > highest) { highest = reader.adtfile.chunks[i].vertices.vertices[j]; }
                                }
                            }
                        }
                    }
                }
                Console.Write(" ..done!\n");
            
                Console.WriteLine("Highest: " + highest);
                Console.WriteLine("Lowest: " + lowest);

                Console.WriteLine("Highest chunkpos: " + highest_chunkpos);
                Console.WriteLine("Lowest chunkpos: " + lowest_chunkpos);

                if (lowest_chunkpos < 0)
                {
                    highest = highest + (lowest * -1) + highest_chunkpos;
                    lowest = (lowest * -1) + (lowest_chunkpos * -1);
                }
                else
                {
                    highest = highest + (lowest * -1) + highest_chunkpos;
                    lowest = (lowest * -1) + lowest_chunkpos;
                }

                Console.WriteLine("Highest post-flip: " + highest);
                Console.WriteLine("Lowest post-flip: " + lowest);

                Console.WriteLine("Highest chunkpos post-flip: " + highest_chunkpos);
                Console.WriteLine("Lowest chunkpos post-flip: " + lowest_chunkpos);

                Console.Write("Creating images..");
                for (int x = 0; x < 63; x++)
                {
                    for (int y = 0; y < 63; y++)
                    {
                        string filename = "World/Maps/" + mapname + "/" + mapname + "_" + y + "_" + x + ".adt";
                        if (CASC.FileExists(filename))
                        {
                            ADTReader reader = new ADTReader();
                            reader.LoadADT(filename);
                            var fullmap = new Bitmap(144, 144);
                            for (var a = 0; a < 256; a++)
                            {
                                //Console.WriteLine(reader.adtfile.chunks[a].header.indexX + " x " + reader.adtfile.chunks[a].header.indexY);

                                int img_x = 0;
                                int img_y = 0;

                                int counter = 0;
                                for (var i = 0; i < 17; ++i)
                                {
                                    for (var j = 0; j < (((i % 2) != 0) ? 8 : 9); ++j)
                                    {
                                        if (i % 2 == 0)
                                        {
                                            //only render these
                                            //Console.Write("(" + j +" " + i + ")" + counter + " |" );
                                            //int greyness = (int)Math.Round(((reader.adtfile.chunks[a].vertices.vertices[counter] + reader.adtfile.chunks[a].header.position.Z) + lowest) / highest * 255);
                                           // if (greyness > 255) { greyness = 255; } //those edge cases where rounding just makes it go over 255
                                            if (reader.adtfile.chunks[a].vertexShading.red != null && reader.adtfile.chunks[a].vertexShading.red[counter] != 127)
                                            {   
                                                fullmap.SetPixel(img_x + (int)(reader.adtfile.chunks[a].header.indexX * 9), img_y + (int)(reader.adtfile.chunks[a].header.indexY * 9),
                                                Color.FromArgb(reader.adtfile.chunks[a].vertexShading.blue[counter], reader.adtfile.chunks[a].vertexShading.green[counter], reader.adtfile.chunks[a].vertexShading.red[counter])
                                                );
                                            }
                                            else
                                            {
                                                int greyness = (int)Math.Round(((reader.adtfile.chunks[a].vertices.vertices[counter] + reader.adtfile.chunks[a].header.position.Z) + lowest) / highest * 255);
                                                if (greyness > 255 || greyness < 0) { greyness = 255; }
                                                fullmap.SetPixel(img_x + (int)(reader.adtfile.chunks[a].header.indexX * 9), img_y + (int)(reader.adtfile.chunks[a].header.indexY * 9), Color.FromArgb(greyness, greyness, greyness));
                                            }
                                        
                                            img_x++;
                                        }
                                        counter++;
                                    }
                                    if (i % 2 == 0)
                                    {
                                        img_y++;
                                        img_x = 0;
                                        //Console.Write("\n");
                                    }
                                }
                            }
                            fullmap.Save("Z:/adttest/" + mapname + "_" + y + "_" + x + ".png");
                        }
                    }
                }
                Console.Write(" ..done!\n");
            
                //Time to compile the full image
                var res_x = (((max_y - min_y) * 144) + 144);
                var res_y = (((max_x - min_x) * 144) + 144);

                if (res_x > 0 && res_y > 0)
                {
                    Console.WriteLine("[" + mapname + "] " + "Creating new image of " + res_x + "x" + res_y);

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

                    for (int cur_x = 0; cur_x < 64; cur_x++)
                    {
                        for (int cur_y = 0; cur_y < 64; cur_y++)
                        {
                            if (File.Exists("Z:/adttest/" + mapname + "_" + cur_x + "_" + cur_y + ".png"))
                            {
                                var bmpreader = new Bitmap("Z:/adttest/" + mapname + "_" + cur_x + "_" + cur_y + ".png");
                                g.DrawImage(bmpreader, (cur_x - min_x) * 144, (cur_y - min_y) * 144, new Rectangle(0, 0, 144, 144), GraphicsUnit.Pixel);
                                bmpreader.Dispose();
                                File.Delete("Z:/adttest/" + mapname + "_" + cur_x + "_" + cur_y + ".png");
                            }
                        }
                    }
                    g.Dispose();
                    if (!Directory.Exists("done")) { Directory.CreateDirectory("done"); }
                    bmp.Save("done/" + mapname + ".png");
                }
            }
        }