private IEnumerator SpreadFire(Dictionary <System.Type, List <Vector3Int> > tiles, bool dynamicSpread)
    {
        // find fire epicenter
        var fireTiles = TilemapHelper.GetTileDictionary(tilemap)[typeof(FireTile)];

        if (fireTiles.Count > 0)
        {
            var average = fireTiles.Aggregate((acc, cur) => acc + cur) / fireTiles.Count;

            StartCoroutine(LerpCameraTo(mainCamera.transform.position, new Vector3(tilemap.CellToWorld(average).x, mainCamera.transform.position.y, tilemap.CellToWorld(average).z - 5f), 0.5f, 0.5f));
            yield return(new WaitForSecondsRealtime(1f));
        }

        var newTilesOnFireCnt = 0;

        foreach (var fireTile in tiles[typeof(FireTile)])
        {
            var currentFireTile = (AbstractGameTile)tilemap.GetTile(fireTile);
            currentFireTile.TileProperties.RoundsOnFire++;
            if (currentFireTile.TileProperties.RoundsOnFire >= 1)
            {
                tilemap.SetTile(fireTile, Resources.Load("BurntTile", typeof(BurntTile)) as BurntTile);
            }

            if (dynamicSpread)
            {
                var reachableNeighbors = TilemapHelper.FindReachableTiles(fireTile, 1, tilemap);
                if (reachableNeighbors.Count >= 2)
                {
                    var possibleTilesToSpreadTo = reachableNeighbors[1];
                    var spreadToThisManyTiles   = (int)Math.Ceiling(possibleTilesToSpreadTo.Count * 0.66f);
                    //var spreadToThisManyTiles = (possibleTilesToSpreadTo.Count - 1) / 2 + 1; // divide by two, but round up
                    var spreadTo = possibleTilesToSpreadTo.OrderBy(x => random.Next()).Take(spreadToThisManyTiles); // randomly choose elements from list
                    foreach (var tile in spreadTo)
                    {
                        var actualTile = (AbstractGameTile)tilemap.GetTile(tile.Item1);
                        if (actualTile.TileProperties.IsFlammable)
                        {
                            tilemap.SetTile(tile.Item1, Resources.Load("FireTile", typeof(FireTile)) as FireTile);
                            newTilesOnFireCnt++;
                        }
                    }
                }
            }
            else
            {
                var neighbors = TilemapHelper.FindNeighbors(fireTile, tilemap);
                foreach (var neighborType in neighbors.Keys)
                {
                    foreach (var neighbor in neighbors[neighborType])
                    {
                        var tile = (AbstractGameTile)tilemap.GetTile(neighbor);
                        if (tile.TileProperties.IsFlammable)
                        {
                            tilemap.SetTile(neighbor, Resources.Load("FireTile", typeof(FireTile)) as FireTile);
                            // replace goal tile with burntGoalTile
                            newTilesOnFireCnt++;
                        }
                    }
                }
            }
        }

        if (newTilesOnFireCnt == 0)
        {
            levelIsComplete = true;
            Debug.Log("Level complete, no fire can spread anymore");
            audioController.PlayMissionSuccessSound();

            StartCoroutine(StartNextLevelDelayed(3));
        }
        else
        {
            audioController.PlayFireSpreadSound();
        }

        if (currentlySelectedUnit != -1)
        {
            StartCoroutine(LerpCameraTo(mainCamera.transform.position, new Vector3(playerUnits[currentlySelectedUnit].transform.position.x, mainCamera.transform.position.y, playerUnits[currentlySelectedUnit].transform.position.z - 5f), 0.5f, 0.5f));
            yield return(new WaitForSecondsRealtime(1f));
        }

        DisplayReachableTilesForCurrentUnit();
        CreateRandomTileProps();
    }