Ejemplo n.º 1
0
 static void AdvanceHallwayPath(GenRoom hub, List <GenRoom> visited)
 {
     if (hub != null && hub.Exists)
     {
         visited.Add(hub);
         if (!visited.Contains(hub.LeftRoom))
         {
             AdvanceBorderPath(hub.LeftRoom, visited);
         }
         if (!visited.Contains(hub.RightRoom))
         {
             AdvanceBorderPath(hub.RightRoom, visited);
         }
         if (!visited.Contains(hub.TopRoom))
         {
             AdvanceBorderPath(hub.TopRoom, visited);
         }
         if (!visited.Contains(hub.BotRoom))
         {
             AdvanceBorderPath(hub.BotRoom, visited);
         }
     }
 }
Ejemplo n.º 2
0
    public static void AddCurve(HashSet <GenRoom> rooms, GenEdge ed)
    {
        GenRoom higher  = ed.r1.r.GetCenter().y > ed.r2.r.GetCenter().y ? ed.r1.r : ed.r2.r;
        GenRoom lower   = ed.r1.r.GetCenter().y > ed.r2.r.GetCenter().y ? ed.r2.r : ed.r1.r;
        GenRoom righter = ed.r1.r.GetCenter().x > ed.r2.r.GetCenter().x ? ed.r1.r : ed.r2.r;
        GenRoom lefter  = ed.r1.r.GetCenter().x > ed.r2.r.GetCenter().x ? ed.r2.r : ed.r1.r;

        RectInt r = new RectInt(lefter.GetCenter().x, lower.GetCenter().y, righter.GetCenter().x - lefter.GetCenter().x, higher.GetCenter().y - lower.GetCenter().y);

        GenRoom verticalLefter = new GenRoom();

        verticalLefter.bounds.x      = r.x - TUNNEL_THICKNESS / 2;
        verticalLefter.bounds.y      = r.y - TUNNEL_THICKNESS / 2;
        verticalLefter.bounds.width  = TUNNEL_THICKNESS;
        verticalLefter.bounds.height = r.height + TUNNEL_THICKNESS;

        GenRoom horizontalLower = new GenRoom();

        horizontalLower.bounds.x      = r.x - TUNNEL_THICKNESS / 2;
        horizontalLower.bounds.y      = r.y - TUNNEL_THICKNESS / 2;
        horizontalLower.bounds.width  = r.width + TUNNEL_THICKNESS;
        horizontalLower.bounds.height = TUNNEL_THICKNESS;

        GenRoom verticalRighter = new GenRoom();

        verticalRighter.bounds.x      = r.x + r.width - TUNNEL_THICKNESS / 2;
        verticalRighter.bounds.y      = r.y - TUNNEL_THICKNESS / 2;
        verticalRighter.bounds.width  = TUNNEL_THICKNESS;
        verticalRighter.bounds.height = r.height + TUNNEL_THICKNESS;

        GenRoom horizontalHigher = new GenRoom();

        horizontalHigher.bounds.x      = r.x - TUNNEL_THICKNESS / 2;
        horizontalHigher.bounds.y      = r.y + r.height - TUNNEL_THICKNESS / 2;
        horizontalHigher.bounds.width  = r.width + TUNNEL_THICKNESS;
        horizontalHigher.bounds.height = TUNNEL_THICKNESS;

        if (lower == lefter)
        {
            horizontalLower.bounds.x      = r.x + lower.bounds.width / 2;
            horizontalLower.bounds.width  = r.width - lower.bounds.width / 2 + TUNNEL_THICKNESS / 2;
            horizontalHigher.bounds.width = r.width - higher.bounds.width / 2 + TUNNEL_THICKNESS / 2;

            verticalLefter.bounds.y       = r.y + lower.bounds.height / 2;
            verticalLefter.bounds.height  = r.height - lower.bounds.height / 2 + TUNNEL_THICKNESS / 2;
            verticalRighter.bounds.height = r.height - higher.bounds.height / 2 + TUNNEL_THICKNESS / 2;
        }
        if (lower == righter)
        {
            horizontalHigher.bounds.x     = r.x + higher.bounds.width / 2;
            horizontalHigher.bounds.width = r.width - higher.bounds.width / 2 + TUNNEL_THICKNESS / 2;
            horizontalLower.bounds.width  = r.width - lower.bounds.width / 2 + TUNNEL_THICKNESS / 2;

            verticalRighter.bounds.y      = r.y + lower.bounds.height / 2;
            verticalRighter.bounds.height = r.height - lower.bounds.height / 2 + TUNNEL_THICKNESS / 2;
            verticalLefter.bounds.height  = r.height - higher.bounds.height / 2 + TUNNEL_THICKNESS / 2;
        }

        bool flip = UnityEngine.Random.value > 0.5;
        bool diffX = ed.r2.r.GetCenter().x - ed.r1.r.GetCenter().x > 0;
        bool diffY = ed.r2.r.GetCenter().y - ed.r1.r.GetCenter().y > 0;
        bool addHorizontal1 = false, addHorizontal2 = false, addVertical1 = false, addVertical2 = false;

        if (diffX && diffY)
        {
            if (flip)
            {
                addVertical1   = true;
                addHorizontal2 = true;
            }
            else
            {
                addVertical2   = true;
                addHorizontal1 = true;
            }
        }
        else if (diffX && !diffY)
        {
            if (flip)
            {
                addVertical2   = true;
                addHorizontal2 = true;
            }
            else
            {
                addVertical1   = true;
                addHorizontal1 = true;
            }
        }
        else if (!diffX && diffY)
        {
            if (flip)
            {
                addVertical1   = true;
                addHorizontal1 = true;
            }
            else
            {
                addVertical2   = true;
                addHorizontal2 = true;
            }
        }
        else if (!diffX && !diffY)
        {
            if (flip)
            {
                addVertical2   = true;
                addHorizontal1 = true;
            }
            else
            {
                addVertical1   = true;
                addHorizontal2 = true;
            }
        }
        if (addHorizontal1)
        {
            rooms.Add(horizontalLower);
            if (lower == lefter)
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    lower.doorsRight.Add(new Vector2Int(horizontalLower.bounds.x - 1, horizontalLower.bounds.y + i));
                }
            }
            else
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    lower.doorsLeft.Add(new Vector2Int(horizontalLower.bounds.x + horizontalLower.bounds.width, horizontalLower.bounds.y + i));
                }
            }
        }
        if (addHorizontal2)
        {
            rooms.Add(horizontalHigher);
            if (lower == righter)
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    higher.doorsRight.Add(new Vector2Int(horizontalHigher.bounds.x - 1, horizontalHigher.bounds.y + i));
                }
            }
            else
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    higher.doorsLeft.Add(new Vector2Int(horizontalHigher.bounds.x + horizontalHigher.bounds.width, horizontalHigher.bounds.y + i));
                }
            }
        }
        if (addVertical1)
        {
            rooms.Add(verticalLefter);
            if (lower == lefter)
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    lower.doorsUp.Add(new Vector2Int(verticalLefter.bounds.x + i, verticalLefter.bounds.y - 1));
                }
            }
            else
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    higher.doorsDown.Add(new Vector2Int(verticalLefter.bounds.x + i, verticalLefter.bounds.y + verticalLefter.bounds.height));
                }
            }
        }
        if (addVertical2)
        {
            rooms.Add(verticalRighter);
            if (lower == righter)
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    lower.doorsUp.Add(new Vector2Int(verticalRighter.bounds.x + i, verticalRighter.bounds.y - 1));
                }
            }
            else
            {
                for (int i = 0; i < TUNNEL_THICKNESS; i++)
                {
                    higher.doorsDown.Add(new Vector2Int(verticalRighter.bounds.x + i, verticalRighter.bounds.y + verticalRighter.bounds.height));
                }
            }
        }
    }
Ejemplo n.º 3
0
    public void Generate()
    {
        int minRoomSize = 50;

        rooms = new HashSet <GenRoom>();
        for (int i = 0; i < 7 + ( int )(UnityEngine.Random.value * 4); i++)
        {
            GenRoom room = new GenRoom();
            room.bounds.width  = ((15 + ( int )(UnityEngine.Random.value * 20)) / 2) * 2;
            room.bounds.height = ((15 + ( int )(UnityEngine.Random.value * 20)) / 2) * 2;
            rooms.Add(room);
        }

        while (true)
        {
            bool changed = false;
            foreach (GenRoom r1 in rooms)
            {
                foreach (GenRoom r2 in rooms)
                {
                    if (r1 == r2)
                    {
                        continue;
                    }
                    Vector2Int p1 = new Vector2Int(r1.bounds.x + r1.bounds.width / 2, r1.bounds.y + r1.bounds.height / 2);
                    Vector2Int p2 = new Vector2Int(r2.bounds.x + r2.bounds.width / 2, r2.bounds.y + r2.bounds.height / 2);
                    if (Math.Pow(Vector2Int.Distance(p1, p2), 2) < 2 * minRoomSize * minRoomSize + 2)
                    {
                        r2.bounds.x += ( int )((UnityEngine.Random.value - 0.5) * 5);
                        r2.bounds.y += ( int )((UnityEngine.Random.value - 0.5) * 2.5);
                        changed      = true;
                        break;
                    }
                }
                if (changed)
                {
                    break;
                }
            }
            if (!changed)
            {
                break;
            }
        }

        HashSet <GenVertex> Q = new HashSet <GenVertex>();

        foreach (GenRoom r in rooms)
        {
            Q.Add(new GenVertex(r));
        }
        GenVertex root = null;

        foreach (GenVertex v in Q)
        {
            if (root == null || v.r.bounds.x < root.r.bounds.x)
            {
                root = v;
            }
        }
        root.value = 0;

        HashSet <GenEdge>   E = new HashSet <GenEdge>();
        HashSet <GenEdge>   G = new HashSet <GenEdge>();
        HashSet <GenVertex> F = new HashSet <GenVertex>();

        foreach (GenVertex r1 in Q)
        {
            foreach (GenVertex r2 in Q)
            {
                if (r1 == r2)
                {
                    goto outer;
                }
                foreach (GenEdge e in E)
                {
                    if (e.r2 == r1 && e.r1 == r2)
                    {
                        goto outer;
                    }
                }
                E.Add(new GenEdge(r1, r2));
            }
            outer :;
        }
        F.Add(root);
        Q.Remove(root);

        while (Q.Count > 0)
        {
            GenEdge start2 = null;
            foreach (GenEdge e in E)
            {
                if (F.Contains(e.r1) ^ F.Contains(e.r2))
                {
                    if (start2 == null || e.dist < start2.dist)
                    {
                        start2 = e;
                    }
                }
            }
            Q.Remove(start2.r2);
            Q.Remove(start2.r1);
            F.Add(start2.r2);
            F.Add(start2.r1);
            E.Remove(start2);
            G.Add(start2);
            if (start2.r1.value < start2.r2.value)
            {
                start2.r2.value = ( float )(start2.r1.value + start2.dist);
            }
            else
            {
                start2.r1.value = ( float )(start2.r2.value + start2.dist);
            }
        }

        // G list of edges
        // rooms list of rooms

        HashSet <GenRoom> rooms2 = new HashSet <GenRoom>();

        foreach (GenEdge ed in G)
        {
            // horizontal
            float diff1 = ed.r1.r.bounds.y - ed.r2.r.bounds.y - ed.r2.r.bounds.height + TUNNEL_THICKNESS;
            float diff2 = ed.r2.r.bounds.y - ed.r1.r.bounds.y - ed.r1.r.bounds.height + TUNNEL_THICKNESS;

            // vertical
            float diff3 = ed.r1.r.bounds.x - ed.r2.r.bounds.x - ed.r2.r.bounds.width + TUNNEL_THICKNESS;
            float diff4 = ed.r2.r.bounds.x - ed.r1.r.bounds.x - ed.r1.r.bounds.width + TUNNEL_THICKNESS;

            if (diff1 < 0 && diff2 < 0)
            {
                AddStraightHorizontal(rooms2, ed);
            }
            else if (diff3 < 0 && diff4 < 0)
            {
                AddStraightVertical(rooms2, ed);
            }
            else
            {
                AddCurve(rooms2, ed);
            }
        }

        HashSet <Vector2Int> allDoors = new HashSet <Vector2Int>();

        foreach (GenRoom r in rooms)
        {
            for (int x1 = r.bounds.x; x1 < r.bounds.x + r.bounds.width; x1++)
            {
                for (int y1 = r.bounds.y; y1 < r.bounds.y + r.bounds.height; y1++)
                {
                    int xMode = (x1 == r.bounds.x) ? -1 : (x1 == r.bounds.x + r.bounds.width - 1) ? 1 : 0;
                    int yMode = (y1 == r.bounds.y) ? -1 : (y1 == r.bounds.y + r.bounds.height - 1) ? 1 : 0;
                    r.tiles.Add(new Vector2Int(x1, y1), new GenTile(Room.TileType.WALL, GenTile.GetPosition(xMode, yMode)));
                }
            }
            for (int x1 = r.bounds.x + 1; x1 < r.bounds.x + r.bounds.width - 1; x1++)
            {
                for (int y1 = r.bounds.y + 1; y1 < r.bounds.y + r.bounds.height - 1; y1++)
                {
                    r.tiles[new Vector2Int(x1, y1)].type = Room.TileType.GROUND;
                }
            }
            allDoors.UnionWith(r.AllDoors());
            foreach (Vector2Int v in r.doorsDown)
            {
                r.tiles[v].type     = Room.TileType.DOOR;
                r.tiles[v].position = GenTile.Position.BOTTOM;
            }
            foreach (Vector2Int v in r.doorsUp)
            {
                r.tiles[v].type     = Room.TileType.DOOR;
                r.tiles[v].position = GenTile.Position.TOP;
            }
            foreach (Vector2Int v in r.doorsLeft)
            {
                r.tiles[v].type     = Room.TileType.DOOR;
                r.tiles[v].position = GenTile.Position.LEFT;
            }
            foreach (Vector2Int v in r.doorsRight)
            {
                r.tiles[v].type     = Room.TileType.DOOR;
                r.tiles[v].position = GenTile.Position.RIGHT;
            }
        }

        path = new GenRoom();
        foreach (GenRoom r in rooms2)
        {
            for (int x1 = r.bounds.x; x1 < r.bounds.x + r.bounds.width; x1++)
            {
                for (int y1 = r.bounds.y; y1 < r.bounds.y + r.bounds.height; y1++)
                {
                    Vector2Int pos1 = new Vector2Int(x1, y1);
                    if (path.tiles.ContainsKey(pos1))
                    {
                        path.tiles[pos1].type = Room.TileType.GROUND;
                    }
                    else
                    {
                        path.tiles.Add(pos1, new GenTile(Room.TileType.GROUND));
                    }

                    Vector2Int pos2 = new Vector2Int(x1 + 1, y1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.RIGHT));
                    }
                    pos2 = new Vector2Int(x1 - 1, y1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.LEFT));
                    }
                    pos2 = new Vector2Int(x1, y1 + 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.TOP));
                    }
                    pos2 = new Vector2Int(x1, y1 - 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.BOTTOM));
                    }
                }
            }
            for (int x1 = r.bounds.x; x1 < r.bounds.x + r.bounds.width; x1++)
            {
                for (int y1 = r.bounds.y; y1 < r.bounds.y + r.bounds.height; y1++)
                {
                    Vector2Int pos2 = new Vector2Int(x1 + 1, y1 + 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.TOP_RIGHT));
                    }
                    pos2 = new Vector2Int(x1 - 1, y1 + 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.TOP_LEFT));
                    }
                    pos2 = new Vector2Int(x1 + 1, y1 - 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.BOTTOM_RIGHT));
                    }
                    pos2 = new Vector2Int(x1 - 1, y1 - 1);
                    if (!path.tiles.ContainsKey(pos2) && !allDoors.Contains(pos2))
                    {
                        path.tiles.Add(pos2, new GenTile(Room.TileType.WALL, GenTile.Position.BOTTOM_LEFT));
                    }
                }
            }
            if (r.AllDoors().Count > 0)
            {
                throw new NotSupportedException("Paths should not have any doors");
            }
        }

        start = root.r;
        end   = null;
        foreach (GenRoom r in rooms)
        {
            if (end == null || r.bounds.x > end.bounds.x)
            {
                end = r;
            }
        }

        rooms.Remove(start);
        rooms.Remove(end);

        foreach (GenRoom r in rooms)
        {
            GenerateInterior(r);
        }

        start.spawnpoints.Add(start.GetCenter());
        end.spawnpoints.Add(end.GetCenter());

        foreach (Vector2Int v in allDoors)
        {
            foreach (GenRoom r in rooms)
            {
                for (int x = -TUNNEL_THICKNESS; x < TUNNEL_THICKNESS; x++)
                {
                    for (int y = -TUNNEL_THICKNESS; y < TUNNEL_THICKNESS; y++)
                    {
                        if (r.tiles.ContainsKey(v + new Vector2Int(x, y)) && r.tiles[v + new Vector2Int(x, y)].type == Room.TileType.ROCK)
                        {
                            r.tiles[v + new Vector2Int(x, y)].type = Room.TileType.GROUND;
                        }
                    }
                }
            }
            {
                GenRoom r = path;
                if (r.tiles.ContainsKey(v + new Vector2Int(0, 1)) && r.tiles[v + new Vector2Int(0, 1)].type == Room.TileType.WALL)
                {
                    r.tiles.Remove(v + new Vector2Int(0, 1));
                }
                if (r.tiles.ContainsKey(v + new Vector2Int(0, -1)) && r.tiles[v + new Vector2Int(0, -1)].type == Room.TileType.WALL)
                {
                    r.tiles.Remove(v + new Vector2Int(0, -1));
                }
                if (r.tiles.ContainsKey(v + new Vector2Int(1, 0)) && r.tiles[v + new Vector2Int(1, 0)].type == Room.TileType.WALL)
                {
                    r.tiles.Remove(v + new Vector2Int(1, 0));
                }
                if (r.tiles.ContainsKey(v + new Vector2Int(-1, 0)) && r.tiles[v + new Vector2Int(-1, 0)].type == Room.TileType.WALL)
                {
                    r.tiles.Remove(v + new Vector2Int(-1, 0));
                }
            }
        }

        foreach (GenRoom r in rooms)
        {
            MakeRoomRelative(r);
        }
        MakeRoomRelative(start);
        MakeRoomRelative(end);
        MakeRoomRelative(path);
    }
Ejemplo n.º 4
0
 public void PlaceRoom(int x, int y, GenRoom room)
 {
     room.PosX = x;
     room.PosY = y;
     Rooms.Add(room);
 }
Ejemplo n.º 5
0
    /// <summary>
    /// checks if Position is in the corner (floor, not wall)
    /// </summary>
    public bool IsCornerGR(int gx, int gy, GenRoom room, GenDetail.DetailType[] checkFor = null, GenDetail.DetailType[] noWall = null)
    {
        if (checkFor == null)
        {
            checkFor = new GenDetail.DetailType[] { GenDetail.DetailType.Wall };
        }
        if (noWall == null)
        {
            noWall = new GenDetail.DetailType[] { GenDetail.DetailType.Door };
        }

        bool    vertical   = false;
        bool    horizontal = false;
        GenTile tile;

        if (room != null)
        {
            tile = room.GetAtWorldspaceG(gx, gy);
            if (tile != null)
            {
                GenTile check = room.GetAtWorldspaceG(gx + 1, gy);
                if (check != null && check.AnyTypes(checkFor) && check.NonTypes(noWall))
                {
                    horizontal = true;
                }
                check = room.GetAtWorldspaceG(gx - 1, gy);
                if (check != null && check.AnyTypes(checkFor) && check.NonTypes(noWall))
                {
                    horizontal = true;
                }
                check = room.GetAtWorldspaceG(gx, gy + 1);
                if (check != null && check.AnyTypes(checkFor) && check.NonTypes(noWall))
                {
                    vertical = true;
                }
                check = room.GetAtWorldspaceG(gx, gy - 1);
                if (check != null && check.AnyTypes(checkFor) && check.NonTypes(noWall))
                {
                    vertical = true;
                }
                return(horizontal && vertical);
            }
            return(false);
        }
        else
        {
            tile = GetTile(gx, gy);
            if (tile != null)
            {
                GenTile check = GetTile(gx + 1, gy);
                if (check != null && check.AnyTypes(GenDetail.DetailType.Wall))
                {
                    horizontal = true;
                }
                check = GetTile(gx - 1, gy);
                if (check != null && check.AnyTypes(GenDetail.DetailType.Wall))
                {
                    horizontal = true;
                }
                check = GetTile(gx, gy + 1);
                if (check != null && check.AnyTypes(GenDetail.DetailType.Wall))
                {
                    vertical = true;
                }
                check = GetTile(gx, gy - 1);
                if (check != null && check.AnyTypes(GenDetail.DetailType.Wall))
                {
                    vertical = true;
                }
                return(horizontal && vertical);
            }
            return(false);
        }
    }
Ejemplo n.º 6
0
    public static IEnumerator GetSimpleTemple()
    {
        GenData temple = new GenData(Random.Range(TempleWidth.start, TempleWidth.end), Random.Range(TempleHeight.start, TempleHeight.end));

        List <GenRoom> AutoFillRoom = new List <GenRoom>();

        // list of all rooms that are not allowed to be used for door placement
        List <GenRoom> NoAutoDoor  = new List <GenRoom>();
        List <GenRoom> SecretRooms = new List <GenRoom>();

        GenTile Chest = GenTile.GetEmpty();

        Chest.Details.Add(new GenDetail()
        {
            Char = '=', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.Chest
        });

        GenTile pillar = GenTile.GetEmpty();

        //pillar.Details.Add(new GenDetail() { Char = '\u01C1', Type = GenDetail.DetailType.Decoration });
        pillar.Details.Add(new GenDetail()
        {
            Char = 'O', Type = GenDetail.DetailType.Decoration
        });

        GenTile[,] pillars = new GenTile[, ]
        {
            { GenTile.Copy(pillar), GenTile.Copy(pillar) },
            { GenTile.Copy(pillar), GenTile.Copy(pillar) }
        };

        GenTile Door = GenTile.GetEmpty();

        Door.Details.Add(new GenDetail()
        {
            Char = '+', Type = GenDetail.DetailType.Door, Entity = GenDetail.EntityType.Door
        });


        GenRoom outer = GenRoom.Sized(temple.Width, temple.Height);

        outer.FillFloor('+');
        outer.SpacePriority = -2;
        temple.PlaceRoom(0, 0, outer);
        temple.EdgeWalls('#', outer);


        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------


        int w = Random.Range(9, 12);
        int h = Random.Range(10, 16);

        // EntryHall
        temple.TryGrowRect(1, outer.Outer.GetCenter().y, w, h, out GenRect EntrySize, false);
        GenRoom EntryHall = GenRoom.At(EntrySize.MinX, EntrySize.MinY, EntrySize.WidthT, EntrySize.HeightT);

        EntryHall.FillFloor('.');
        temple.PlaceRoom(EntrySize.MinX, EntrySize.MinY, EntryHall);
        temple.EdgeWalls('#');
        EntryHall.GetAtWorldspaceG(
            EntrySize.MinX + 1, EntrySize.GetCenter().y)
        .Details
        .Add(new GenDetail()
        {
            Char = '>', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.StairsDown
        });


        int posX = EntrySize.MinX + 2;
        int posy = EntrySize.MinY + 2;

        GenTile[,] sym = GenUtil.GetSymetry(pillars.GetCopy(), ref posX, ref posy, EntryHall, GenUtil.Axis.Horizontal | GenUtil.Axis.Vertical);

        EntryHall.PlaceDetailsAt(posX, posy, sym);
        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // hall to big thing
        int whall = Random.Range(10, 25);
        int hhall = Random.Range(5, 7);
        int space = Random.Range(2, 4);

        temple.TryGrowRect(EntrySize.MaxX + 1, EntrySize.GetCenter().y, whall, hhall, out GenRect HallSize);
        GenRoom PillarHall = GenRoom.Sized(HallSize.WidthT, HallSize.HeightT);

        PillarHall.FillFloor('.');
        PillarHall.SpacePriority = 3;
        temple.PlaceRoom(HallSize.MinX, HallSize.MinY, PillarHall);
        temple.EdgeWalls('#', PillarHall);

        NoAutoDoor.Add(PillarHall);

        // place doors to the entry
        if (hhall == 5)
        {
            // a single door in the middle
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 2, GenTile.Copy(Door));
        }
        else
        {
            // place symetric doors
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 3, GenTile.Copy(Door));

            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 3, GenTile.Copy(Door));
        }

        int currBar = HallSize.MinX + space;

        GenTile[,] singlePillar = new GenTile[, ] {
            { GenTile.Copy(pillar) }
        };
        while (temple.IsInsideRoom(currBar, HallSize.MinY + 1, PillarHall))
        {
            int fx = currBar;
            int fy = HallSize.MinY + 1;
            GenTile[,] feature = GenUtil.GetSymetry(singlePillar, ref fx, ref fy, PillarHall, GenUtil.Axis.Vertical);
            PillarHall.PlaceDetailsAt(fx, fy, feature);
            currBar += space;
        }
        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // holy water or something

        int waterHeight      = Random.Range(2, 4);
        int waterWidth       = Random.Range(2, 4);
        int waterPillarWidth = Random.Range(2, 3);

        int waterRoomHeight = waterHeight + 4 + waterPillarWidth * 2;
        int waterRoomWidth  = waterWidth + 6 + waterPillarWidth * 2;

        temple.TryGrowRect(HallSize.MaxX + 1, HallSize.GetCenter().y, waterRoomWidth, waterRoomHeight, out GenRect WaterSize, false, GenUtil.Direction4.Top);

        GenRoom waterRoom = GenRoom.Sized(WaterSize.WidthT, WaterSize.HeightT);

        waterRoom.FillFloor();
        waterRoom.SpacePriority = 2;
        temple.PlaceRoom(WaterSize.MinX, WaterSize.MinY, waterRoom);
        temple.EdgeWalls('#', waterRoom);


        int BackDoorWater = Random.Range(1, waterRoom.Height / 2);

        waterRoom.AddDetails(WaterSize.MaxX, WaterSize.MinY + BackDoorWater, GenTile.Copy(Door));
        waterRoom.AddDetails(WaterSize.MaxX, WaterSize.MaxY - BackDoorWater, GenTile.Copy(Door));


        GenTile waterSingle = GenTile.GetEmpty();

        waterSingle.Details.Add(new GenDetail()
        {
            Char = '~', Type = GenDetail.DetailType.Background
        });
        GenTile[,] water = GenUtil.Fill(waterWidth, waterHeight, waterSingle);

        waterRoom.PlaceDetailsAt(WaterSize.MinX + 3 + waterPillarWidth, WaterSize.MinY + 2 + waterPillarWidth, water);

        int waterPX = WaterSize.MinX + 3;
        int waterPY = WaterSize.MinY + 2;

        GenTile[,] waterPillarPlace = GenUtil.GetSymetry(pillars.GetCopy(), ref waterPX, ref waterPY, waterRoom, GenUtil.Axis.Horizontal | GenUtil.Axis.Vertical);
        waterRoom.PlaceDetailsAt(waterPX, waterPY, waterPillarPlace);


        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // pillar spam
        int spamWidth  = Random.Range(10, 20);
        int spamHeight = WaterSize.HeightT + Random.Range(8, 15);

        temple.TryGrowRect(WaterSize.MaxX + 1, WaterSize.GetCenter().y, spamWidth, spamHeight, out GenRect SpamSize, true, GenUtil.Direction4.Top);
        GenRoom Spam = GenRoom.Sized(SpamSize.WidthT, SpamSize.HeightT);

        Spam.FillFloor();
        Spam.SpacePriority = 1;
        temple.PlaceRoom(SpamSize.MinX, SpamSize.MinY, Spam);
        temple.EdgeWalls('#', Spam);

        int spamPX = SpamSize.MinX + 2;
        int spamPY = SpamSize.MinY + 2;

        for (int x = spamPX; temple.IsInsideRoom(x, spamPY, Spam); x += 2)
        {
            for (int y = spamPY; temple.IsInsideRoom(x, y, Spam); y += 2)
            {
                GenTile p = GenTile.Copy(pillar);
                Spam.AddDetails(x, y, p);
            }
        }
        Spam.AddDetail(
            SpamSize.MaxX - 1,
            SpamSize.GetCenter().y,
            new GenDetail()
        {
            Char = '<', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.StairsUp
        });

        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        //temple.Rooms.Remove(outer); // we dont have boundries
        for (int x = outer.Inner.MinX; x < outer.Outer.MaxX; x++)
        {
            for (int y = outer.Inner.MinY; y < outer.Outer.MaxY; y++)
            {
                outer.RemoveTileAtG(x, y);
            }
        }


        //GenRoom Mark = GenRoom.Sized(0, 0);
        //Mark.FillFloor('X');
        //Mark.SpacePriority = 100;


        // lets go ham with randomly sized rooms
        int spawnAttemptsRemaining = 1000;

        while (spawnAttemptsRemaining-- > 0)// lol the arrow
        {
            int rWidth  = Random.Range(RandomWidth.start, RandomWidth.end);
            int rHeight = Random.Range(RandomHeight.start, RandomHeight.end);

            int     rX        = Random.Range(2, temple.Width - 2);
            int     rY        = Random.Range(2, temple.Height - 2);
            GenRect rHopeSize = new GenRect(rX, rX + rWidth + 1, rY, rY + rWidth - 1);


            if (temple.IsInsideRoom(rX, rY) || temple.GetTile(rX, rY) != null)
            {
                continue;
            }

            temple.TryGrowRect(rX, rY, rWidth, rHeight, out GenRect rSize, true);

            GenRoom add = GenRoom.Sized(rSize.WidthT, rSize.HeightT);
            add.FillFloor();
            add.SpacePriority = 01;

            temple.PlaceRoom(rSize.MinX, rSize.MinY, add);

            AutoFillRoom.Add(add);

            temple.EdgeWalls('#', add);

            temple.FixOverlap();

            /*
             * if (rWidth * 2 < rHeight || rHeight * 2 < rWidth)
             * {
             *  if (Random.Range(0,10)>4)
             *  {
             *      // we are making a hallway
             *
             *      //TODO: hallway
             *
             *      temple.PlaceRoom(rX, rY, Mark);
             *      Log(temple);
             *      if (Logging!=null)
             *  {
             *      yield return new WaitForSeconds(0.25f);
             *  }
             *      temple.Rooms.Remove(Mark);
             *      continue;
             *  }
             * }
             */

            /*
             * int randomChance = Random.Range(0, 4);
             * switch (randomChance)
             * {
             *  case 0:
             *      // random pillars in the room
             *
             *      for (int i = 0; i < 7 + (rSize.WidthT + rSize.HeightT)/5; i++)
             *      {
             *          int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *          int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *          add.AddDetails(px, py, pillar);
             *      }
             *
             *      break;
             *  case 1:
             *      // random water
             *      for (int i = 0; i < 15 + (rSize.WidthT + rSize.HeightT)/3; i++)
             *      {
             *          int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *          int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *          GenDetail littleWater= new GenDetail() { Char = '~', Type = GenDetail.DetailType.Background};
             *          add.AddDetail(px, py, littleWater);
             *      }
             *      break;
             *  case 2:
             *      // random room inside if possible else empty
             *      if (rSize.WidthT>=7&& rSize.HeightT >= 7)
             *      {
             *          int insideX = rSize.GetCenter().x;
             *          int insideY = rSize.GetCenter().y;
             *
             *          temple.TryGrowRect(insideX, insideY, 100, 100, out GenRect insideSize, false);
             *          GenRoom inside = GenRoom.Sized(insideSize.WidthT, insideSize.HeightT);
             *          inside.FillFloor();
             *          inside.SpacePriority = 2;
             *          temple.PlaceRoom(insideSize.MinX, insideSize.MinY, inside);
             *          temple.EdgeWalls('#',inside);
             *          temple.FixOverlap();
             *
             *      }
             *      else
             *      {
             *          for (int i = 0; i < 7; i++)
             *          {
             *              int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *              int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *              add.AddDetails(px, py, pillar);
             *          }
             *      }
             *      break;
             *  default:
             *      break;
             * }
             *
             * Log(temple);
             * if (Logging!=null)
             *  {
             *      yield return new WaitForSeconds(0.25f);
             *  }
             */
        }

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // now fill the rooms with things

        var adjList = temple.GetAdjacentRoomMap();
        // remove any Room that is too small and have no connections

        List <GenRoom> tooSmall = new List <GenRoom>();

        foreach (var room in temple.Rooms)
        {
            if (room.Width >= 5 && room.Height == 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (room.Height >= 5 && room.Width == 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (room.Height <= 3 && room.Width <= 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (adjList[room].Count == 0)
            {
                tooSmall.Add(room);
                continue;
            }
        }
        foreach (var room in tooSmall)
        {
            temple.Rooms.Remove(room);
        }

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        List <GenRoom> PotentialSecret = new List <GenRoom>();

        foreach (var room in temple.Rooms)
        {
            if (room.Width + room.Height <= 12)
            {
                PotentialSecret.Add(room);
            }
        }

        Debug.Log("potential " + PotentialSecret.Count + "Secret rooms");

        // 1 room --> 0,1,2,3
        // 2 room --> 4,5
        int SecretCount = Mathf.Min(Mathf.FloorToInt(Mathf.Sqrt(Random.Range(1, 6))), PotentialSecret.Count); // this goes to 5

        Debug.Log(SecretCount + " Secret rooms chosen");
        foreach (var secret in PotentialSecret.GetRandom(SecretCount))
        {
            // we get random door
            // add a chest
            // remove it from door spawn
            GenPositionTile entry = temple.GetDoorableTiles(secret.GetAllTiles()).GetRandom();
            secret.AddDetail(entry.PositionG.x, entry.PositionG.y,
                             new GenDetail()
            {
                Char = '*', Entity = GenDetail.EntityType.Door, Type = GenDetail.DetailType.Door
            });

            GenPositionTile myChest = secret
                                      .GetAllTiles()
                                      .Where(t => temple.IsInsideRoom(t.PositionG.x, t.PositionG.y, secret) && temple.IsCornerGR(t.PositionG.x, t.PositionG.y, secret))
                                      .ToList()
                                      .GetRandom();
            secret.AddDetails(myChest.PositionG.x, myChest.PositionG.y, GenTile.Copy(Chest));

            AutoFillRoom.Remove(secret);
            SecretRooms.Add(secret);
            NoAutoDoor.Add(secret);
        }
        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // go through all other rooms and determin what they are

        foreach (GenRoom room in AutoFillRoom)
        {
            // -----------
            Log(temple);
            if (Logging != null)
            {
                yield return(new WaitForSeconds(0.25f));
            }
            // -----------

            // pillar hallway
            if (room.Height <= 7 && room.Height >= 5 && room.Width > 6)
            {
                // potential horizontal hallway
                if (Random.value < 0.4f)
                {
                    // hallway confirmed
                    // left to right

                    GenTile[,] p = new GenTile[, ]
                    {
                        { GenTile.Copy(pillar) }
                    };
                    int spacing = Random.Range(2, 5);

                    int tmpX = room.Outer.MinX + spacing;
                    int tmpY = room.Outer.MinY + 1;


                    p = GenUtil.GetSymetry(p, ref tmpX, ref tmpY, room, GenUtil.Axis.Vertical);

                    while (temple.IsInsideRoom(tmpX, tmpY, room))
                    {
                        room.PlaceDetailsAt(tmpX, tmpY, p);

                        tmpX = tmpX + spacing;
                    }
                    int enemyCount = Random.Range(0, 4);
                    for (int i = 0; i < enemyCount; i++)
                    {
                        SpawnEnemy(temple, room);
                    }
                    int itemCount = Random.Range(-1, 3);
                    for (int i = 0; i < itemCount; i++)
                    {
                        SpawnItem(temple, room, true);
                    }
                    int chestCount = Random.Range(-2, 2);
                    for (int i = 0; i < chestCount; i++)
                    {
                        SpawnChest(temple, room, true);
                    }
                    continue;
                }
            }
            if (room.Width <= 7 && room.Width >= 5 && room.Height > 6)
            {
                // potential horizontal hallway
                if (Random.value < 0.4f)
                {
                    // hallway confirmed
                    // left to right

                    GenTile[,] p = new GenTile[, ]
                    {
                        { GenTile.Copy(pillar) }
                    };
                    int spacing = Random.Range(2, 5);

                    int tmpX = room.Outer.MinX + 1;
                    int tmpY = room.Outer.MinY + spacing;


                    p = GenUtil.GetSymetry(p, ref tmpX, ref tmpY, room, GenUtil.Axis.Horizontal);

                    while (temple.IsInsideRoom(tmpX, tmpY, room))
                    {
                        room.PlaceDetailsAt(tmpX, tmpY, p);

                        tmpY = tmpY + spacing;
                    }
                    int enemyCount = Random.Range(0, 4);
                    for (int i = 0; i < enemyCount; i++)
                    {
                        SpawnEnemy(temple, room);
                    }
                    int itemCount = Random.Range(-1, 3);
                    for (int i = 0; i < itemCount; i++)
                    {
                        SpawnItem(temple, room, true);
                    }
                    int chestCount = Random.Range(-2, 2);
                    for (int i = 0; i < chestCount; i++)
                    {
                        SpawnChest(temple, room, true);
                    }
                    continue;
                }
            }

            if (room.Height >= 8 && room.Width >= 8)
            {
                // can either be pillar spam or room in room

                if (Random.value < 0.6f)
                {
                    if (Random.value < 0.7f && room.Width % 2 == 1 && room.Height % 2 == 1)
                    {
                        // pillar spam

                        for (int x = 2; x < room.Width - 2; x += 2)
                        {
                            for (int y = 2; y < room.Height - 2; y += 2)
                            {
                                room.AddDetails(room.PosX + x, room.PosY + y, GenTile.Copy(pillar));
                            }
                        }
                        int enemyCount = Random.Range(0, 5);
                        for (int i = 0; i < enemyCount; i++)
                        {
                            SpawnEnemy(temple, room);
                        }
                        int itemCount = Random.Range(-1, 3);
                        for (int i = 0; i < itemCount; i++)
                        {
                            SpawnItem(temple, room, true);
                        }
                        int chestCount = Random.Range(-3, 3);
                        for (int i = 0; i < chestCount; i++)
                        {
                            SpawnChest(temple, room, true);
                        }
                    }
                    else
                    {
                        // room in room

                        // find where to put the inner room
                        temple.TryGrowRect(room.Inner.GetCenter().x, room.Inner.GetCenter().y, 100, 100, out GenRect InnerSize);


                        if (InnerSize.WidthT >= 4 && InnerSize.HeightT >= 4)
                        {
                            if (InnerSize.WidthT >= 10 || InnerSize.HeightT >= 10)
                            {
                                if (Mathf.Abs(InnerSize.WidthT - InnerSize.HeightT) > 3)
                                {
                                    // we want to divide
                                    if (InnerSize.WidthT > InnerSize.HeightT)
                                    {
                                        // divide left and right
                                        int singleWidth = InnerSize.WidthT / 2 - 2;
                                        // left
                                        GenRect LeftRoom = new GenRect(InnerSize.MinX, InnerSize.MinX + singleWidth, InnerSize.MinY, InnerSize.MaxY);
                                        // right
                                        GenRect RightRoom = new GenRect(InnerSize.MaxX - singleWidth, InnerSize.MaxX, InnerSize.MinY, InnerSize.MaxY);

                                        GenRoom left = GenRoom.Sized(LeftRoom.WidthT, LeftRoom.HeightT);
                                        left.FillFloor();
                                        left.SpacePriority = 4;
                                        GenRoom right = GenRoom.Sized(RightRoom.WidthT, RightRoom.HeightT);
                                        right.FillFloor();
                                        right.SpacePriority = 4;
                                        temple.PlaceRoom(LeftRoom.MinX, LeftRoom.MinY, left);
                                        temple.PlaceRoom(RightRoom.MinX, RightRoom.MinY, right);

                                        NoAutoDoor.Add(left);
                                        NoAutoDoor.Add(right);

                                        temple.EdgeWalls('#', left);
                                        temple.EdgeWalls('#', right);

                                        temple.FixOverlap();
                                        // -----------
                                        Log(temple);
                                        if (Logging != null)
                                        {
                                            yield return(new WaitForSeconds(0.25f));
                                        }
                                        // -----------

                                        var leftDoor  = temple.GetDoorableTiles(left.GetAllTiles()).GetRandom(1);
                                        var rightDoor = temple.GetDoorableTiles(right.GetAllTiles()).GetRandom(1);

                                        for (int i = 0; i < leftDoor.Count; i++)
                                        {
                                            left.AddDetails(leftDoor[i].PositionG.x, leftDoor[i].PositionG.y, GenTile.Copy(Door));
                                        }
                                        for (int i = 0; i < rightDoor.Count; i++)
                                        {
                                            right.AddDetails(rightDoor[i].PositionG.x, rightDoor[i].PositionG.y, GenTile.Copy(Door));
                                        }
                                        SpawnItem(temple, left);
                                        SpawnItem(temple, right);
                                        if (Random.value < 0.4f)
                                        {
                                            SpawnItem(temple, right);
                                        }
                                        if (Random.value < 0.4f)
                                        {
                                            SpawnItem(temple, left);
                                        }
                                        if (Random.value < 0.2f)
                                        {
                                            SpawnChest(temple, left, true);
                                        }
                                        if (Random.value < 0.2f)
                                        {
                                            SpawnChest(temple, left, true);
                                        }
                                    }
                                    else
                                    {
                                        // divide top bot
                                        Debug.Log("currently not implemented, sorry");
                                    }
                                }
                            }
                            else
                            {
                                // one single room
                                if (InnerSize.WidthT > 5)
                                {
                                    InnerSize = InnerSize.Transform(-1, 0, -1, 0);
                                }
                                if (InnerSize.HeightT > 5)
                                {
                                    InnerSize = InnerSize.Transform(0, -1, 0, -1);
                                }

                                Debug.Log("HERE");

                                GenRoom single = GenRoom.Sized(InnerSize.WidthT, InnerSize.HeightT);
                                single.SpacePriority = 4;
                                single.FillFloor();
                                NoAutoDoor.Add(single);

                                temple.PlaceRoom(InnerSize.MinX, InnerSize.MinY, single);
                                temple.EdgeWalls('#', single);
                                temple.FixOverlap();
                                // -----------
                                Log(temple);
                                if (Logging != null)
                                {
                                    yield return(new WaitForSeconds(0.25f));
                                }
                                // -----------



                                // double doors
                                var doorables = single.GetAllTiles();// single.GetEdge().ToList();
                                var theDoors  = temple.GetDoorableTiles(doorables).GetRandom(2);

                                for (int i = 0; i < theDoors.Count; i++)
                                {
                                    single.AddDetails(theDoors[i].PositionG.x, theDoors[i].PositionG.y, GenTile.Copy(Door));
                                }

                                SpawnItem(temple, single);

                                if (Random.value < 0.2f)
                                {
                                    SpawnChest(temple, single, true);
                                }
                                if (Random.value < 0.2f)
                                {
                                    SpawnChest(temple, single, true);
                                }
                            }
                        }

                        SpawnEnemy(temple, room);
                        if (Random.value < 0.5f)
                        {
                            SpawnEnemy(temple, room);
                        }
                        if (Random.value < 0.2f)
                        {
                            SpawnEnemy(temple, room);
                        }
                    }
                    continue;
                }
            }
            // something random
            //room.FillFloor('~');

            SpawnEnemy(temple, room);
            SpawnEnemy(temple, room);

            if (Random.value < 0.5f)
            {
                SpawnEnemy(temple, room);
            }
            if (Random.value < 0.2f)
            {
                SpawnEnemy(temple, room);
            }
            SpawnItem(temple, room);
            if (Random.value < 0.3f)
            {
                SpawnItem(temple, room);
            }
            if (Random.value < 0.3f)
            {
                SpawnItem(temple, room);
            }
            if (Random.value < 0.4f)
            {
                SpawnChest(temple, room);
            }
            if (Random.value < 0.1f)
            {
                SpawnChest(temple, room);
            }
        }


        List <GenRoom> RequireDoor = new List <GenRoom>(temple.Rooms);

        foreach (var doo in NoAutoDoor)
        {
            RequireDoor.Remove(doo);
        }
        List <GenRoom> DoorIteration = new List <GenRoom>(RequireDoor);
        GenRoom        start         = EntryHall;

        Dictionary <GenRoom, List <GenRoom> > adj = temple.GetAdjacentRoomMap();

        void RandomDoorTo(GenRoom a, GenRoom b)
        {
            var tiles    = temple.GetDoorableTiles(temple.GetConnectingTiles(a, b));
            var location = tiles.GetRandom();

            a.AddDetails(location.PositionG.x, location.PositionG.y, GenTile.Copy(Door));
        }

        while (RequireDoor.Count > 0)
        {
            DoorIteration.Clear();
            DoorIteration.AddRange(RequireDoor);
            foreach (var room in DoorIteration)
            {
                if (temple.IsReachable(start, room))
                {
                    // reachable so we dont have to do a thing
                    RequireDoor.Remove(room);
                }
                else
                {
                    // place random door
                    var available = adj[room];
                    RandomDoorTo(room, available.GetRandom());
                }
                // -----------
                Log(temple);
                if (Logging != null)
                {
                    yield return(new WaitForSeconds(0.1f));
                }

                // -----------
            }
        }


        foreach (var room in adj[Spam].GetRandom(2))
        {
            RandomDoorTo(Spam, room);
        }

        Log(temple);
        Debug.Log("Done");


        LastOutput = GenUtil.Print(temple, false);
        Done?.Invoke();
    }
Ejemplo n.º 7
0
    public IEnumerator GrowTest()
    {
        TestDrawer.text    = "Grow Test";
        GenUtil.PrintCount = 0;

        GenData growArea = new GenData(40, 25);

        GenRoom left = GenRoom.Sized(10, 15);

        left.FillFloor('.');
        growArea.PlaceRoom(0, 0, left);


        GenRoom right = GenRoom.Sized(10, 15);

        right.FillFloor('.');
        growArea.PlaceRoom(11, 0, right);

        growArea.EdgeWalls('#');


        TestDrawer.text = growArea.Print(false);
        yield return(new WaitForSeconds(1f));



        for (int x = 0; x < 8; x++)
        {
            for (int y = 0; y < 13; y++)
            {
                {
                    TestDrawer.text = growArea.Print(false);
                    //yield return new WaitForSeconds(0.05f);

                    bool sucL = growArea.TryGrowRect(1 + x, 1 + y, 5, 6, out GenRect oL, true);

                    GenRoom resultL = GenRoom.Sized(oL.WidthT, oL.HeightT);
                    resultL.FillFloor('O');
                    growArea.PlaceRoom(oL.MinX, oL.MinY, resultL);
                    growArea.EdgeWalls('#');


                    bool sucR = growArea.TryGrowRect(12 + x, 1 + y, 5, 6, out GenRect oR, false);

                    GenRoom resultR = GenRoom.Sized(oR.WidthT, oR.HeightT);
                    resultR.FillFloor('O');
                    growArea.PlaceRoom(oR.MinX, oR.MinY, resultR);
                    growArea.EdgeWalls('#');



                    GenRoom dotL = GenRoom.Sized(1, 1);
                    dotL.FillFloor('+');
                    growArea.PlaceRoom(1 + x, 1 + y, dotL);

                    GenRoom dotR = GenRoom.Sized(1, 1);
                    dotR.FillFloor('X');
                    growArea.PlaceRoom(12 + x, 1 + y, dotR);


                    TestDrawer.text = growArea.Print(false);
                    yield return(new WaitForSeconds(0.50f));



                    growArea.Rooms.Remove(dotR);
                    growArea.Rooms.Remove(dotL);
                    growArea.Rooms.Remove(resultL);
                    growArea.Rooms.Remove(resultR);
                }
            }
        }

        /*
         * for (int x = 0; x < 8; x++)
         * {
         *  for (int y = 0; y < 13; y++)
         *  {
         *
         *      {
         *          TestDrawer.text = growArea.Print(false);
         *          //yield return new WaitForSeconds(0.05f);
         *
         *          bool suc = growArea.TryGrowRect(3 + x, 3 + y, 5, 6, out GenRect o, false);
         *
         *          GenRoom result = GenRoom.Sized(o.WidthT, o.HeightT);
         *          result.FillFloor('O');
         *          growArea.PlaceRoom(o.MinX, o.MinY, result);
         *          growArea.EdgeWalls('#');
         *
         *          GenRoom dot = GenRoom.Sized(1, 1);
         *          dot.FillFloor('X');
         *          growArea.PlaceRoom(3 + x, 3 + y, dot);
         *
         *          TestDrawer.text = growArea.Print(false);
         *          yield return new WaitForSeconds(0.50f);
         *
         *          growArea.Rooms.Remove(dot);
         *          growArea.Rooms.Remove(result);
         *      }
         *  }
         * }
         *
         */
    }
Ejemplo n.º 8
0
    public IEnumerator RunGenerationTest()
    {
        GenUtil.PrintCount = 0;
        GenData sym = new GenData(20, 15);

        GenRoom Hallway = GenRoom.Sized(15, 5);

        Hallway.FillFloor('.');
        Hallway.SpacePriority = 2;
        sym.PlaceRoom(1, 1, Hallway);

        TestDrawer.text = sym.Print(false);
        yield return(new WaitForSeconds(1f));


        GenRoom OtherRooom = GenRoom.Sized(8, 10);

        OtherRooom.FillFloor('.');
        OtherRooom.SpacePriority = 3;
        sym.PlaceRoom(11, 3, OtherRooom);

        TestDrawer.text = sym.Print(false);
        yield return(new WaitForSeconds(1f));

        sym.EdgeWalls('#');

        TestDrawer.text = sym.Print(false);
        yield return(new WaitForSeconds(1f));

        OtherRooom.SpacePriority = 1;
        sym.FixOverlap();

        TestDrawer.text = sym.Print(false);
        yield return(new WaitForSeconds(1f));



        int wantX = 3;
        int wantY = 2;

        bool done = false;

        while (!done)
        {
            var got = Hallway.GetAtWorldspaceG(wantX, wantY);

            if (!sym.IsInsideRoom(wantX, wantY))
            {
                done = true;
            }
            else
            {
                GenTile tile = GenTile.GetEmpty();
                tile.Details.Add(new GenDetail()
                {
                    Type = GenDetail.DetailType.Decoration, Char = 'O'
                });
                GenTile[,] feature = new GenTile[, ]
                {
                    { tile }
                };

                int fposX = wantX;
                int fposY = wantY;

                GenTile[,] final = GenUtil.GetSymetry(feature, ref fposX, ref fposY, Hallway, GenUtil.Axis.Vertical);

                Hallway.SetTilesAtG(fposX, fposY, final);

                TestDrawer.text = sym.Print(false);
                yield return(new WaitForSeconds(0.5f));


                wantX += 2;
            }
        }

        for (int x = 0; x < 20; x++)
        {
            for (int y = 0; y < 15; y++)
            {
                if (sym.IsCornerG(x, y, GenDetail.DetailType.Wall, GenDetail.DetailType.Decoration))
                {
                    GenRoom corner = GenRoom.Sized(1, 1);
                    corner.FillFloor('X');
                    sym.PlaceRoom(x, y, corner);

                    TestDrawer.text = sym.Print(false);
                    yield return(new WaitForSeconds(0.25f));
                }
            }
        }



        /*
         * GenData data = new GenData(40, 20);
         *
         * GenRoom startRoom = GenRoom.Sized(5,8,true);
         * startRoom.SpacePriority = 0;
         *
         * GenRoom room2 = GenRoom.Sized(8, 8, true);
         * room2.FillFloor('a');
         *
         * GenRoom room3 = GenRoom.Sized(5, 5, true);
         * room3.FillFloor('b');
         * room3.SpacePriority = 2;
         *
         * GenRoom room4 = GenRoom.Sized(10, 10, true);
         * room4.FillFloor('c');
         *
         * data.PlaceRoom(1, 0, startRoom);
         * data.PlaceRoom(4, 1, room2);
         * data.PlaceRoom(25, 11, room3);
         * data.PlaceRoom(23, 3, room4);
         *
         * data.FixOverlap();
         * data.EdgeWalls('#');
         *
         * data.Print(false);
         */
    }
Ejemplo n.º 9
0
 public GenVertex(GenRoom r)
 {
     this.r = r;
     value  = float.PositiveInfinity;
 }
Ejemplo n.º 10
0
    public static Dungeon GenerateDungeon(Quest quest, int seed = 0)
    {
        if (seed != 0)
        {
            Random.InitState(seed);
        }

        string[] lengthes = new string[] { "", "short", "medium", "long" };

        Dungeon dungeon = new Dungeon();
        DungeonGenerationData genData = DarkestDungeonManager.Data.DungeonGenerationData.Find(item =>
                                                                                              item.Dungeon == quest.Dungeon &&
                                                                                              item.Length == lengthes[quest.Length] &&
                                                                                              item.QuestType == quest.Type);
        DungeonEnviromentData envData = DarkestDungeonManager.Data.DungeonEnviromentData[quest.Dungeon];

        int RoomsLeft = genData.BaseRoomNumber;
        int HallsLeft = genData.BaseCorridorNumber;
        int xSize     = genData.GridSizeX;
        int ySize     = genData.GridSizeY;

        dungeon.GridSizeX = xSize;
        dungeon.GridSizeY = ySize;

        List <GenRoom> Areas = new List <GenRoom>();

        GenRoom[,] areaGrid = new GenRoom[xSize, ySize];

        GenerateRooms(Areas, areaGrid, RoomsLeft, xSize, ySize);
        GenRoom hub = GetHub(Areas);

        List <GenRoom> ExistingRooms = ForceBorderRooms(Areas, hub, RoomsLeft);
        List <GenHall> ExistingHalls = ForceHallConnection(Areas, hub, ExistingRooms, HallsLeft);

        dungeon.Rooms    = GetFinalRooms(ExistingRooms, genData);
        dungeon.Hallways = GetFinalHallways(dungeon, ExistingHalls, genData);

        MarkEntrance(dungeon);
        switch (quest.Goal.Type)
        {
        case "kill_monster":
            if (quest.Goal.QuestData is QuestKillMonsterData)
            {
                var bossData = quest.Goal.QuestData as QuestKillMonsterData;
                envData.BattleMashes.Find(mash => mash.BossEncounters.Find(encounter =>
                                                                           encounter.MonsterSet.Contains(bossData.MonsterNameIds[0])) != null);
                var bossGenRoom = LongestPathRoom(ExistingRooms.Find(room => room.Id == dungeon.StartingRoomId), ExistingRooms);
                var bossRoom    = dungeon.Rooms[bossGenRoom.Id];
                bossRoom.Type = AreaType.Boss;
                var bossEncounter = envData.BattleMashes.Find(mash => mash.MashId == quest.Difficulty).
                                    BossEncounters.Find(encounter => encounter.MonsterSet.Contains(bossData.MonsterNameIds[0]));
                bossRoom.BattleEncounter = new BattleEncounter(bossEncounter.MonsterSet);
            }
            else
            {
                Debug.LogError("Missing boss data in dungeon!");
            }
            break;

        case "activate":
            if (quest.Goal.QuestData is QuestActivateData)
            {
                var activateData = quest.Goal.QuestData as QuestActivateData;
                var lastRoom     = LongestPathRoom(ExistingRooms.Find(room => room.Id == dungeon.StartingRoomId), ExistingRooms);
                for (int i = 0; i < activateData.Amount; i++)
                {
                    var availableRooms = ExistingRooms.FindAll(room =>
                                                               room.MinPath >= (float)i / activateData.Amount * lastRoom.MinPath &&
                                                               room.MinPath <= (float)(i + 1) / activateData.Amount * lastRoom.MinPath);
                    int randomRoom = Random.Range(0, availableRooms.Count - 1);
                    var questRoom  = dungeon.Rooms[availableRooms[randomRoom].Id];
                    if (questRoom.Type == AreaType.Empty)
                    {
                        var curio = new Curio(activateData.CurioName);
                        curio.IsQuestCurio = true;

                        if (quest.Goal.StartingItems.Count > 0)
                        {
                            curio.ItemInteractions.Add(new ItemInteraction()
                            {
                                Chance     = 1,
                                ItemId     = quest.Goal.StartingItems[0].Id,
                                ResultType = "loot",
                                Results    = new List <CurioResult>(),
                            });
                        }

                        questRoom.Type = AreaType.Curio;
                        questRoom.Prop = curio;
                    }
                    else
                    {
                        i--;
                    }
                }
            }
            break;

        case "gather":
            if (quest.Goal.QuestData is QuestGatherData)
            {
                var gatherData = quest.Goal.QuestData as QuestGatherData;
                var lastRoom   = LongestPathRoom(ExistingRooms.Find(room => room.Id == dungeon.StartingRoomId), ExistingRooms);
                for (int i = 0; i < gatherData.Item.Amount; i++)
                {
                    var availableRooms = ExistingRooms.FindAll(room =>
                                                               room.MinPath >= (float)i / gatherData.Item.Amount * lastRoom.MinPath &&
                                                               room.MinPath <= (float)(i + 1) / gatherData.Item.Amount * lastRoom.MinPath);
                    int randomRoom = Random.Range(0, availableRooms.Count - 1);
                    var questRoom  = dungeon.Rooms[availableRooms[randomRoom].Id];
                    if (questRoom.Type == AreaType.Empty)
                    {
                        var curio = new Curio(gatherData.CurioName);
                        curio.IsQuestCurio = true;

                        var curioInteraction = new CurioInteraction();
                        curioInteraction.Chance     = 1;
                        curioInteraction.ResultType = "loot";
                        curioInteraction.Results    = new List <CurioResult>();
                        curioInteraction.Results.Add(new CurioResult()
                        {
                            Chance = 1,
                            Draws  = 1,
                            Item   = gatherData.Item.Id,
                        });
                        curio.Results.Add(curioInteraction);
                        questRoom.Type = AreaType.Curio;
                        questRoom.Prop = curio;
                    }
                    else
                    {
                        i--;
                    }
                }
            }
            break;

        default:
            break;
        }
        PopulateRooms(dungeon, genData);
        LoadRoomEnviroment(dungeon, envData, quest.Difficulty);
        PopulateHalls(dungeon, genData);
        LoadHallEnviroment(dungeon, envData, quest.Difficulty);

        dungeon.GridSizeX   = 1 + (xSize - 1) * 7;
        dungeon.GridSizeY   = 1 + (ySize - 1) * 7;
        dungeon.Name        = quest.Dungeon;
        dungeon.DungeonMash = envData.BattleMashes.Find(mash => mash.MashId == quest.Difficulty);
        dungeon.SharedMash  = DarkestDungeonManager.Data.DungeonEnviromentData["shared"].
                              BattleMashes.Find(mash => mash.MashId == quest.Difficulty);
        return(dungeon);
    }
Ejemplo n.º 11
0
    public int genGateEvent(GenRoom newRoom, int direction)
    {
        // prepare event to open the gate
        // before everything start, lets check if any monsters
        int gateOpenMethod;
        List <GenMonster> targetMonsters = new List <GenMonster>();

        if (newRoom.monsters == null)
        {
            gateOpenMethod = 0;

            // TODO: add chance to trigger/treasure open gate event here (or not here? need a better flow)
        }
        else
        {
            // lets check how many target monster here
            for (int i = 0; i < newRoom.monsters.Length; i++)
            {
                // lets assume monsterObjId 1 as target monster
                if (newRoom.monsters[i].monsterObjId == 1)
                {
                    targetMonsters.Add(newRoom.monsters[i]);
                }
            }
            // currently there should be three type of method to open gate
            gateOpenMethod = randomGen(new int[] { 0, 1 });
            if (targetMonsters.Count > 0)
            {
                // kill specific monsters can only be done when target monsters exists
                gateOpenMethod = randomGen(new int[] { 1, 2 });
            }
        }
        switch (gateOpenMethod)
        {
        case 0:
        {
            // if no monster, gate must be opened already, so add an event on level start
//          GenEvent gateOpeningEvent = new GenEvent();
//          gateOpeningEvent.triggerTypeId = GenEvent.TriggerType.LEVEL_ENTER;
//          gateOpeningEvent.results = new GenEventResult[1];
//          gateOpeningEvent.results[0] = new GenEventResult();
//          gateOpeningEvent.results[0].resultTypeId = GenEvent.ResultType.GATE_OPEN;
//          gateOpeningEvent.results[0].resultParams = new float[]{currentWorkingLevel.levelId, newRoom.roomId, direction};
//
//          currentWorkingLevel.events.Add(gateOpeningEvent);
        }
        break;

        // 1) kill all monsters
        // Event setting: all monster will add 1 to a global variable when being killed
        //					when that global variable reach the number of monsters, trigger an event to open the gate
        case 1:
        {
            // 1. set monster event, when die, add a counter
            GenVariable newVar = new GenVariable();
            newVar.variableId = variablesCounter++;
            newVar.initValue  = 0;
            variablesList.Add(newVar);

            // 2. Create an event that, when a monster dead, add up a counter
//          GenEvent monsterDieEvent = new GenEvent();
//          monsterDieEvent.triggerTypeId = GenEvent.TriggerType.MONSTER_DIE;
//          monsterDieEvent.results = new GenEventResult[1];
//          monsterDieEvent.results[0] = new GenEventResult();
//          monsterDieEvent.results[0].resultTypeId = GenEvent.ResultType.VAR_SET_AS_VAR_PLUS_NUM;
//          monsterDieEvent.results[0].resultParams = new float[]{newVar.variableId, newVar.variableId, 1f};
//
//          // 3. Create an event that, when a monster dead, check if thee counter is larger than or equal to room monster num, if yes then open the gate
//          GenEvent gateOpeningEvent = new GenEvent();
//          gateOpeningEvent.triggerTypeId = GenEvent.TriggerType.MONSTER_DIE;
//          gateOpeningEvent.conds = new GenEventCond[1];
//          gateOpeningEvent.conds[0] = new GenEventCond();
//          gateOpeningEvent.conds[0].condTypeId = GenEvent.CondType.LOGIC_LARGER_OR_EQUAL_NUM;
//          gateOpeningEvent.conds[0].condParams = new float[]{newVar.variableId, newRoom.monsters.Length};
//          gateOpeningEvent.results = new GenEventResult[1];
//          gateOpeningEvent.results[0] = new GenEventResult();
//          gateOpeningEvent.results[0].resultTypeId = GenEvent.ResultType.GATE_OPEN;
//          gateOpeningEvent.results[0].resultParams = new float[]{currentWorkingLevel.levelId, newRoom.roomId, direction};
//
//          // 4. now assign both event to every monster in room
//          for(int i=0;i<newRoom.monsters.Length;i++) {
//              if(newRoom.monsters[i].events == null) {
//                  newRoom.monsters[i].events = new List<GenEvent>();
//              }
//              newRoom.monsters[i].events.Add(monsterDieEvent);
//              newRoom.monsters[i].events.Add (gateOpeningEvent);
//          }
        }
        break;

        // 2) kill specific monsters
        // Event setting: similar to above, be the counter variable is not all monsters,
        //					and not all monsters have the triggering event
        case 2:
        {
            // 1. set monster event, when die, add a counter
            GenVariable newVar = new GenVariable();
            newVar.variableId = variablesCounter++;
            newVar.initValue  = 0;


            // 2. Create an event that, when a monster dead, add up a counter
//          GenEvent monsterDieEvent = new GenEvent();
//          monsterDieEvent.triggerTypeId = GenEvent.TriggerType.MONSTER_DIE;
//          monsterDieEvent.results = new GenEventResult[1];
//          monsterDieEvent.results[0] = new GenEventResult();
//          monsterDieEvent.results[0].resultTypeId = GenEvent.ResultType.VAR_SET_AS_VAR_PLUS_NUM;
//          monsterDieEvent.results[0].resultParams = new float[]{newVar.variableId, newVar.variableId, 1f};
//
//          // 3. Create an event that, when a monster dead, check if thee counter is larger than or equal to room monster num, if yes then open the gate
//          GenEvent gateOpeningEvent = new GenEvent();
//          gateOpeningEvent.triggerTypeId = GenEvent.TriggerType.MONSTER_DIE;
//          gateOpeningEvent.conds = new GenEventCond[1];
//          gateOpeningEvent.conds[0] = new GenEventCond();
//          gateOpeningEvent.conds[0].condTypeId = GenEvent.CondType.LOGIC_LARGER_OR_EQUAL_NUM;
//          gateOpeningEvent.conds[0].condParams = new float[]{newVar.variableId, targetMonsters.Count};
//          gateOpeningEvent.results = new GenEventResult[1];
//          gateOpeningEvent.results[0] = new GenEventResult();
//          gateOpeningEvent.results[0].resultTypeId = GenEvent.ResultType.GATE_OPEN;
//          gateOpeningEvent.results[0].resultParams = new float[]{currentWorkingLevel.levelId, newRoom.roomId, direction};
//
//          // 4. now assign both event to every monster in room
//          for(int i=0;i<targetMonsters.Count;i++) {
//              if(targetMonsters[i].events == null) {
//                  targetMonsters[i].events = new List<GenEvent>();
//              }
//              targetMonsters[i].events.Add(monsterDieEvent);
//              targetMonsters[i].events.Add (gateOpeningEvent);
//          }
        }
        break;

            // 3) use key
            // Event setting: TODO <--- seems need to expand data structure
        }

        return(gateOpenMethod);
    }
Ejemplo n.º 12
0
    public GenRoom genNextRoom(int x, int y, bool isMainline, bool isLastLevel = false, int length = 0, int incomeDirection = -1)
    {
        GenRoom newRoom = new GenRoom();

        newRoom.roomObjId = randomGen(roomIds);
        Room roomData = new Room(newRoom.roomObjId);

        newRoom.roomId = roomIdCounter++;
        int monsterNum = 0;

        // first calibrate the position
        if (incomeDirection != -1)
        {
            x -= roomData.gates [incomeDirection].pos.x;
            y -= roomData.gates [incomeDirection].pos.y;
        }
        else
        {
            x -= 8;
            y -= 8;
        }
        // check collision
        Rect newArea = new Rect(x, y, 16, 16);

        if (collisionCheck(newArea))
        {
            return(null);
        }
        occupiedArea.Add(newArea);

        // add monster to room
        // check if needed (not starting room)
        if (length == mainlineLength)
        {
            // starting room need character starting position
            //bool validPos = false;
            newRoom.charPosition = new Pos(5, 5);
//          while(!validPos) {
//              newRoom.charPosition.x = Random.Range (0, 13);
//              newRoom.charPosition.y = Random.Range (0, 13);
//              if(roomData.landscape[newRoom.charPosition.y][newRoom.charPosition.x] == 1) {
//                  validPos = true;
//              }
//          }
        }
        else if (length == 1)
        {
            // last room, let this be the teleport gate room
            newRoom.teleportGate = new GenTGate();
            newRoom.teleportGate.teleportGateObjId = 1;
            bool validPos = false;
            newRoom.teleportGate.position = new Pos(0, 0);
            while (!validPos)
            {
                newRoom.teleportGate.position.x = Random.Range(0, 13);
                newRoom.teleportGate.position.y = Random.Range(0, 13);
                if (roomData.landscape[newRoom.teleportGate.position.y][newRoom.teleportGate.position.x] == 1)
                {
                    validPos = true;
                }
            }
            if (isLastLevel)
            {
                newRoom.teleportGate.target = "boss";
            }
            else
            {
                newRoom.teleportGate.target = "level";
            }
        }
        // else {
        // random number of monsters
        monsterNum       = maxMonsterNum;// randomGen(monsterNums);
        newRoom.monsters = new GenMonster[monsterNum];
        for (int i = 0; i < monsterNum; i++)
        {
            // get a position
            // TODO: stop using silly method
            bool validPos = false;
            Pos  position = new Pos(0, 0);

            while (!validPos)
            {
                position.x = Random.Range(0, 13);
                position.y = Random.Range(0, 13);
                if (roomData.landscape[position.y][position.x] == 1)
                {
                    // mark area around nolonger avaliable
                    roomData.landscape[position.y - 1][position.x] = 0;
                    roomData.landscape[position.y + 1][position.x] = 0;
                    roomData.landscape[position.y][position.x - 1] = 0;
                    roomData.landscape[position.y][position.x + 1] = 0;
                    roomData.landscape[position.y][position.x]     = 0;

                    validPos = true;
                }
            }
            newRoom.monsters[i] = genMonster(i, position);
        }
        //}

        // mark all gate position
        for (int i = 0; i < 4; i++)
        {
            newRoom.gates[i].x = x + roomData.gates[i].pos.x;
            newRoom.gates[i].y = y + roomData.gates[i].pos.y;
        }

        if (isMainline)
        {
            // get the next room (recursion), attach to the bridge
            if (length > 1)
            {
                // random a gate
                int direction;

                GenBridge    newBridge     = null;
                GenRoom      nextRoom      = null;
                int[]        directions    = new int[] { 0, 1, 2, 3 };
                List <int>   directionList = new List <int>(directions);
                List <float> ratioList     = new List <float>(directionRatio);
                if (directionList.Remove(incomeDirection) == true)
                {
                    ratioList.RemoveAt(incomeDirection);
                }
                do
                {
                    if (directionList.Count == 0)
                    {
                        return(null);
                    }

                    direction = randomGen(directionList.ToArray(), ratioList.ToArray());
                    int directionIndex = directionList.IndexOf(direction);
                    directionList.RemoveAt(directionIndex);
                    ratioList.RemoveAt(directionIndex);

                    newBridge = genBridge(newRoom.gates[direction].x, newRoom.gates[direction].y, direction);
                    nextRoom  = genNextRoom(newBridge.x, newBridge.y, isMainline, isLastLevel, length - 1, (direction < 2?direction + 2:direction - 2));
                } while (nextRoom == null);

                // open the gate
                newRoom.gates[direction].isGateOpen = true;

                int gateOpenMethod = genGateEvent(newRoom, direction);


                // TODO: Old open gate method, get ride of this when have time to implement event system on client side
                newRoom.gates[direction].gateOpenCondId = gateOpenMethod;
                if (newRoom.monsters == null)
                {
                    newRoom.gates[direction].gateOpenCondId = 0;
                }
                else if (newRoom.gates[direction].gateOpenCondId == 2)
                {
                    // need to kill specific monster, mark which one
                    // temp all monsterObj = 1
                    List <int> targetMonsters = new List <int>();
                    for (int i = 0; i < monsterNum; i++)
                    {
                        if (newRoom.monsters[i].monsterObjId == 1)
                        {
                            targetMonsters.Add(i);
                        }
                    }
                    newRoom.gates[direction].gateOpenCondParam = targetMonsters.ToArray();
                }

                // get a bridge and connect to the gate
                newRoom.gates[direction].bridge            = newBridge;
                newRoom.gates[direction].bridge.targetRoom = nextRoom;

                // gather list of unused gate for branching
                if (length != mainlineLength)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        if (i != direction && i != incomeDirection)
                        {
                            branchableGates.Add(newRoom.gates[i]);
                        }
                    }
                }
            }
        }
        else
        {
        }

        return(newRoom);
    }
Ejemplo n.º 13
0
 public List <GenTile> GetNeighbouringTiles(GenRoom room)
 {
     return(Data.ToList().Union(room.Data.ToList()).ToList());
 }
Ejemplo n.º 14
0
 public bool IsNeighbour(GenRoom room)
 {
     return(Data.ToList().Union(room.Data.ToList()).ToList().Count > 0);
 }
Ejemplo n.º 15
0
 public GenConnection(GenRoom a, GenRoom b)
 {
     this.a = a;
     this.b = b;
 }
Ejemplo n.º 16
0
    public static bool GenerateLayout(LevelGenerator generator, uint generationIndex)
    {
        Queue <GenRoom> rooms    = new Queue <GenRoom>(4);
        List <GenRoom>  genRooms = new List <GenRoom>(12);

        rooms.Enqueue(generator.firstRoom);
        while (rooms.Count > 0)
        {
            GenRoom room = rooms.Dequeue();
            if (room.generationIndex != generationIndex)
            {
                GenRoom firstGeneratedPrevRoom = null;
                int     connectionCount        = 0;
                for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next, connectionCount++)
                {
                    GenRoom otherRoom = room.GetOtherRoom(connection);
                    if (otherRoom.generationIndex != generationIndex)
                    {
                        rooms.Enqueue(otherRoom);
                    }
                    else if (firstGeneratedPrevRoom == null)
                    {
                        firstGeneratedPrevRoom = otherRoom;
                    }
                }

                GenRoomInfo roomInfo = generator.collection.GetRandomRoom(room.type);
                Debug.Assert(roomInfo.doors.Count >= connectionCount);
                // TODO: GetRandomRoom based on connectionCount

                if (firstGeneratedPrevRoom != null)
                {
                    List <GenRoom> connectedRooms = new List <GenRoom>(1)
                    {
                        firstGeneratedPrevRoom
                    };
                    List <Vector2Int> positions = GetUnconnectedPositions(firstGeneratedPrevRoom, roomInfo);
                    int positionCount           = positions.Count;

                    for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next)
                    {
                        GenRoom otherRoom = room.GetOtherRoom(connection);
                        if (otherRoom.generationIndex == generationIndex && otherRoom != firstGeneratedPrevRoom)
                        {
                            connectedRooms.Add(otherRoom);
                            List <Vector2Int> otherPositions = GetUnconnectedPositions(otherRoom, roomInfo);

                            for (int i = positions.Count - 1; i >= 0; --i)
                            {
                                if (!otherPositions.Contains(positions[i]))
                                {
                                    positions.RemoveAt(i);
                                }
                            }

                            if (positions.Count == 0)
                            {
                                Debug.Log($"FAILED: Couldn't find any connected positions for the room: {room.name} from the {positionCount} started positions!");
                                return(false);
                            }
                        }
                    }

                    RemoveCollidedPositions(genRooms, connectedRooms, positions, roomInfo.size);
                    if (positions.Count == 0)
                    {
                        if (positionCount == 0)
                        {
                            Debug.Log($"FAILED: Couldn't find any started positions for the room: {room.name} from the previous room: {firstGeneratedPrevRoom.name}");
                        }
                        else
                        {
                            Debug.Log($"FAILED: Couldn't find any uncollided positions  for the room: {room.name} from the {positionCount} started positions!");
                        }
                        return(false);
                    }

                    Vector2Int randomPos = positions.RandomElement();
                    InitGenRoom(genRooms, room, roomInfo, randomPos, generationIndex);
                    for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next)
                    {
                        GenRoom otherRoom = room.GetOtherRoom(connection);
                        if (otherRoom.generationIndex == generationIndex)
                        {
                            RectInt door = GetUnconnectedMatchDoors(room, otherRoom).RandomElement();
                            connection.connection.rect = door;
                            Debug.Assert(room.unconnectedDoors.Remove(new RectInt(door.position - room.rect.position, door.size)));
                            Debug.Assert(otherRoom.unconnectedDoors.Remove(new RectInt(door.position - otherRoom.rect.position, door.size)));
                        }
                    }
                }
                else
                {
                    InitGenRoom(genRooms, room, roomInfo, Vector2Int.zero, generationIndex);
                }
            }
        }

        return(true);