Exemple #1
0
    override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier)
    {
        CellLocation currentLocation = starting_location;

        map.MarkAsVisited(currentLocation);

        // Pick a starting previous direction
        VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North;

        List <CellLocation> previousLocations = new List <CellLocation>();

        // Repeat until all cells have been visited
        while (!map.AllCellsVisited)
        {
            // Get a starting direction
            DirectionPicker          directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection);
            VirtualMap.DirectionType direction       = directionPicker.GetNextDirection(map, currentLocation);

            if (direction != VirtualMap.DirectionType.None)
            {
                // Create a corridor in the current cell and flag it as visited
                previousLocations.Add(currentLocation);
                previousDirection = direction;
                currentLocation   = map.CreateCorridor(currentLocation, direction);
                map.FlagCellAsVisited(currentLocation);
            }
            else
            {
                // Backtrack
                currentLocation = previousLocations[previousLocations.Count - 1];
                previousLocations.RemoveAt(previousLocations.Count - 1);
            }
        }
    }
    override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier)
    {
        CellLocation currentLocation = starting_location;

        map.MarkAsVisited(currentLocation);

        // Pick a previous direction
        VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North;

        // Repeat until all cells have been visited
        while (!map.AllCellsVisited)
        {
            // Get a starting direction
            DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection);

            VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation);

            if (direction != VirtualMap.DirectionType.None)
            {
                // Create a corridor in the current cell and flag it as visited
                currentLocation = map.CreateCorridor(currentLocation, direction);
                map.FlagCellAsVisited(currentLocation);
                previousDirection = direction;
            }
            // or start from another visited cell
            // NOTE: This may be less performant!
            else
            {
                currentLocation = map.GetRandomVisitedCell(currentLocation);

                // No visited cell available: proceed from a random unvisited cell
                if (currentLocation.x == -1)
                {
                    currentLocation = map.PickRandomUnvisitedLocation();
                    map.MarkAsVisited(currentLocation);
                }
            }
        }
    }
    // Open dead ends by linking them to rooms
    private void OpenDeadEnds(VirtualMap map)
    {
        //		Console.WriteLine("DEAD END MOD: " + openDeadEndModifier);
        if (openDeadEndModifier == 0)
        {
            return;
        }

        IEnumerable <CellLocation> deads = map.DeadEndCellLocations;

        foreach (CellLocation deadEnd in deads)
        {
            if (DungeonGenerator.Random.Instance.Next(1, 99) < openDeadEndModifier)
            {
                CellLocation currentLocation = deadEnd;
                //				int count=0;
                do
                {
                    // Initialize the direction picker not to select the dead-end corridor direction
                    DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, map.CalculateDeadEndCorridorDirection(currentLocation));
                    //                    Debug.Log("We have a dead and " + directionPicker);
                    VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation);
                    //					Debug.Log("We choose dir " + direction);
                    if (direction == VirtualMap.DirectionType.None)
                    {
                        throw new InvalidOperationException("Could not remove the dead end!");
                    }
                    //						Debug.Log("Cannot go that way!");
                    else
                    {
                        // Create a corridor in the selected direction
                        currentLocation = map.CreateCorridor(currentLocation, direction);
                    }
                    //					count++;
                } while (map.IsDeadEnd(currentLocation) && currentLocation != deadEnd); // Stop when you intersect an existing corridor, or when you end back to the starting cell (that means we could not remove the dead end, happens with really small maps
                //				Debug.Log("Dead end removed");
            }
        }
    }
Exemple #4
0
    private void CreateVerticalCorridor(VirtualMap map, BSPTreeNodeBounds roomBoundsBottom, BSPTreeNodeBounds roomBoundsTop)
    {
        BSPTreeNodeBounds higherRoomBounds = null, lowerRoomBounds = null;
        int  v_start      = 0;
        bool createLShape = false;
        int  higher_min_v = Mathf.Max(roomBoundsBottom.min_x, roomBoundsTop.min_x);
        int  lower_max_v  = Mathf.Min(roomBoundsBottom.max_x, roomBoundsTop.max_x);
        int  overlapping_v_range = lower_max_v - higher_min_v;

        if (overlapping_v_range > 0)
        {
            // They overlap: we choose randomly the start where the sides overlap
            v_start = DungeonGenerator.Random.Instance.Next(higher_min_v, lower_max_v - 1);
        }
        else
        {
            // They do not overlap! We'll need a L-shaped corridor!
            // We do so starting from one room, then going OVER the other, and then going down
            //Debug.Log("L");
            createLShape = true;

            // We now need to check which is the higher one
            if (roomBoundsBottom.max_x > roomBoundsTop.max_x)
            {
                // B higher than T
                higherRoomBounds = roomBoundsBottom;
                lowerRoomBounds  = roomBoundsTop;
            }
            else
            {
                // T higher than B
                higherRoomBounds = roomBoundsTop;
                lowerRoomBounds  = roomBoundsBottom;
            }

            // The v_start comes from the higher one
            v_start = DungeonGenerator.Random.Instance.Next(
                higherRoomBounds.min_x,
                higherRoomBounds.max_x - 1);
        }


        // We create a corridor from south to north
        int corridorWidth = 1;

        if (!createLShape)
        {
            corridorWidth = Mathf.Min(overlapping_v_range, maxCorridorWidth);
            if (corridorWidth > 1 && overlapping_v_range > 0)
            {
                int overflow = v_start + (corridorWidth - 1) - (lower_max_v - 1);
                v_start -= overflow;
                //Debug.Log(overflow);
            }
        }

        for (int y = roomBoundsBottom.max_y - 1; y < roomBoundsTop.min_y; y++)
        {
            CellLocation l = new CellLocation(v_start * 2 + 1, y * 2 + 1);

            // If already entering a corridor, we stop here!

            /*CellLocation target_l =  map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.North);
             * bool makeDoor = !(map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor);
             * makeDoor = true;*/

            map.CreateCorridor(l, VirtualMap.DirectionType.North, corridorWidth, makeDoor: true);
        }

        if (createLShape)
        {
            // We also create the W-E corridor
            for (int x = lowerRoomBounds.max_x - 1; x < v_start; x++)
            {
                int y_start = 0;
                if (lowerRoomBounds == roomBoundsTop)
                {
                    y_start = roomBoundsTop.min_y;
                }
                else
                {
                    y_start = roomBoundsBottom.max_y - 1;
                }
                CellLocation l = new CellLocation(x * 2 + 1, y_start * 2 + 1);

                // If already entering a corridor, we stop here!
                //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.East);
                //bool makeDoor = !(map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor);
                //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.East);
                //if (map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor) return;

                map.CreateCorridor(l, VirtualMap.DirectionType.East, makeDoor: true);
            }
        }
    }
Exemple #5
0
    private void CreateHorizontalCorridor(VirtualMap map, BSPTreeNodeBounds roomBoundsLeft, BSPTreeNodeBounds roomBoundsRight)
    {
        BSPTreeNodeBounds higherRoomBounds = null, lowerRoomBounds = null;
        int  v_start      = 0;
        bool createLShape = false;
        int  higher_min_v = Mathf.Max(roomBoundsLeft.min_y, roomBoundsRight.min_y);
        int  lower_max_v  = Mathf.Min(roomBoundsLeft.max_y, roomBoundsRight.max_y);
        int  overlapping_v_range = lower_max_v - higher_min_v;

        if (overlapping_v_range > 0)
        {
            // They overlap: we choose randomly the start where the sides overlap
            v_start = DungeonGenerator.Random.Instance.Next(
                higher_min_v,
                lower_max_v - 1);
        }
        else
        {
            // They do not overlap! We'll need a L-shaped corridor!
            // We do so starting from one room, then going OVER the other, and then going down
            //Debug.Log("L");
            createLShape = true;

            // We now need to check which is the higher one
            if (roomBoundsLeft.max_y > roomBoundsRight.max_y)
            {
                // L higher than R
                higherRoomBounds = roomBoundsLeft;
                lowerRoomBounds  = roomBoundsRight;
            }
            else
            {
                // R higher than L
                higherRoomBounds = roomBoundsRight;
                lowerRoomBounds  = roomBoundsLeft;
            }

            // The y_start comes from the higher one
            v_start = DungeonGenerator.Random.Instance.Next(
                higherRoomBounds.min_y,
                higherRoomBounds.max_y - 1);
        }

        // We create a corridor from west to east
        int corridorWidth = 1;

        if (!createLShape)
        {
            corridorWidth = Mathf.Min(overlapping_v_range, maxCorridorWidth);
            if (corridorWidth > 1 && overlapping_v_range > 0)
            {
                //Debug.Log("Start: " + v_start);
                int overflow = higher_min_v - (v_start - (corridorWidth - 1)); //(v_start - (corridorWidth - 1)) +  (higher_min_v - 1);
                v_start += overflow;
                //Debug.Log("Overflow: " + overflow);
                //Debug.Log("End: " + v_start);
            }
        }

        for (int x = roomBoundsLeft.max_x - 1; x < roomBoundsRight.min_x; x++)
        {
            CellLocation l = new CellLocation(x * 2 + 1, v_start * 2 + 1);
            //Debug.Log("EAST: " + l);

            // If already entering a corridor, we stop here!
            //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l,VirtualMap.DirectionType.East);
            //if (map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor) return;
            //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.East);
            //bool makeDoor = !(map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor);

            map.CreateCorridor(l, VirtualMap.DirectionType.East, corridorWidth, makeDoor: true);
        }

        if (createLShape)
        {
            // We also create the S-N corridor
            for (int y = lowerRoomBounds.max_y - 1; y < v_start; y++)
            {
                int x_start = 0;
                if (lowerRoomBounds == roomBoundsRight)
                {
                    x_start = roomBoundsRight.min_x;
                }
                else
                {
                    x_start = roomBoundsLeft.max_x - 1;
                }
                CellLocation l = new CellLocation(x_start * 2 + 1, y * 2 + 1);

                // If already entering a corridor, we stop here!
                //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.East);
                //if (map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor) return;
                // If already entering a corridor, we stop here!
                //CellLocation target_l = map.GetNeighbourCellLocationOfSameType(l, VirtualMap.DirectionType.North);
                //bool makeDoor = !(map.GetCell(target_l).Type == VirtualCell.CellType.CorridorFloor);

                map.CreateCorridor(l, VirtualMap.DirectionType.North, makeDoor: true);
            }
        }
    }