Beispiel #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);
    }
Beispiel #2
0
    private bool CanAddRoom(RCObj rco)
    {
        int width  = rco.roomData.width;
        int height = rco.roomData.height;

        for (int r = 0; r < height; r++)
        {
            for (int c = 0; c < width; c += 7) // check every 7 columns maybe itll be faster
            {
                if (grid[MID + basePos.x + rco.pos.x + c, MID + basePos.y + rco.pos.y + r])
                {
                    return(false);
                }
            }
        }

        for (int r = 0; r < height; r++) // this might be wrong
        {
            if (grid[MID + basePos.x + rco.pos.x + width - 1, MID + basePos.y + rco.pos.y + r])
            {
                return(false);
            }
        }

        return(true);
    }
Beispiel #3
0
    public List <Vector3Int> path = new List <Vector3Int>(); // exclusive

    public HallwayObj(RCObj RCA, RCObj RCB, RCConnection conA, RCConnection conB, bool isStraight)
    {
        roomA          = RCA;
        roomB          = RCB;
        connectionA    = conA;
        connectionB    = conB;
        isPathStraight = isStraight;
    }
Beispiel #4
0
    public int[] GetFurthestConnection(RCObj other, int n)
    {
        List <System.Tuple <int, int> > distIndexList = new List <System.Tuple <int, int> >();

        for (int i = 0; i < connections.Count; i++)
        {
            if (!connections[i].isAvailable)
            {
                continue;
            }
            int maxManhattan = 0;
            int furthestInd  = -1;

            for (int j = 0; j < other.connections.Count; j++)
            {
                if (!other.connections[j].isAvailable)
                {
                    continue;
                }
                Vector3Int d         = (pos + connections[i].pos) - (other.pos + other.connections[j].pos);
                int        manhattan = Mathf.Abs(d.x) + Mathf.Abs(d.y);
                if (manhattan > maxManhattan)
                {
                    maxManhattan = manhattan;
                    furthestInd  = i;
                }
            }

            distIndexList.Add(new System.Tuple <int, int>(maxManhattan, furthestInd));
        }
        distIndexList.Sort();
        if (Constants.doRandom && distIndexList.Count > 1 &&
            distIndexList[0].Item2 == distIndexList[1].Item2 && Random.Range(0, 2) == 1)
        {
            System.Tuple <int, int> temp = distIndexList[0];
            distIndexList[0] = distIndexList[1];
            distIndexList[1] = temp;
        }
        distIndexList.Reverse();
        int[] sortedIndexes = new int[n];
        int   count         = 0;

        while (count < distIndexList.Count && count < n)
        {
            sortedIndexes[count] = distIndexList[count].Item2;
            count++;
        }
        while (count < n)
        {
            sortedIndexes[count] = -1;
            count++;
        }

        return(sortedIndexes);
    }
Beispiel #5
0
    // assumes origRoom is already in rooms
    public bool Add(RCObj origRoom, int origConnectionIndex, RCObj newRoom, int newConnectionIndex)
    {
        if (!rooms.Contains(origRoom) || !origRoom.connections[origConnectionIndex].isAvailable ||
            !newRoom.connections[newConnectionIndex].isAvailable)
        {
            Debug.LogWarning("Something went wrong when adding a room to composite!");
        }

        Direction  dirOut     = origRoom.connections[origConnectionIndex].side;
        Vector3Int nearestPos = origRoom.pos + origRoom.connections[origConnectionIndex].pos -
                                newRoom.connections[newConnectionIndex].pos + MIN_HALLWAY * DirectionUtil.Convert(dirOut);

        HallwayObj hallway = new HallwayObj(origRoom, newRoom,
                                            origRoom.connections[origConnectionIndex], newRoom.connections[newConnectionIndex], true);

        for (int i = 0; i < MAX_HALLWAY; i++)
        {
            if (Constants.doRandom)
            {
                if (Random.Range(0, 1f) < 0.3f)
                {
                    continue;
                }
            }

            newRoom.pos = nearestPos + (i * DirectionUtil.Convert(dirOut));
            if (CanAddRoom(newRoom))
            {
                if (TryGenerateSimpleHallway(hallway))
                {
                    hallway.roomA.connectedObjects.Add(hallway.roomB);
                    hallway.roomB.connectedObjects.Add(hallway.roomA);

                    rooms.Add(newRoom);
                    origRoom.connections[origConnectionIndex].isAvailable = false;
                    newRoom.connections[newConnectionIndex].isAvailable   = false;

                    AddRoomToGrid(newRoom);
                    AddHalwayToGrid(hallway);
                    UpdateDoorAvailability();
                    return(true);
                }
            }
        }

        return(false);
    }
Beispiel #6
0
    private void AddRoomToGrid(RCObj rco)
    {
        int width  = rco.roomData.width;
        int height = rco.roomData.height;

        char[] roomChar = rco.roomData.roomString.ToCharArray();

        for (int r = 0; r < height; r++)
        {
            for (int c = 0; c < width; c++)
            {
                char t = roomChar[r * (width + 1) + c];
                if (t == RoomData.WALLCHAR || t == RoomData.FLOORCHAR)
                {
                    // does this mirror rooms?
                    grid[MID + basePos.x + rco.pos.x + c, MID + basePos.y + rco.pos.y + (height - r - 1)] = true;
                }
            }
        }
    }
Beispiel #7
0
    public bool TryGenerateComplexHallway(RCObj RCA, RCObj RCB)
    {
        int[] lastRoomInds  = RCB.GetClosestConnections(RCA, 2);
        int[] firstRoomInds = RCA.GetClosestConnections(RCB, 2);

        if (lastRoomInds[0] == -1 || firstRoomInds[0] == -1) // no available connections, restart composite
        {
            return(false);
        }

        for (int lastInd = 0; lastInd < 2; lastInd++)
        {
            if (lastRoomInds[lastInd] == -1)
            {
                continue;
            }
            for (int firstInd = 0; firstInd < 2; firstInd++)
            {
                if (firstRoomInds[firstInd] == -1)
                {
                    continue;
                }

                HallwayObj complexHallway = new HallwayObj(RCA, RCB,
                                                           RCA.connections[firstRoomInds[firstInd]], RCB.connections[lastRoomInds[lastInd]], false);
                if (TryGenerateComplexHallwayHelper(complexHallway))
                {
                    AddHalwayToGrid(complexHallway);
                    complexHallway.connectionA.isAvailable = false;
                    complexHallway.connectionB.isAvailable = false;
                    UpdateDoorAvailability();
                    RCA.connectedObjects.Add(RCB);
                    RCB.connectedObjects.Add(RCA);
                    return(true);
                }
            }
        }

        return(false);
    }
Beispiel #8
0
    private bool AddNode(FlowNode node, RCObj rco)
    {
        addedNodes[node] = rco;
        remainingNodes.Remove(node);

        foreach (FlowNode adj in node.neighbors)
        {
            if (addedNodes.ContainsKey(adj))
            {
                if (!rco.connectedObjects.Contains(addedNodes[adj]))
                {
                    bool didGen = dungeonComposite.TryGenerateComplexHallway(rco, addedNodes[adj]);

                    if (!didGen)
                    {
                        return(false);
                    }
                }
            }
        }
        return(true);
    }
Beispiel #9
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);
    }
Beispiel #10
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);
    }
Beispiel #11
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);
    }
Beispiel #12
0
    private bool[,] grid = new bool[MAX_SIZE, MAX_SIZE];         // [x, y] = true if wall

    public RoomComposite(RCObj rco)
    {
        rooms.Add(rco);

        AddRoomToGrid(rco);
    }