public bool Reroll(Func <RandomLevelData, bool> requirements)
        {
            TileConnection requirement = TileConnection.None;

            if (this.data.up && this.up != null && this.up.data != null)
            {
                requirement |= TileConnection.Up;
            }
            if (this.data.down && this.down != null && this.down.data != null)
            {
                requirement |= TileConnection.Down;
            }
            if (this.data.left && this.left != null && this.left.data != null)
            {
                requirement |= TileConnection.Left;
            }
            if (this.data.right && this.right != null && this.right.data != null)
            {
                requirement |= TileConnection.Right;
            }
            RandomLevelData tile = LevelGenerator.GetTile(requirement, this.data, type: LevGenType.Deathmatch, lambdaReq: requirements);

            if (tile == null)
            {
                return(false);
            }
            this.data = tile;
            if (this.symmetricalPartner != null)
            {
                this.symmetricalPartner.data = tile.Flipped();
            }
            return(true);
        }
        private void GenerateTilesRecurse(RandomLevelData tile, LevGenType type = LevGenType.Any)
        {
            this.visited = true;
            if (tile == null)
            {
                return;
            }
            this.data            = tile;
            this.connectionUp    = this.data.up;
            this.connectionDown  = this.data.down;
            this.connectionLeft  = this.data.left;
            this.connectionRight = this.data.right;
            if (this.symmetric)
            {
                if (this.kingTile)
                {
                    if (this.connectionLeft && this.connectionRight || !this.connectionLeft && !this.connectionRight)
                    {
                        this.mirror = true;
                    }
                    else
                    {
                        if (!this.connectionLeft)
                        {
                            if (this.up != null)
                            {
                                this.up.left        = (RandomLevelNode)null;
                                this.up.removeRight = true;
                            }
                            if (this.down != null)
                            {
                                this.down.left        = (RandomLevelNode)null;
                                this.down.removeRight = true;
                            }
                            this.removeRight = true;
                            this.left        = (RandomLevelNode)null;
                        }
                        if (!this.connectionRight)
                        {
                            if (this.up != null)
                            {
                                this.up.right      = (RandomLevelNode)null;
                                this.up.removeLeft = true;
                            }
                            if (this.down != null)
                            {
                                this.down.right      = (RandomLevelNode)null;
                                this.down.removeLeft = true;
                            }
                            this.removeLeft = true;
                            this.right      = (RandomLevelNode)null;
                        }
                    }
                }
                if (this.mirror)
                {
                    this.connectionRight = this.data.left;
                }
                if (this.up != null)
                {
                    this.up.mirror = this.mirror;
                }
                if (this.down != null)
                {
                    this.down.mirror = this.mirror;
                }
            }
            List <TileConnection> source = new List <TileConnection>()
            {
                TileConnection.Right,
                TileConnection.Left,
                TileConnection.Up,
                TileConnection.Down
            };

            if (this.removeLeft)
            {
                source.Remove(TileConnection.Left);
            }
            if (this.removeRight)
            {
                source.Remove(TileConnection.Right);
            }
            foreach (TileConnection tileConnection in (IEnumerable <TileConnection>)source.OrderBy <TileConnection, float>((Func <TileConnection, float>)(x => Rando.Float(1f))))
            {
                switch (tileConnection)
                {
                case TileConnection.Left:
                    if (this.connectionLeft && this.left != null && this.left.data == null && (!this.mirror || !this.symmetric || !this.rightSymmetric))
                    {
                        if (this.mirror && this.symmetric)
                        {
                            this.leftSymmetric = true;
                            if (this.down != null)
                            {
                                this.down.leftSymmetric = this.leftSymmetric;
                                if (this.down.down != null)
                                {
                                    this.down.down.leftSymmetric = this.leftSymmetric;
                                }
                            }
                            if (this.up != null)
                            {
                                this.up.leftSymmetric = this.leftSymmetric;
                                if (this.up.up != null)
                                {
                                    this.up.up.leftSymmetric = this.leftSymmetric;
                                }
                            }
                        }
                        this.left.leftSymmetric  = this.leftSymmetric;
                        this.left.rightSymmetric = this.rightSymmetric;
                        this.left.symmetric      = this.symmetric;
                        this.left.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Right, tile, type: type, mirror: this.left.mirror, filter: this.left.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Right:
                    if (this.connectionRight && this.right != null && this.right.data == null && (!this.mirror || !this.symmetric || !this.leftSymmetric))
                    {
                        if (this.mirror && this.symmetric)
                        {
                            this.rightSymmetric = true;
                            if (this.down != null)
                            {
                                this.down.rightSymmetric = this.rightSymmetric;
                                if (this.down.down != null)
                                {
                                    this.down.down.rightSymmetric = this.rightSymmetric;
                                }
                            }
                            if (this.up != null)
                            {
                                this.up.rightSymmetric = this.rightSymmetric;
                                if (this.up.up != null)
                                {
                                    this.up.up.rightSymmetric = this.rightSymmetric;
                                }
                            }
                        }
                        this.right.leftSymmetric  = this.leftSymmetric;
                        this.right.rightSymmetric = this.rightSymmetric;
                        this.right.symmetric      = this.symmetric;
                        this.right.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Left, tile, type: type, mirror: this.right.mirror, filter: this.right.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Up:
                    if (this.connectionUp && this.up != null && this.up.data == null)
                    {
                        this.up.leftSymmetric  = this.leftSymmetric;
                        this.up.rightSymmetric = this.rightSymmetric;
                        this.up.symmetric      = this.symmetric;
                        this.up.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Down, tile, type: type, mirror: this.mirror, filter: this.up.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Down:
                    if (this.connectionDown && this.down != null && this.down.data == null)
                    {
                        this.down.leftSymmetric  = this.leftSymmetric;
                        this.down.rightSymmetric = this.rightSymmetric;
                        this.down.symmetric      = this.symmetric;
                        this.down.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Up, tile, type: type, mirror: this.mirror, filter: this.down.GetFilter()), type);
                        continue;
                    }
                    continue;

                default:
                    continue;
                }
            }
            if (!this.kingTile || !this.symmetric)
            {
                return;
            }
            this.SolveSymmetry();
            if (this.up != null)
            {
                this.up.SolveSymmetry();
            }
            if (this.down == null)
            {
                return;
            }
            this.down.SolveSymmetry();
        }
 public void GenerateTiles(RandomLevelData tile = null, LevGenType type = LevGenType.Any, bool symmetricVal = false)
 {
     this.symmetric = symmetricVal;
     this.GenerateTilesRecurse(tile != null ? tile : LevelGenerator.GetTile(TileConnection.None, tile, false, type, requiresSpawns: true), type);
     this.ClearFlags();
 }