Ejemplo 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);
    }
    /* DEPRECATED
     * public void CreateDoorPassages_Post(VirtualMap map)
     * {
     *  if (map.HasRooms())
     *  {
     *      RoomGenerator roomG = new RoomGenerator();
     *      roomG.doorsDensityModifier = doorsDensityModifier;
     *      foreach (VirtualRoom r in map.rooms) roomG.CreateDoors_Post(map, r);
     *  }
     *  }*/

    public void CreateRocks(VirtualMap map)
    {
        foreach (CellLocation c in map.visitedCells)
        {
            if (map.IsSurroundedByWalls(c))
            {
                map.GetCell((int)c.x, (int)c.y).Type = VirtualCell.CellType.Rock;
            }
        }
    }
    /********************
    * Door creation
    ********************/
    public void CreateDoors(VirtualMap map, VirtualRoom r, RoomGenerator roomGenerator)
    {
        // Create a list of border floors (close to the borders of the room)
        List <CellLocation> borderFloors = new List <CellLocation>();

        for (int i = 0; i < r.Width; i++)
        {
            for (int j = 0; j < r.Height; j++)
            {
                if (i == 0 || j == 0 || i == r.Width - 1 || j == r.Height - 1)
                {
                    CellLocation l = new CellLocation(r.leftCorner.x + 2 * i, r.leftCorner.y + 2 * j);
                    borderFloors.Add(l);
                }
            }
        }

        // For each border floor, check if we are connecting to something on the other side
        List <CellLocation>             outsideBorderFloors = new List <CellLocation>();
        List <CellLocation>             insideBorderFloors  = new List <CellLocation>();
        List <VirtualMap.DirectionType> borderDirections    = new List <VirtualMap.DirectionType>();

        CellLocation target_passage;
        CellLocation target_floor;

        foreach (CellLocation l in borderFloors)
        {
            foreach (VirtualMap.DirectionType dir in map.directions)
            {
                target_passage = map.GetNeighbourCellLocation(l, dir);
                target_floor   = map.GetTargetLocation(l, dir);
                if (!map.LocationIsOutsideBounds(target_floor) &&
                    map.GetCell(target_passage).IsWall() &&
                    !map.IsSurroundedByWalls(target_floor))
                {
                    outsideBorderFloors.Add(target_floor);
                    insideBorderFloors.Add(l);
                    borderDirections.Add(dir);
                }
            }
        }

        // We now create a door for each outside border floor, making sure to avoid re-creating doors if the floors are already connected
        List <CellLocation> unremovedFloors = new List <CellLocation>(outsideBorderFloors);

        for (int i = 0; i < outsideBorderFloors.Count; i++)
        {
            CellLocation l = outsideBorderFloors[i];
            // If not already removed (but we may not skip if we request more doors than needed)
            if (unremovedFloors.Contains(l) || DungeonGenerator.Random.Instance.Next(0, 100) < doorsDensityModifier)
            {
                CreateDoor(map, r, roomGenerator, insideBorderFloors[i], l, borderDirections[i]);
                unremovedFloors.Remove(l);

                // We also remove the other connected cells
                for (int j = unremovedFloors.Count - 1; j >= 0; j--)
                {
                    CellLocation other_l    = unremovedFloors[j];
                    bool         existsPath = map.ExistsPathBetweenLocations(l, other_l);
                    if (existsPath)
                    {
                        unremovedFloors.Remove(other_l);
                    }
                }
            }
        }
    }
    private void PickBestRoomLocation(VirtualMap map, VirtualRoom r)
    {//, int roomNumber){
        // Traverse all floor cells checking for the best position for a room
        int best_score = 1000000;
        int current_score;
        List <CellLocation> best_locations = new List <CellLocation>();
        List <CellLocation> locations      = new List <CellLocation>(map.floorCells);

        foreach (CellLocation map_l in locations)
        {
            r.leftCorner = map_l;
            if (IsRoomLocationValid(map, r))
            {
                current_score = 0;       // Lower is better
                for (int i = 0; i < r.Width; i++)
                {
                    for (int j = 0; j < r.Height; j++)
                    {
                        CellLocation possible_room_l = new CellLocation(r.leftCorner.x + 2 * i, r.leftCorner.y + 2 * j);
                        //						Debug.Log("Possible room l: " + possible_room_l);

                        // Corridor vicinity: good
                        if (map.IsSurroundedByWalls(possible_room_l) && map.HasAdjacentFloor(possible_room_l))
                        {
                            current_score += 1;
                        }

                        bool corridorOverlap = map.IsFloor(possible_room_l);

                        // Corridor overlap: bad (at default)
                        if (!forceRoomTransversal && corridorOverlap)
                        {
                            current_score += 3;
                        }

                        // or good if we want the room in the middle!
                        else if (forceRoomTransversal && !corridorOverlap)
                        {
                            current_score += 3;
                        }

                        // Room overlap: very very bad
                        if (map.IsRoomFloor(possible_room_l))
                        {
                            current_score += 100;
                        }

                        // If multi-storey, the first room should be placed above another room!
                        //						if (roomNumber == 0 && !belowMap.isRoomFloor(possible_room_l)) current_score += 5;

                        // TODO: may be more efficient to exit now if the score is already low enough!
                    }
                }

                if (current_score == 0)
                {
                    continue;                     // Zero is not a valid score, as it means the room is isolated
                }
                if (current_score == best_score)
                {
                    best_locations.Add(map_l);
                }
                else if (current_score < best_score)
                {
                    best_score = current_score;
                    best_locations.Clear();
                    best_locations.Add(map_l);
                }
            }
        }

        if (best_locations.Count == 0)
        {
            r.leftCorner = new CellLocation(-1, -1);
        }
        else
        {
            r.leftCorner = best_locations[DungeonGenerator.Random.Instance.Next(0, best_locations.Count - 1)];
        }
    }