コード例 #1
0
    private bool TryCombiningRooms(RoomComposite composite, RCObj RCOrig, RCObj RCNew, int[] indsOrig)
    {
        foreach (int indA in indsOrig)
        {
            Direction dirA = RCOrig.connections[indA].side;
            Direction dirN = (Direction)(((int)dirA + 2) % 4);

            int[] indsN = RCNew.GetRandomConnections(dirN);

            foreach (int indN in indsN)
            {
                if (indA == -1 || indN == -1) // should be unneccesary
                {
                    continue;
                }

                bool didAdd = composite.Add(RCOrig, indA, RCNew, indN);
                if (didAdd)
                {
                    return(true);
                }
            }
        }
        return(false);
    }
コード例 #2
0
    private bool AddRoomRandom(RoomComposite composite, RCObj RCOrig, FlowNode nodeNew)
    {
        RoomData roomNew;
        RCObj    RCNew;

        // try adding first 2 rooms together
        for (int i = 0; i < MAX_TRIES; i++)
        {
            roomNew = GetRoom(nodeNew);
            RCNew   = new RCObj(roomNew);

            bool didAdd = TryCombiningRooms(composite, RCOrig, RCNew, RCOrig.GetAvailableConnections());
            if (didAdd)
            {
                if (!AddNode(nodeNew, RCNew))
                {
                    return(false); // couldn't generate complex hallway
                }
                return(true);
            }
        }
        return(false);
    }
コード例 #3
0
    private bool CheckOverlappingCyclesHelper(List <List <FlowNode> > cycles, out bool properlyGenerated)
    {
        properlyGenerated = true;
        foreach (List <FlowNode> cycle in cycles)
        {
            if (DoesCycleContain(addedCycles, cycle))
            {
                continue;
            }

            foreach (FlowNode currentNode in addedNodes.Keys)
            {
                if (cycle.Contains(currentNode))
                {
                    while (cycle[0] != currentNode) // cycle until currentNode is in the front
                    {
                        cycle.Add(cycle[0]);
                        cycle.RemoveAt(0);
                    }
                    RoomComposite rc = AddCycleToComposite(dungeonComposite, addedNodes[currentNode], cycle);
                    if (rc == null)
                    {
                        properlyGenerated = false;
                        return(false);
                    }
                    else
                    {
                        addedCycles.Add(cycle);
                        properlyGenerated = true;
                        return(true);
                    }
                }
            }
        }
        return(false);
    }
コード例 #4
0
    private bool TryGenerating(List <List <FlowNode> > cycles)
    {
        addedCycles    = new List <List <FlowNode> >();
        addedNodes     = new Dictionary <FlowNode, RCObj>();
        remainingNodes = new List <FlowNode>();
        foreach (FlowNode node in currentFlow.verticies)
        {
            remainingNodes.Add(node.Copy());
        }

        dungeonComposite = null;
        bool didGen = true;

        if (cycles.Count > 0)
        {
            // TODO: progress cycle a random amount
            if (Constants.doRandom)
            {
                int n = Random.Range(0, cycles.Count);
                for (int i = 0; i < n; i++)
                {
                    cycles[0].Add(cycles[0][0]);
                }
                cycles[0].RemoveRange(0, n);
            }

            FlowNode nodeInit = cycles[0][0];
            RoomData roomInit = GetRoom(nodeInit);
            RCObj    RCInit   = new RCObj(roomInit);
            dungeonComposite = new RoomComposite(RCInit);

            AddNode(nodeInit, RCInit);
            dungeonComposite = AddCycleToComposite(dungeonComposite, RCInit, cycles[0]);
            if (dungeonComposite == null)
            {
                return(false);
            }

            addedCycles.Add(cycles[0]);

            didGen = CheckOverlappingCycles(cycles);
            if (!didGen)
            {
                return(false);
            }
        }
        else
        {
            FlowNode maxNode = remainingNodes[0];
            foreach (FlowNode node in remainingNodes)
            {
                if (node.neighbors.Count > maxNode.neighbors.Count)
                {
                    maxNode = node;
                }
            }

            RoomData roomInit = GetRoom(maxNode);
            RCObj    RCInit   = new RCObj(roomInit);
            dungeonComposite = new RoomComposite(RCInit);
            didGen           = AddNode(maxNode, RCInit);
            if (!didGen)
            {
                return(false);
            }
        }

        //Debug.Log(remainingNodes.Count + " remaining!");

        int limitCount = 0;

        while (remainingNodes.Count > 0 && limitCount < 1000000)
        {
            limitCount++;

            List <FlowNode> frontierNodes = new List <FlowNode>();
            foreach (FlowNode node in addedNodes.Keys)
            {
                foreach (FlowNode adj in node.neighbors)
                {
                    if (remainingNodes.Contains(adj))
                    {
                        frontierNodes.Add(adj);
                    }
                }
            }

            FlowNode maxNode = remainingNodes[0];
            foreach (FlowNode node in frontierNodes)
            {
                if (node.neighbors.Count > maxNode.neighbors.Count)
                {
                    maxNode = node;
                }
            }

            FlowNode origNode = null;
            foreach (FlowNode node in addedNodes.Keys)
            {
                if (node.neighbors.Contains(maxNode))
                {
                    origNode = node;
                }
            }


            didGen = AddRoomRandom(dungeonComposite, addedNodes[origNode], maxNode);
            if (!didGen)
            {
                return(false);
            }

            if (addedCycles.Count < cycles.Count)
            {
                didGen = CheckOverlappingCycles(cycles);
                if (!didGen)
                {
                    return(false);
                }
            }
        }


        if (dungeonComposite == null || limitCount > 1000000)
        {
            return(false);
        }

        return(true);
    }
コード例 #5
0
    private RoomComposite AddCycleToComposite(RoomComposite composite, RCObj RCA, List <FlowNode> cycle)
    {
        FlowNode nodeN = cycle[1];
        RoomData roomN = null;
        RCObj    RCN   = null;

        bool didAdd = false;

        if (!addedNodes.ContainsKey(cycle[1]))
        {
            // try adding first 2 rooms together
            for (int i = 0; i < MAX_TRIES; i++)
            {
                roomN = GetRoom(nodeN);
                RCN   = new RCObj(roomN);

                didAdd = TryCombiningRooms(composite, RCA, RCN, RCA.GetAvailableConnections());
                if (didAdd)
                {
                    if (!AddNode(nodeN, RCN))
                    {
                        return(null); // couldn't generate complex hallway
                    }
                    break;
                }
            }

            // failed to place first two rooms
            if (!didAdd)
            {
                return(null);
            }
        }
        else
        {
            RCN = addedNodes[nodeN];
        }


        // place rest of rooms
        for (int n = 2; n < cycle.Count; n++)
        {
            didAdd = false;

            FlowNode nodeM = cycle[n];

            if (!addedNodes.ContainsKey(nodeM))
            {
                int[] indsN;
                // get furthest dir
                if (n < (cycle.Count + 1) / 2)
                {
                    indsN = RCN.GetFurthestConnection(RCA, 3);
                }
                else // get closest dir
                {
                    indsN = RCN.GetClosestConnections(RCA, 3);
                }
                if (indsN[0] == -1)
                {
                    continue;
                }

                for (int i = 0; i < MAX_TRIES; i++)
                {
                    RoomData roomM = GetRoom(nodeM);
                    RCObj    RCM   = new RCObj(roomM);

                    didAdd = TryCombiningRooms(composite, RCN, RCM, indsN);

                    if (didAdd)
                    {
                        if (!AddNode(nodeM, RCM))
                        {
                            return(null); // couldn't generate complex hallway
                        }
                        RCN = RCM;
                        break;
                    }
                }

                if (!didAdd)
                {
                    return(null); // restart composite
                }
            }
            else
            {
                // already added
                RCN = addedNodes[nodeM];
            }
        }

        //if (!composite.TryGenerateComplexHallway(RCN, RCA))
        //    return null; // couldnt do the last hallway :(

        // succeeded
        //Debug.Log("Rooms added successfully!");
        return(composite);
    }
コード例 #6
0
    public void PlaceComposite(RoomComposite composite, int x, int y, GameObject dungeonContainer = null)
    {
        if (dungeonContainer == null)
        {
            dungeonContainer = GameObject.Find("DungeonContainer"); // maybe do a new GameObject() here
        }
        Awake();                                                    // delete later

        Vector3Int offset = composite.basePos + new Vector3Int(x, y, 0);

        foreach (RCObj rco in composite.rooms)
        {
            // placing room
            GameObject roomGameObj = PlaceRoom(rco.roomData, offset.x + rco.pos.x, offset.y + rco.pos.y, dungeonContainer);
            Room       room        = roomGameObj.GetComponent <Room>();

            // special cases
            if (rco.roomData.roomType == RoomType.entrance)
            {
                List <Direction> sides = new List <Direction>();

                foreach (RCConnection connection in rco.connections)
                {
                    if (connection.isAvailable)
                    {
                        sides.Add(connection.side);
                    }
                }
                Direction dir;
                if (sides.Count == 0)
                {
                    Debug.LogError("No sides to spawn entrance in!");
                    dir = 0;
                }
                else
                {
                    dir = sides[Random.Range(0, sides.Count)];
                    dir = (Direction)((int)dir % 4);
                }
                room.SpawnEnterance(dir);
            }
            else if (rco.roomData.roomType == RoomType.exit)
            {
                Direction dir = 0;
                foreach (RCConnection connection in rco.connections)
                {
                    if (!connection.isAvailable)
                    {
                        dir = connection.side;
                        break;
                    }
                }
                dir = (Direction)(((int)dir + 2) % 4);
                room.SpawnExit(dir);
            }

            // filling unused walls with doors
            for (int doorInd = 0; doorInd < rco.connections.Count; doorInd++)
            {
                UpdateDoorWallCheck(room.doors[doorInd], rco.connections[doorInd], offset + rco.pos);
            }
        }
        // placing hallway
        foreach (HallwayObj h in composite.hallways)
        {
            PlaceHallway(h, offset);
        }
    }