예제 #1
0
    //Returns a list of newly created rooms
    public LinkedList <RoomNode> BuildCorridors(RoomNode roomA, RoomNode roomB, Vector3 lastDir, LinkedList <RoomNode> existingRooms)
    {
        if (lastDir == Vector3.zero)
        {
            Debug.Log("Attempting to build new corridor");
        }
        if (roomA == roomB)
        {
            return(new LinkedList <RoomNode> ());
        }
        int attempts = 8;

        while (attempts > 0)
        {
            Vector3 overlapAxes  = RoomNode.OverlapAxes(roomA.roomBounds, roomB.roomBounds);
            int     numOverlaps  = Util.VecNonZeroes(overlapAxes);
            int     selectedAxis = Random.Range(0, 3);
            if (overlapAxes == Vector3.one)
            {
                return(new LinkedList <RoomNode> ());
            }
            while (overlapAxes[selectedAxis] != 0)
            {
                selectedAxis = Random.Range(0, 3);
            }
            Vector3 corridorDir = Vector3.zero;
            corridorDir [selectedAxis] = Mathf.Sign(roomB.roomBounds.center [selectedAxis] - roomA.roomBounds.center [selectedAxis]);
            //Debug.Log ("Connect " + numOverlaps);
            if (numOverlaps == 2)
            {
                LinkedList <RoomNode> result = new LinkedList <RoomNode> ();
                Bounds   b          = RoomNode.OverlapBounds(roomA.roomBounds, roomB.roomBounds);
                RoomNode r          = new RoomNode(b);
                Vector3  randomAxes = Vector3.one;
                randomAxes [selectedAxis] = 0;
                if (lastDir != Vector3.zero)
                {
                    r.ShoveToEdge(lastDir, Vector3.one * 0.5f * corridorSize);
                }
                else
                {
                    r.RandomizeBounds(randomAxes, corridorSize * Vector3.one, corridorSize * Vector3.one);
                }
                int limit = 12;
                while (GetOverlapped(r.roomBounds, existingRooms, corridorDir) != null && limit > 0)
                {
                    r.roomBounds = b;
                    r.RandomizeBounds(randomAxes, corridorSize * Vector3.one, corridorSize * Vector3.one);
                    limit--;
                }
                if (limit == 0)
                {
                    //Debug.Log ("OH GOD DAMMIT " + r.roomBounds.ToString ());
                    //Instantiate (indicatorPrefab, r.roomBounds.center, Quaternion.identity);
                }
                else
                {
                    r.isCorridor = true;
                    RoomNode.MakeNeighbors(roomA, r);
                    RoomNode.MakeNeighbors(r, roomB);
                    r.name = numOverlaps.ToString();
                    result.AddFirst(r);

                    return(result);
                }
            }
            else if (numOverlaps < 2)
            {
                Bounds b             = RoomNode.OverlapBounds(roomA.roomBounds, roomB.roomBounds);
                int    selectedOther = Random.Range(0, 3);
                while (selectedOther == selectedAxis || overlapAxes[selectedOther] != 0)
                {
                    selectedOther = Random.Range(0, 3);
                }
                Vector3 newCenter;
                Vector3 newExtents;
                newCenter  = b.center;
                newExtents = b.extents;
                if (numOverlaps == 1)
                {
                    newCenter [selectedOther]  = roomA.roomBounds.center [selectedOther];
                    newExtents [selectedOther] = roomA.roomBounds.extents [selectedOther];
                }
                else if (numOverlaps == 0)
                {
                    Debug.Log("Connecting Zero");
                    newCenter  = roomA.roomBounds.center;
                    newExtents = roomA.roomBounds.extents;
                    newCenter [selectedAxis]  = b.center [selectedAxis];
                    newExtents [selectedAxis] = b.extents [selectedAxis];
                }
                float sign      = Mathf.Sign(newCenter [selectedAxis] - roomA.roomBounds.center [selectedAxis]);
                float extension = Random.Range(corridorSize, roomB.roomBounds.extents [selectedAxis]);
                newCenter [selectedAxis]  += extension * sign;
                newExtents [selectedAxis] += extension;
                b.center  = newCenter;
                b.extents = newExtents;
                RoomNode r          = new RoomNode(b);
                Vector3  randomAxes = Vector3.one;
                randomAxes [selectedAxis] = 0;
                if (lastDir != Vector3.zero)
                {
                    r.ShoveToEdge(lastDir, Vector3.one * 0.5f * corridorSize);
                }
                else
                {
                    r.RandomizeBounds(randomAxes, corridorSize * Vector3.one, corridorSize * Vector3.one);
                }
                int limit = 12;
                while (GetOverlapped(r.roomBounds, existingRooms, corridorDir) != null && limit > 0)
                {
                    b          = RoomNode.OverlapBounds(roomA.roomBounds, roomB.roomBounds);
                    newCenter  = b.center;
                    newExtents = b.extents;
                    if (numOverlaps == 1)
                    {
                        newCenter [selectedOther]  = roomA.roomBounds.center [selectedOther];
                        newExtents [selectedOther] = roomA.roomBounds.extents [selectedOther];
                    }
                    else if (numOverlaps == 0)
                    {
                        newCenter  = roomA.roomBounds.center;
                        newExtents = roomA.roomBounds.extents;
                        newCenter [selectedAxis]  = b.center [selectedAxis];
                        newExtents [selectedAxis] = b.extents [selectedAxis];
                    }

                    extension = Random.Range(corridorSize, roomB.roomBounds.extents [selectedAxis]);
                    newCenter [selectedAxis]  += extension * sign;
                    newExtents [selectedAxis] += extension;
                    b.center     = newCenter;
                    b.extents    = newExtents;
                    r.roomBounds = b;
                    r.RandomizeBounds(randomAxes, corridorSize * Vector3.one, corridorSize * Vector3.one);
                    limit--;
                }
                if (limit == 0)
                {
                    //Debug.Log ("Aw f**k");
                }
                else
                {
                    LinkedList <RoomNode> result = BuildCorridors(r, roomB, corridorDir, existingRooms);
                    if (result.Count != 0)
                    {
                        r.isCorridor = true;
                        RoomNode.MakeNeighbors(roomA, r);
                        r.name = numOverlaps.ToString();
                        result.AddFirst(r);
                        return(result);
                    }
                }
            }
            attempts--;
        }

        if (lastDir == Vector3.zero)
        {
            Debug.Log("Couldn't Connect");
        }
        return(new LinkedList <RoomNode> ());
    }