public static void ImportAllDtefTiles(string sourceDir, string cachePattern)
        {
            var dirs = Directory.GetDirectories(sourceDir);

            foreach (var dir in dirs)
            {
                var fileName      = Path.GetFileName(dir);
                var outputFnTiles = string.Format(cachePattern, fileName);
                DiagManager.Instance.LoadMsg = "Importing " + fileName;

                // Read XML for layer mapping
                var document = new XmlDocument();
                document.Load(Path.Join(dir, XML_FN));
                var tileSize = int.Parse(document.DocumentElement.GetAttribute("dimensions"));

                // The tile index inside the tile sheet where the first frame of animation for this variation is.
                var variationStarts = new[] { 0, 0, 0 };

                // Outer dict: Layer num; inner dict: frame num; tuple: (file name, frame length)
                var frameSpecs = new[] {
                    new SortedDictionary <int, SortedDictionary <int, Tuple <string, int> > >(),
                    new SortedDictionary <int, SortedDictionary <int, Tuple <string, int> > >(),
                    new SortedDictionary <int, SortedDictionary <int, Tuple <string, int> > >()
                };

                try
                {
                    var tileList = new List <BaseSheet>();
                    foreach (var tileTitle in TileTitles)
                    {
                        for (var vi = 0; vi < VariantTitles.Length; vi++)
                        {
                            variationStarts[vi] = tileList.Count;
                            var variantFn = VariantTitles[vi];
                            var reg       = VariantTitlesFrames[vi];
                            var path      = Path.Join(dir, variantFn);
                            if (!File.Exists(path))
                            {
                                if (variantFn != VAR0_FN)
                                {
                                    throw new KeyNotFoundException($"Base variant missing for {fileName}.");
                                }
                                continue;
                            }

                            // Import main frame
                            var tileset = BaseSheet.Import(path);
                            tileList.Add(tileset);

                            // List additional layers and their frames - We do it this way in two steps to make sure it's sorted
                            foreach (var frameFn in Directory.GetFiles(dir, "*.png"))
                            {
                                if (!reg.IsMatch(frameFn))
                                {
                                    continue;
                                }
                                var match       = reg.Match(frameFn);
                                var layerIdx    = int.Parse(match.Groups[1].ToString());
                                var frameIdx    = int.Parse(match.Groups[2].ToString());
                                var durationIdx = int.Parse(match.Groups[3].ToString());
                                if (!frameSpecs[vi].ContainsKey(layerIdx))
                                {
                                    frameSpecs[vi].Add(layerIdx, new SortedDictionary <int, Tuple <string, int> >());
                                }
                                // GetFiles lists some files twice??
                                if (!frameSpecs[vi][layerIdx].ContainsKey(frameIdx))
                                {
                                    frameSpecs[vi][layerIdx].Add(frameIdx, new Tuple <string, int>(frameFn, durationIdx));
                                }
                            }

                            // Import additional frames
                            foreach (var layerFn in frameSpecs[vi].Values)
                            {
                                foreach (var frameFn in layerFn.Values)
                                {
                                    // Import frame
                                    tileset = BaseSheet.Import(frameFn.Item1);
                                    tileList.Add(tileset);
                                }
                            }
                        }

                        var node  = document.SelectSingleNode("//DungeonTileset/RogueEssence/" + tileTitle);
                        var index = -1;
                        if (node != null)
                        {
                            index = int.Parse(node.InnerText);
                        }

                        var autoTile = new AutoTileData();
                        var entry    = new AutoTileAdjacent();

                        var totalArray = new List <TileLayer> [48][];

                        for (var jj = 0; jj < FieldDtefMapping.Length; jj++)
                        {
                            totalArray[jj] = new List <TileLayer> [3];
                            for (var kk = 0; kk < MAX_VARIANTS; kk++)
                            {
                                totalArray[jj][kk] = new List <TileLayer>();
                            }
                        }

                        for (var jj = 0; jj < FieldDtefMapping.Length; jj++)
                        {
                            for (var kk = 0; kk < MAX_VARIANTS; kk++)
                            {
                                if (FieldDtefMapping[jj] == -1)
                                {
                                    continue; // Skip empty tile
                                }
                                var offIndex = tileTitle switch
                                {
                                    "Secondary" => 1,
                                    "Floor" => 2,
                                    _ => 0
                                };
                                var tileX = 6 * offIndex + jj % 6;
                                var tileY = (int)Math.Floor(jj / 6.0);

                                // Base Layer
                                var baseLayer = new TileLayer {
                                    FrameLength = 999
                                };
                                var idx     = variationStarts[kk];
                                var tileset = tileList[idx];
                                //keep adding more tiles to the anim until end of blank spot is found
                                if (!tileset.IsBlank(tileX * tileSize, tileY * tileSize, tileSize, tileSize))
                                {
                                    baseLayer.Frames.Add(new TileFrame(new Loc(tileX, tileY + idx * 8), fileName));
                                }
                                if (baseLayer.Frames.Count < 1)
                                {
                                    continue;
                                }
                                totalArray[jj][kk].Add(baseLayer);

                                // Additional layers
                                var processedLayerFrames = 1;
                                foreach (var layer in frameSpecs[kk].Values)
                                {
                                    if (layer.Count < 1)
                                    {
                                        continue;
                                    }
                                    var anim = new TileLayer {
                                        FrameLength = layer[0].Item2
                                    };

                                    for (var mm = 0; mm < layer.Count; mm++)
                                    {
                                        idx = variationStarts[kk] + processedLayerFrames;
                                        processedLayerFrames += 1;
                                        if (tileList.Count <= idx)
                                        {
                                            continue;
                                        }
                                        tileset = tileList[idx];
                                        //keep adding more tiles to the anim until end of blank spot is found
                                        if (!tileset.IsBlank(tileX * tileSize, tileY * tileSize, tileSize, tileSize))
                                        {
                                            anim.Frames.Add(new TileFrame(new Loc(tileX, tileY + idx * 8), fileName));
                                        }
                                    }

                                    if (anim.Frames.Count > 0)
                                    {
                                        totalArray[jj][kk].Add(anim);
                                    }
                                }
                            }
                        }

                        if (index == -1)
                        {
                            if (tileTitle == "Secondary")  // Secondary terrain is okay to be missing.
                            {
                                continue;
                            }
                            throw new KeyNotFoundException($"Layer index mapping for layer {tileTitle} for {fileName} missing.");
                        }

                        // Import auto tiles
                        for (var i = 0; i < FieldDtefMapping.Length; i++)
                        {
                            if (FieldDtefMapping[i] == -1)
                            {
                                continue;
                            }
                            List <List <TileLayer> > tileArray = typeof(AutoTileAdjacent)
                                                                 .GetField($"Tilex{FieldDtefMapping[i]:X2}")
                                                                 .GetValue(entry) as List <List <TileLayer> >;
                            ImportTileVariant(tileArray, totalArray[i]);
                        }

                        autoTile.Tiles = entry;

                        autoTile.Name = new LocalText(fileName + tileTitle);

                        DataManager.SaveData(index, DataManager.DataType.AutoTile.ToString(), autoTile);
                        Debug.WriteLine($"{index:D3}: {autoTile.Name}");
                    }
                    ImportHelper.SaveTileSheet(tileList, outputFnTiles, tileSize);
                    foreach (var tex in tileList)
                    {
                        tex.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    DiagManager.Instance.LogError(new Exception("Error importing " + fileName + "\n", ex));
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Reads all tileset folders from the input directory, and creates autotiles from them.
        /// </summary>
        /// <param name="sourceDir"></param>
        /// <param name="cacheDir"></param>
        public static void ImportAllAutoTiles(string sourceDir, string cacheDir)
        {
            //TODO: create a version for one tile import
            int index = 0;

            string[] sizeDirs = Directory.GetDirectories(sourceDir);
            foreach (string sizeDir in sizeDirs)
            {
                int tileSize = GetDirSize(sizeDir);
                if (tileSize == 0)
                {
                    continue;
                }


                string[] dirs = Directory.GetDirectories(sizeDir);
                for (int ii = 0; ii < dirs.Length; ii++)
                {
                    string fileName = Path.GetFileName(dirs[ii]);
                    //string[] info = fileName.Split('.');
                    string outputName = fileName;


                    DiagManager.Instance.LoadMsg = "Importing " + outputName;

                    int TOTAL_TILES = 47;

                    try
                    {
                        int currentTier = 0;
                        foreach (string tileTitle in TILE_TITLES)
                        {
                            AutoTileData     autoTile = new AutoTileData();
                            AutoTileAdjacent entry    = new AutoTileAdjacent();

                            List <TileLayer>[][] totalArray = new List <TileLayer> [48][];

                            for (int jj = 0; jj < TOTAL_TILES; jj++)
                            {
                                totalArray[jj] = new List <TileLayer> [3];
                                for (int kk = 0; kk < 3; kk++)
                                {
                                    totalArray[jj][kk] = new List <TileLayer>();
                                }
                            }

                            int layerIndex = 0;
                            while (true)
                            {
                                string[] layers = Directory.GetFiles(dirs[ii] + "/", tileTitle + "." + String.Format("{0:D2}", layerIndex) + ".*");
                                if (layers.Length == 1)
                                {
                                    string   layerName = Path.GetFileNameWithoutExtension(layers[0]);
                                    string[] layerInfo = layerName.Split('.');

                                    using (BaseSheet tileset = BaseSheet.Import(layers[0]))
                                    {
                                        int frameLength = Convert.ToInt32(layerInfo[2]);
                                        if (frameLength == 0)
                                        {
                                            frameLength = 60;
                                        }
                                        int maxVariants = Convert.ToInt32(layerInfo[3]);


                                        int maxFrames = tileset.Width / tileSize / maxVariants;

                                        for (int jj = 0; jj < TOTAL_TILES; jj++)
                                        {
                                            for (int kk = 0; kk < maxVariants; kk++)
                                            {
                                                //go through each layer
                                                TileLayer anim = new TileLayer();
                                                anim.FrameLength = frameLength;

                                                for (int mm = 0; mm < maxFrames; mm++)
                                                {
                                                    //keep adding more tiles to the anim until end of blank spot is found
                                                    if (!tileset.IsBlank((kk * maxFrames + mm) * tileSize, jj * tileSize, tileSize, tileSize))
                                                    {
                                                        anim.Frames.Add(new TileFrame(new Loc(kk * maxFrames + mm, jj + currentTier * 47), outputName));
                                                    }
                                                }

                                                if (anim.Frames.Count > 0)
                                                {
                                                    totalArray[jj][kk].Add(anim);
                                                }
                                            }
                                        }
                                    }
                                }
                                else if (layers.Length > 1)
                                {
                                    throw new Exception("More files than expected");
                                }
                                else
                                {
                                    break;
                                }
                                layerIndex++;
                                currentTier++;
                            }

                            if (layerIndex > 0)
                            {
                                ImportTileVariant(entry.Tilex00, totalArray[0]);
                                ImportTileVariant(entry.Tilex01, totalArray[1]);
                                ImportTileVariant(entry.Tilex02, totalArray[2]);
                                ImportTileVariant(entry.Tilex03, totalArray[3]);
                                ImportTileVariant(entry.Tilex13, totalArray[4]);
                                ImportTileVariant(entry.Tilex04, totalArray[5]);
                                ImportTileVariant(entry.Tilex05, totalArray[6]);
                                ImportTileVariant(entry.Tilex06, totalArray[7]);
                                ImportTileVariant(entry.Tilex26, totalArray[8]);
                                ImportTileVariant(entry.Tilex07, totalArray[9]);
                                ImportTileVariant(entry.Tilex17, totalArray[10]);
                                ImportTileVariant(entry.Tilex27, totalArray[11]);
                                ImportTileVariant(entry.Tilex37, totalArray[12]);
                                ImportTileVariant(entry.Tilex08, totalArray[13]);
                                ImportTileVariant(entry.Tilex09, totalArray[14]);
                                ImportTileVariant(entry.Tilex89, totalArray[15]);
                                ImportTileVariant(entry.Tilex0A, totalArray[16]);
                                ImportTileVariant(entry.Tilex0B, totalArray[17]);
                                ImportTileVariant(entry.Tilex1B, totalArray[18]);
                                ImportTileVariant(entry.Tilex8B, totalArray[19]);
                                ImportTileVariant(entry.Tilex9B, totalArray[20]);
                                ImportTileVariant(entry.Tilex0C, totalArray[21]);
                                ImportTileVariant(entry.Tilex4C, totalArray[22]);
                                ImportTileVariant(entry.Tilex0D, totalArray[23]);
                                ImportTileVariant(entry.Tilex4D, totalArray[24]);
                                ImportTileVariant(entry.Tilex8D, totalArray[25]);
                                ImportTileVariant(entry.TilexCD, totalArray[26]);
                                ImportTileVariant(entry.Tilex0E, totalArray[27]);
                                ImportTileVariant(entry.Tilex2E, totalArray[28]);
                                ImportTileVariant(entry.Tilex4E, totalArray[29]);
                                ImportTileVariant(entry.Tilex6E, totalArray[30]);
                                ImportTileVariant(entry.Tilex0F, totalArray[31]);
                                ImportTileVariant(entry.Tilex1F, totalArray[32]);
                                ImportTileVariant(entry.Tilex2F, totalArray[33]);
                                ImportTileVariant(entry.Tilex3F, totalArray[34]);
                                ImportTileVariant(entry.Tilex4F, totalArray[35]);
                                ImportTileVariant(entry.Tilex5F, totalArray[36]);
                                ImportTileVariant(entry.Tilex6F, totalArray[37]);
                                ImportTileVariant(entry.Tilex7F, totalArray[38]);
                                ImportTileVariant(entry.Tilex8F, totalArray[39]);
                                ImportTileVariant(entry.Tilex9F, totalArray[40]);
                                ImportTileVariant(entry.TilexAF, totalArray[41]);
                                ImportTileVariant(entry.TilexBF, totalArray[42]);
                                ImportTileVariant(entry.TilexCF, totalArray[43]);
                                ImportTileVariant(entry.TilexDF, totalArray[44]);
                                ImportTileVariant(entry.TilexEF, totalArray[45]);
                                ImportTileVariant(entry.TilexFF, totalArray[46]);

                                autoTile.Tiles = entry;

                                autoTile.Name = new LocalText(outputName + tileTitle);

                                DataManager.SaveData(index, DataManager.DataType.AutoTile.ToString(), autoTile);
                                Debug.WriteLine(String.Format("{0:D3}: {1}", index, autoTile.Name));
                                index++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        DiagManager.Instance.LogError(new Exception("Error importing " + outputName + "\n", ex));
                    }
                }
            }
        }