public TileMask[] GetBitmapsFromSelectedTiles(bool flipX, bool flipY, TilePriority priority)
        {
            if (selectedTiles == null)
            {
                return(null);
            }
            TileMask[] tms =
                new TileMask[selectedTiles.GetLength(0) * selectedTiles.GetLength(1)];

            int w = selectedTiles.GetLength(0) - 1;
            int h = selectedTiles.GetLength(1) - 1;

            int  k = 0;
            int  x, y;
            char c1, c2;

            c1 = selectedTiles[0, 0].Code[2];
            c2 = selectedTiles[w, 0].Code[2];

            bool even1 = (c1 % 2 == 0 && c1 > '9') ||
                         (c1 % 2 == 1 && c1 <= '9');

            bool even2 = (c2 % 2 == 0 && c2 > '9') ||
                         (c2 % 2 == 1 && c2 <= '9');

            bool oddX = even1 != even2;

            c1 = selectedTiles[0, 0].Code[1];
            c2 = selectedTiles[0, h].Code[1];

            even1 = (c1 % 2 == 0 && c1 > '9') ||
                    (c1 % 2 == 1 && c1 <= '9');

            even2 = (c2 % 2 == 0 && c2 > '9') ||
                    (c2 % 2 == 1 && c2 <= '9');
            bool oddY = even1 != even2;

            x = 0;
            int tileSize = 16;

            if (selectedTiles[0, 0].Size == 8)
            {
                tileSize = 8;
            }
            int zsiz = tileSize * TileZoom;

            for (int i = 0; i < selectedTiles.GetLength(0); i++, x += zsiz)
            {
                if (tileSize == 16 && oddX && i == w)
                {
                    x -= (zsiz / 2);
                }

                y = 0;
                for (int j = 0; j < selectedTiles.GetLength(1); j++, y += zsiz)
                {
                    if (tileSize == 16 && oddY && j == h)
                    {
                        y -= (zsiz / 2);
                    }
                    tms[k] = new TileMask(sp, selectedTiles[i, j], TileZoom, flipX, flipY)
                    {
                        Priority = priority,
                        XDisp    = x,
                        YDisp    = y
                    };
                    k++;
                }
            }
            return(tms);
        }
    public List <Tile> GetPathTo(Tile startTile, Tile endTile)
    {
        LinkedList <TilePriority> openToCheck = new LinkedList <TilePriority>();
        Dictionary <Tile, Tile>   origins     = new Dictionary <Tile, Tile>();
        Dictionary <Tile, int>    totalCosts  = new Dictionary <Tile, int>();

        openToCheck.AddFirst(new TilePriority(startTile, Tile.Distance(startTile, endTile)));
        origins.Add(startTile, null);
        totalCosts.Add(startTile, 0);


        while (openToCheck.Count > 0) //HACK hard limit on tiles in openlist
        {
            Debug.Assert(openToCheck.Count < 2500, "AI did not find a way from " + startTile.pPosition.ToString() + " to " + endTile.pPosition.ToString() + " in time");
            if (openToCheck.Count > 2500)
            {
                return(null);
            }


            Tile activeTile = openToCheck.First.Value.tile;
            openToCheck.RemoveFirst();

            if (activeTile == endTile)
            {
                List <Tile> result = new List <Tile>();
                while (activeTile != startTile)
                {
                    result.Add(activeTile);
                    activeTile = origins[activeTile];
                }
                return(result);
            }

            foreach (Tile neighbour in activeTile.GetNeighbours())
            {
                if (neighbour == null || neighbour.pBlockType != eBlockType.Empty)
                {
                    continue;
                }
                int newCost = totalCosts[activeTile] + 1;
                if (!totalCosts.ContainsKey(neighbour) || totalCosts[neighbour] >= newCost)
                {
                    totalCosts[neighbour] = newCost;
                    TilePriority temp = new TilePriority(neighbour, newCost + Tile.Distance(neighbour, endTile));
                    if (openToCheck.Count > 0)
                    {
                        for (LinkedListNode <TilePriority> recentNode = openToCheck.First; recentNode != null; recentNode = recentNode.Next)
                        {
                            if (recentNode.Value.priority > temp.priority)
                            {
                                openToCheck.AddBefore(recentNode, temp);
                                break;
                            }
                        }
                    }
                    else
                    {
                        openToCheck.AddFirst(temp);
                    }
                    origins[neighbour] = activeTile;
                }
            }
        }
        return(null);
    }