Exemplo n.º 1
0
    private bool CheckSkipDoorToCorridor(VirtualMap map, VirtualRoom r, CellLocation end_floor_loc)
    {
        // Note that 'dont skip' takes precedence!
        //Debug.Log(r + " to " + end_floor_loc);

        // At default, we do not skip
        bool skip = false;

        // Already connected: we should skip it
        skip = r.IsConnectedToCorridor();
        //Debug.Log("Connected already? " + skip);

        // If 3 walls, we instead do not skip it
        skip = skip && !map.IsDeadEnd(end_floor_loc, alsoConsiderDoors: true);

        /*if (r.leftCorner.x == 9 && r.leftCorner.y == 3)
         * {
         *  Debug.Log(r + " to " + end_floor_loc);
         *  Debug.Log("3 walls? " + map.IsDeadEnd(end_floor_loc, alsoConsiderDoors: true));
         * }*/

        // If 4 walls, we instead do not skip it
        skip = skip && !map.IsSurroundedByWalls(end_floor_loc);
        //Debug.Log("4 walls? " + map.IsSurroundedByWalls(end_floor_loc));

        // We do not skip if we request more doors
        skip = skip && !(DungeonGenerator.Random.Instance.Next(0, 100) < doorsDensityModifier);
        //Debug.Log("More doors? " + moreDoors);

        return(skip);
    }
    // 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");
            }
        }
    }
    public void ComputeStartAndEnd(VirtualMap map, VirtualMap vmapBelow)
    {
        List <CellLocation> iterable_locations;
        bool foundStart = false;

        if (forceStartAndEndInRooms)
        {
            iterable_locations = new List <CellLocation>(map.RoomWalkableLocations);
        }
        else
        {
            iterable_locations = new List <CellLocation>(map.WalkableLocations);
        }

        // Makes sure it is in some dead end, or in a room, if possible
        List <CellLocation> possible_start_locations = new List <CellLocation>();

        foreach (CellLocation l in iterable_locations)
        {
            if (map.IsDeadEnd(l) || map.IsInRoom(l))
            {
                possible_start_locations.Add(l);
            }
        }

        // If not possible, consider all locations equally
        if (possible_start_locations.Count == 0)
        {
            possible_start_locations = iterable_locations;
        }
        //		Debug.Log ("Possible start locations: " + possible_start_locations.Count);

        // TODO: Make an option for the start to be on the perimeter
//		foreach (CellLocation l in possible_start_locations) {
//			if (map.IsOnPerimeter(l) possible_start_locations
//		}


        // NOTE: we here find a start, but the algorithm already could have one! maybe use that?
        if (vmapBelow == null)
        {
            // Choose a random walkable cell as the starting point
            int index;
            index = DungeonGenerator.Random.Instance.Next(0, possible_start_locations.Count - 1);
            if (index != -1 && possible_start_locations.Count != 0)
            {
                map.start  = new CellLocation(possible_start_locations[index].x, possible_start_locations[index].y);
                foundStart = true;
            }
        }
        else
        {
            // Choose the cell above the below map's end as the starting point
            map.start  = vmapBelow.end;
            foundStart = true;
        }

        if (foundStart)
        {
            //Debug.Log ("CHOSEN START: " + map.start);
            // For this to work, we must compute the distance of all cells from the starting cell
            map.ComputeCellDistances(startCellLocation: map.start);

            // Choose a cell at a certain distance from the starting point as the ending point
            map.end = map.GetCellLocationInLimits(iterable_locations, minimumDistanceBetweenStartAndEnd / 100.0f * map.GetMaximumDistance(), maximumDistanceBetweenStartAndEnd / 100.0f * map.GetMaximumDistance());
        }

        //Debug.Log("START : " + map.start);
        //Debug.Log("END : " + map.end);
        //Debug.Log(map.GetWalkDistance(map.start,map.end));

        if (!foundStart)
        {
            Debug.LogError("Cannot find a suitable entrance!");
        }
        //DebugUtils.Assert(foundStart, "Cannot find a suitable entrance!");
    }