void BuildBorder(CellStartData data)
    {
        if (CellStartData.Level == 1)
        {
            if (data.Y != 0 || data.X != 0)
            {
                if (data.X == 0)
                {
                    Instantiate(LeftBorder, this.transform);
                }

                if (data.X == data.Settings.LevelWidth - 1)
                {
                    Instantiate(RightBorder, this.transform);
                }
            }
        }
        else
        {
            if (data.X == 0)
            {
                Instantiate(LeftBorder, this.transform);
            }

            if (data.X == data.Settings.LevelWidth - 1)
            {
                Instantiate(RightBorder, this.transform);
            }
        }
    }
    bool PlaceStartRoom(CellStartData data)
    {
        if (CellStartData.Level != 1)
        {
            return(false);
        }

        if (data.Y == 0 && data.X == 0)
        {
            if (CellStartData.Level == 1)
            {
                var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.RoomClass == RoomType.Entrance)
                           .PickOne();
                var room = PlaceRoom(rmPf, data.FromDir, EdgeType.A);

                data.NextDir          = Direction.Right;
                nextCellData.X        = data.X + 1;
                nextCellData.FromEdge = room.Data.RealRightEdge;
                nextCellData.FromDir  = data.NextDir;

                return(true);
            }
        }

        return(false);
    }
    Direction CalculateNextDir(CellStartData data)
    {
        var defaultDir = data.Y % 2 == 0 ? Direction.Right : Direction.Left;

        if (data.Y == data.Settings.LevelHeight - 1)
        {
            return(defaultDir);
        }

        if (defaultDir == Direction.Left && data.X == 0)
        {
            return(Direction.Up);
        }

        if (defaultDir == Direction.Right && data.X == data.Settings.LevelWidth - 1)
        {
            return(Direction.Up);
        }

        if (MathHelper.DiceRoll(data.Settings.VerticalChance))
        {
            return(Direction.Up);
        }

        return(defaultDir);
    }
    public void SpawnCell(CellStartData data)
    {
        nextCellData = new CellStartData
        {
            Settings   = data.Settings,
            CellPrefab = data.CellPrefab,
            Repo       = data.Repo,
            X          = data.X,
            Y          = data.Y,
            IsMainPath = data.IsMainPath
        };

        CalculateAndPlaceRoom(data);
        BuildBorder(data);
        CreateNewCell();
    }
    void Start()
    {
        roomRepo = Resources.LoadAll <GameObject>("Rooms");
        var cell = Instantiate(CellPrefab, Vector3.zero, Quaternion.identity).GetComponent <CellStarter>();

        var cellData = new CellStartData
        {
            FromDir  = Direction.Right,
            FromEdge = new[] { EdgeType.A, EdgeType.B, EdgeType.C, EdgeType.D }.PickOne(),
            X          = 0,
            Y          = 0,
            Repo       = roomRepo,
            Settings   = this.Settings,
            CellPrefab = this.CellPrefab,
            IsMainPath = true
        };

        CellStartData.Level = this.Level;
        cell.SpawnCell(cellData);
    }
    bool PlaceEndRoom(CellStartData data)
    {
        if (data.Y == data.Settings.LevelHeight - 1)
        {
            if ((data.FromDir == Direction.Left && data.X == 0) || (data.FromDir == Direction.Right && data.X == data.Settings.LevelWidth - 1))
            {
                if (CellStartData.Level == 3)
                {
                    var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.SideEdges.Contains(data.FromEdge) &&
                                               c.GetComponent <RoomBase>().Data.RoomClass == RoomType.BossChamber)
                               .PickOne();
                    PlaceRoom(rmPf, data.FromDir, data.FromEdge);
                    nextCellData = null;
                    return(true);
                }
            }
        }

        return(false);
    }
    void CalculateAndPlaceRoom(CellStartData data)
    {
        if (!PlaceStartRoom(data) && !PlaceEndRoom(data))
        {
            if (data.FromDir == Direction.Left || data.FromDir == Direction.Right)
            {
                data.NextDir = CalculateNextDir(data);

                if (data.NextDir == Direction.Left || data.NextDir == Direction.Right)
                {
                    var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.SideEdges.Contains(data.FromEdge) &&
                                               c.GetComponent <RoomBase>().Data.RoomClass == RoomType.Horizontal)
                               .PickOne();
                    var room = PlaceRoom(rmPf, data.FromDir, data.FromEdge);

                    if (data.NextDir == Direction.Left)
                    {
                        nextCellData.X        = data.X - 1;
                        nextCellData.FromEdge = room.Data.RealLeftEdge;
                    }

                    if (data.NextDir == Direction.Right)
                    {
                        nextCellData.X        = data.X + 1;
                        nextCellData.FromEdge = room.Data.RealRightEdge;
                    }

                    nextCellData.FromDir = data.NextDir;
                }
                else if (data.NextDir == Direction.Up)
                {
                    var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.SideEdges.Contains(data.FromEdge) &&
                                               c.GetComponent <RoomBase>().Data.TopEdge != EdgeType.Z).PickOne();
                    var room = PlaceRoom(rmPf, data.FromDir, data.FromEdge);

                    nextCellData.Y        = data.Y + 1;
                    nextCellData.FromDir  = data.NextDir;
                    nextCellData.FromEdge = room.Data.RealTopEdge;
                }
                else if (data.NextDir == Direction.Down)
                {
                    var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.SideEdges.Contains(data.FromEdge) &&
                                               c.GetComponent <RoomBase>().Data.BottomEdge != EdgeType.Z).PickOne();
                    var room = PlaceRoom(rmPf, data.FromDir, data.FromEdge);

                    nextCellData.Y        = data.Y - 1;
                    nextCellData.FromDir  = data.NextDir;
                    nextCellData.FromEdge = room.Data.RealBottomEdge;
                }
            }
            else if (data.FromDir == Direction.Up)
            {
                data.NextDir = data.Y % 2 == 0 ? Direction.Right : Direction.Left;
                var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.BottomEdge != EdgeType.Z).PickOne();
                var room = PlaceRoom(rmPf, data.FromDir, data.FromEdge);

                if (data.NextDir == Direction.Left)
                {
                    nextCellData.X        = data.X - 1;
                    nextCellData.FromEdge = room.Data.RealLeftEdge;
                }

                if (data.NextDir == Direction.Right)
                {
                    nextCellData.X        = data.X + 1;
                    nextCellData.FromEdge = room.Data.RealRightEdge;
                }

                nextCellData.FromDir = data.NextDir;
            }
            else if (data.FromDir == Direction.Down)
            {
                data.NextDir = data.Y % 2 == 0 ? Direction.Right : Direction.Left;
                var rmPf = data.Repo.Where(c => c.GetComponent <RoomBase>().Data.TopEdge != EdgeType.Z).PickOne();
                var room = PlaceRoom(rmPf, data.FromDir, data.FromEdge);

                if (data.NextDir == Direction.Left)
                {
                    nextCellData.X        = data.X - 1;
                    nextCellData.FromEdge = room.Data.RealLeftEdge;
                }

                if (data.NextDir == Direction.Right)
                {
                    nextCellData.X        = data.X + 1;
                    nextCellData.FromEdge = room.Data.RealRightEdge;
                }

                nextCellData.FromDir = data.NextDir;
            }
        }
    }