def _link_up_stairs(new_map, old_map, old_quarry_stairs):
    old_quarry_stairs[1].dest_position = algebra.Location(
        new_map.width / 2, new_map.height / 2)
    old_quarry_stairs[
        0].dest_position = old_quarry_stairs[1].dest_position + MINE_SCALE * (
            old_quarry_stairs[0].pos - old_quarry_stairs[1].pos)
    old_quarry_stairs[
        2].dest_position = old_quarry_stairs[1].dest_position + MINE_SCALE * (
            old_quarry_stairs[2].pos - old_quarry_stairs[1].pos)

    map_inset = algebra.Rect(10, 10, new_map.width - 20, new_map.height - 20)
    old_quarry_stairs[0].dest_position.bound(map_inset)
    old_quarry_stairs[2].dest_position.bound(map_inset)

    # print('Map is ' + str(new_map.width) + ' x ' + str(new_map.height))
    # print('Stairs come from ', [i.pos for i in old_quarry_stairs])
    # print('Stairs to mines connect to ', [i.dest_position for i in old_quarry_stairs])

    for i in range(3):
        old_quarry_stairs[i].destination = new_map
        stairs = Object(old_quarry_stairs[i].dest_position,
                        '>',
                        'mine exit',
                        libtcod.white,
                        always_visible=True)
        stairs.destination = old_map
        stairs.dest_position = old_quarry_stairs[i].pos
        new_map.objects.insert(0, stairs)
        new_map.portals.insert(0, stairs)
示例#2
0
def _build_map(new_map):
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    new_map.spare_terrain = copy.deepcopy(
        new_map.terrain
    )  # [[0 for y in range(new_map.height)] for x in range(new_map.width)]
    dig_ca_region(new_map, algebra.Rect(0, 0, new_map.width, new_map.height),
                  4, 3)

    center = algebra.Location(new_map.width / 2, new_map.height / 2)
    stair_loc = _probe_for_stair(new_map, range(new_map.width - 2, center.x,
                                                -1), center.y)
    if not stair_loc:
        # Uh-oh; no guarantee of completion
        print('Recursing with unenterable map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    pool_x = new_map.width / 4
    for x in range(pool_x - 6, pool_x + 7):
        for y in range(center.y - 6, center.y + 7):
            dx = x - pool_x
            dy = y - center.y
            if math.sqrt(dx**2 + dy**2) > 6:
                continue
            if new_map.terrain[x][y] == map.TERRAIN_WALL:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    new_map.pool_x = pool_x
    _scatter_ponds(new_map)

    # Can we reach from the stairs to the center of the pool?
    _floodfill(new_map, stair_loc.x, stair_loc.y, map.TERRAIN_GROUND,
               map.TERRAIN_FLOOR)
    if new_map.terrain[pool_x][center.y] != map.TERRAIN_FLOOR:
        # Uh-oh; no guarantee of completion
        print('Recursing with disconnected map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    # Close up any unconnected subcaves; flood any western bits
    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL
            elif x < pool_x and new_map.terrain[x][y] == map.TERRAIN_FLOOR:
                new_map.terrain[x][y] = map.TERRAIN_WATER

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    return stair_loc
def _dig_some_caves(new_map, old_quarry_stairs):
    new_map.spare_terrain = copy.deepcopy(
        new_map.terrain
    )  # [[0 for y in range(new_map.height)] for x in range(new_map.width)]

    new_map.cave_zones = []
    x = new_map.rnd(3, old_quarry_stairs[1].dest_position.x / 2)
    w = new_map.rnd(20, old_quarry_stairs[1].dest_position.x - x - 3)
    if old_quarry_stairs[0].dest_position.y < old_quarry_stairs[
            1].dest_position.y:
        # staircase 0 in top left quadrant, put caves in bottom left quadrant
        y = new_map.rnd(old_quarry_stairs[1].dest_position.y + 3,
                        old_quarry_stairs[1].dest_position.y * 3 / 2)
        h = new_map.rnd(20, new_map.height - y - 3)
    else:
        # staircase 0 in bottom left quadrant, put caves in top left quadrant
        y = new_map.rnd(3, old_quarry_stairs[1].dest_position.y / 2)
        h = new_map.rnd(20, old_quarry_stairs[1].dest_position.y - y - 3)

    target_zone = algebra.Rect(x, y, w, h)
    target_zone.x2 = min(target_zone.x2, new_map.width - 2)
    target_zone.y2 = min(target_zone.y2, new_map.height - 2)
    # print("Target zone 0 ", target_zone)
    ca_cartographer.dig_ca_region(new_map, target_zone, 4, 3)
    new_map.cave_zones.append(target_zone)

    x = new_map.rnd(old_quarry_stairs[1].dest_position.x + 3,
                    old_quarry_stairs[1].dest_position.x * 3 / 2)
    w = new_map.rnd(20, new_map.width - x - 3)
    if old_quarry_stairs[2].dest_position.y < old_quarry_stairs[
            1].dest_position.y:
        y = new_map.rnd(old_quarry_stairs[1].dest_position.y + 3,
                        old_quarry_stairs[1].dest_position.y * 3 / 2)
        h = new_map.rnd(20, new_map.height - y - 3)
    else:
        y = new_map.rnd(3, old_quarry_stairs[1].dest_position.y / 2)
        h = new_map.rnd(20, old_quarry_stairs[1].dest_position.y - y - 3)

    target_zone = algebra.Rect(x, y, w, h)
    target_zone.x2 = min(target_zone.x2, new_map.width - 2)
    target_zone.y2 = min(target_zone.y2, new_map.height - 2)
    # print("Target zone 1 ", target_zone)
    ca_cartographer.dig_ca_region(new_map, target_zone, 4, 3)
    new_map.cave_zones.append(target_zone)
def _consider_terminal_room(new_map, x, y):
    new_room = algebra.Rect(x - 2, y - 2, 4, 4)
    _create_room(new_map, new_room)
    count = len(new_map.rooms)
    new_map.rooms.append(new_room)
    new_map.room_entered.append(False)
    for ii in range(x - 2, x + 3):
        for jj in range(y - 2, y + 3):
            if (ii >= 0 and jj >= 0 and ii < new_map.width
                    and jj < new_map.height):
                new_map.room[ii][jj] = count
def _place_random_creatures(new_map, player):
    start_region = new_map.region[player.pos.x][player.pos.y]
    terrain_chances = {
        'lake': {
            None: 10
        },
        'marsh': {
            None: 10,
            bestiary.swamp_goblin: 10
        },
        'desert': {
            None: 20,
            bestiary.hyena_pair: 5,
            bestiary.gazelle: 10
        },
        'scrub': {
            None: 20,
            bestiary.hyena: 2,
            bestiary.gazelle: 4,
            bestiary.deer: 4,
            bestiary.wolf: 2
        },
        'forest': {
            None: 20,
            bestiary.deer: 10,
            bestiary.wolf_pair: 5,
            bestiary.bear: 3
        },
        'rock': {
            None: 10,
            bestiary.snow_leopard: 1
        },
        'ice': {
            None: 10,
            bestiary.snow_leopard: 1
        }
    }
    for r in range(len(new_map.region_seeds)):
        if (r == start_region
                or (new_map.quarry_regions and r in new_map.quarry_regions)):
            continue
        fn = _random_choice(terrain_chances[new_map.region_terrain[r]])
        if fn is not None:
            pos = algebra.Location(new_map.region_seeds[r][0],
                                   new_map.region_seeds[r][1])
            while new_map.is_blocked_at(pos):
                pos += actions.random_direction()
                pos.bound(
                    algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))
            if new_map.caravanserai and new_map.caravanserai.bounds.contains(
                    pos):
                continue
            # print('Creature in region ' + str(r) + ' at ' + str(pos.x) + ' ' + str(pos.y))
            fn(new_map, pos, player)
示例#6
0
def update_camera(player):
    """
    Makes sure the player is roughly centered and that we're not trying to draw off screen.
    Basic implementation is stateless.
    """
    newPos = player.pos - _console_center

    # Make sure the camera doesn't see outside the map.
    newPos.bound(algebra.Rect(0, 0,
                 player.current_map.width - config.MAP_PANEL_WIDTH,
                 player.current_map.height - config.MAP_PANEL_HEIGHT))

    if newPos != player.camera_position:
        player.current_map.fov_needs_recompute = True
        player.camera_position = newPos
def _create_entries(new_map, old_quarry_stairs):
    for i in range(3):
        w = libtcod.random_get_int(new_map.rng, 1, 3) * 2 + 3
        h = libtcod.random_get_int(new_map.rng, 1, 3) * 2 + 3
        x = old_quarry_stairs[i].dest_position.x - w / 2
        y = old_quarry_stairs[i].dest_position.y - h / 2

        new_room = algebra.Rect(x, y, w, h)
        _create_room(new_map, new_room)
        # print('Room #' + str(i) + ' at ' + str(new_room))
        new_map.rooms.append(new_room)
        new_map.room_entered.append(False)

        new_ctr = new_room.center()
        assert (new_ctr == old_quarry_stairs[i].dest_position)
示例#8
0
    def __init__(self, width, height, default_terrain):
        self.width = width
        self.height = height
        self.loc_bound = algebra.Rect(0, 0, width - 1, height - 1)
        self.objects = []
        self.portals = []

        self.random_seed = None
        self.rng = None

        self.fov_map = None
        self.fov_needs_recompute = True

        self.terrain = [[default_terrain for y in range(height)]
                        for x in range(width)]
        self._explored = [[False for y in range(height)] for x in range(width)]

        self.xp_visit = None
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.OutdoorMap(config.OUTDOOR_MAP_WIDTH,
                             config.OUTDOOR_MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)

    # Might want to change this later, but this is required in creature placement
    # routines so we know what region the player starts in so there isn't a
    # wandering monster jumping down their throat. Unless, of course, this
    # start point is on a *region border* and there's a monster in the next
    # region over...
    player.pos = algebra.Location(config.OUTDOOR_MAP_WIDTH - 8, 12)

    _place_random_creatures(new_map, player)
    _inhabit_rotunda(new_map, new_map.peak)
    if new_map.caravanserai:
        compound_cartographer.inhabit_caravanserai(new_map, player)
    if new_map.quarry_regions:
        _inhabit_quarry(new_map, player)

    # make sure we're not starting on top of an object or terrain feature
    while (new_map.terrain_at(player.pos).name != 'ground'):
        # subtle bug? doesn't use the map-building random number generator
        player.pos = player.pos + actions.random_direction()
        player.pos.bound(
            algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))

    new_map.initialize_fov()
    # setting an instancemethod breaks shelve save games
    # new_map.xp_visit = type(map.BaseMap.xp_visit)(_mountain_exploration, new_map, map.BaseMap)
    new_map.xp_visit = _mountain_exploration
    return True
示例#10
0
def make_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    old_quarry_stairs = old_map.quarry_stairs
    _link_up_stairs(new_map, old_map, old_quarry_stairs)
    _create_entries(new_map, old_quarry_stairs)
    _descend_stairs(new_map, player, old_quarry_stairs)
    _dig_some_caves(new_map, old_quarry_stairs)
    _dig_mine_tunnels(new_map)

    map_bounds = algebra.Rect(1, 1, new_map.width - 1, new_map.height - 1)
    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    ca_cartographer._generation(new_map, map_bounds, 7, 1)
    ca_cartographer._generation(new_map, map_bounds, 5, 1)

    # Redig the initial rooms because the CA can fill in the stairs
    for i in range(3):
        _create_room(new_map, new_map.rooms[i])

    for i in range(3):
        stair_pos = old_quarry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
                                   map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    zone_divisor = MINE_SIZE / 3
    slime_zone = new_map.rnd(0, 2)
    while True:
        undead_zone = new_map.rnd(0, 2)
        if undead_zone != slime_zone:
            break

    for r in range(3, len(new_map.rooms)):
        if new_map.rnd(1, 4) < 3:
            room = new_map.rooms[r]
            zone = room.center().x / zone_divisor
            if zone == slime_zone:
                if new_map.rnd(1, 2) == 1:
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                else:
                    bestiary.jelly(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
            elif zone == undead_zone:
                bestiary.ghul(new_map, _find_floor_near_room(new_map, room),
                              player)
            else:
                bestiary.worm(new_map, _find_floor_near_room(new_map, room),
                              player)

    r = new_map.rnd(3, len(new_map.rooms) - 1)
    pos = new_map.rooms[r].center()
    while new_map.is_blocked_at(pos):
        pos += actions.random_direction()

    new_map.objects.insert(0,
                           Object(pos, '%', "hero's corpse", libtcod.dark_red))
    sword = miscellany.the_black_sword()
    sword.pos = pos
    new_map.objects.insert(0, sword)

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()
示例#11
0
def make_caravanserai(new_map):
    size = 3
    (found_x, found_y) = _place_caravanserai(new_map, size)
    if found_x < 0 or found_y < 0:
        # Better undersized than none at all?
        size = 2
        (found_x, found_y) = _place_caravanserai(new_map, size)
        if found_x < 0 or found_y < 0:
            print("Couldn't fit caravanserai anywhere; sorry!")
            new_map.caravanserai = None
            return

    tl = new_map.region_seeds[found_x * 20 + found_y]
    br = new_map.region_seeds[found_x * 20 + found_y + (size - 1) * 20 +
                              (size - 1)]
    print('Caravanserai stretches from ', tl, ' to ', br, ' or so')
    bounds = algebra.Rect(
        tl[0], tl[1],
        max(min(br[0] - tl[0] + 1, MAX_CARAVANSERAI_SIZE),
            MIN_CARAVANSERAI_SIZE),
        max(min(br[1] - tl[1] + 1, MAX_CARAVANSERAI_SIZE),
            MIN_CARAVANSERAI_SIZE))
    for x in range(bounds.x1, bounds.x2 + 1):
        for y in range(bounds.y1, bounds.y2 + 1):
            if (x == bounds.x1 or x == bounds.x2 or y == bounds.y1
                    or y == bounds.y2):
                new_map.terrain[x][y] = map.TERRAIN_WALL
            else:
                new_map.terrain[x][y] = map.TERRAIN_FLOOR
    _clear_outside_walls(new_map, bounds)

    # Cut gates in it facing east and south
    center = bounds.center()

    new_map.caravanserai = Caravanserai(bounds)

    if (bounds.width > bounds.height):
        new_map.terrain[center.x][bounds.y2] = map.TERRAIN_GROUND
        new_map.terrain[bounds.x2][center.y + 2] = map.TERRAIN_GROUND

        # Rooms in west half
        wall_offset = new_map.rnd(2, (center.x - bounds.x1) / 3)
        for y in range(bounds.y1, bounds.y2 + 1):
            new_map.terrain[center.x - wall_offset][y] = map.TERRAIN_WALL

        north_door = new_map.rnd(bounds.y1 + 1, center.y - 2)
        _place_door(new_map,
                    algebra.Location(center.x - wall_offset, north_door))
        south_door = new_map.rnd(center.y + 1, bounds.y2 - 1)
        _place_door(new_map,
                    algebra.Location(center.x - wall_offset, south_door))

        wall_y = (north_door + south_door) / 2
        for x in range(bounds.x1, center.x - wall_offset):
            new_map.terrain[x][wall_y] = map.TERRAIN_WALL

        new_map.caravanserai.rooms.append(
            algebra.Rect(bounds.x1, bounds.y1,
                         center.x - wall_offset - bounds.x1,
                         wall_y - bounds.y1))
        new_map.caravanserai.rooms.append(
            algebra.Rect(bounds.x1, wall_y, center.x - wall_offset - bounds.x1,
                         bounds.y2 - wall_y))

        # outer rooms
        courtyard_mid_x = (center.x - wall_offset + bounds.x2) / 2
        outer_wall_y = (bounds.y1 + center.y + 2) / 2
        if outer_wall_y < north_door:
            outer_wall_y = north_door + 1
        for x in range(center.x - wall_offset, bounds.x2):
            new_map.terrain[x][outer_wall_y] = map.TERRAIN_WALL

        west_door = new_map.rnd(center.x - wall_offset + 2,
                                courtyard_mid_x - 2)
        _place_door(new_map, algebra.Location(west_door, outer_wall_y))
        east_door = new_map.rnd(courtyard_mid_x + 2, bounds.x2 - 2)
        _place_door(new_map, algebra.Location(west_door, outer_wall_y))

        wall_x = (east_door + west_door) / 2
        for y in range(bounds.y1, outer_wall_y):
            new_map.terrain[wall_x][y] = map.TERRAIN_WALL

        new_map.caravanserai.rooms.append(
            algebra.Rect(center.x - wall_offset, bounds.y1,
                         wall_x - center.x + wall_offset, wall_y - bounds.y1))
        new_map.caravanserai.rooms.append(
            algebra.Rect(wall_x, bounds.y1, center.x - wall_offset - bounds.x1,
                         bounds.x2 - wall_x))

        courtyard_bounds = algebra.Rect(center.x - wall_offset + 1,
                                        outer_wall_y + 1,
                                        bounds.x2 - center.x + wall_offset - 1,
                                        bounds.y2 - outer_wall_y - 1)

    else:
        new_map.terrain[center.x + 2][bounds.y2] = map.TERRAIN_GROUND
        new_map.terrain[bounds.x2][center.y] = map.TERRAIN_GROUND

        # Rooms in north half
        wall_offset = new_map.rnd(2, (center.y - bounds.y1) / 3)
        for x in range(bounds.x1, bounds.x2 + 1):
            new_map.terrain[x][center.y - wall_offset] = map.TERRAIN_WALL

        west_door = new_map.rnd(bounds.x1 + 1, center.x - 2)
        _place_door(new_map, algebra.Location(west_door,
                                              center.y - wall_offset))
        east_door = new_map.rnd(center.x + 1, bounds.x2 - 1)
        _place_door(new_map, algebra.Location(east_door,
                                              center.y - wall_offset))

        wall_x = (east_door + west_door) / 2
        for y in range(bounds.y1, center.y - wall_offset):
            new_map.terrain[wall_x][y] = map.TERRAIN_WALL

        new_map.caravanserai.rooms.append(
            algebra.Rect(bounds.x1, bounds.y1, wall_x - bounds.x1,
                         center.y - wall_offset - bounds.y1))
        new_map.caravanserai.rooms.append(
            algebra.Rect(wall_x, bounds.y1, bounds.x2 - center.x + wall_offset,
                         center.y - wall_offset - bounds.y1))

        # outer rooms
        courtyard_mid_y = (center.y - wall_offset + bounds.y2) / 2
        outer_wall_x = (bounds.x1 + center.x + 2) / 2
        if outer_wall_x < west_door:
            outer_wall_x = west_door + 1
        for y in range(center.y - wall_offset, bounds.y2):
            new_map.terrain[outer_wall_x][y] = map.TERRAIN_WALL

        north_door = new_map.rnd(center.y - wall_offset + 2,
                                 courtyard_mid_y - 2)
        _place_door(new_map, algebra.Location(outer_wall_x, north_door))
        south_door = new_map.rnd(courtyard_mid_y + 2, bounds.y2 - 2)
        _place_door(new_map, algebra.Location(outer_wall_x, south_door))

        wall_y = (south_door + north_door) / 2
        for x in range(bounds.x1, outer_wall_x):
            new_map.terrain[x][wall_y] = map.TERRAIN_WALL

        new_map.caravanserai.rooms.append(
            algebra.Rect(bounds.x1, center.y - wall_offset,
                         center.x - wall_offset - bounds.x1,
                         wall_y - center.y + wall_offset))
        new_map.caravanserai.rooms.append(
            algebra.Rect(bounds.x1, wall_y, center.x - wall_offset - bounds.x1,
                         bounds.x2 - wall_y))

        courtyard_bounds = algebra.Rect(outer_wall_x + 1,
                                        center.y - wall_offset + 1,
                                        bounds.x2 - outer_wall_x - 1,
                                        bounds.y2 - center.y + wall_offset - 1)

    print('Caravanserai court ', courtyard_bounds)
    print('Caravanserai rooms ', new_map.caravanserai.rooms[0],
          new_map.caravanserai.rooms[1], new_map.caravanserai.rooms[2],
          new_map.caravanserai.rooms[3])

    new_map.caravanserai.courtyard = courtyard_bounds
    _clear_courtyard(new_map, courtyard_bounds)

    # TODO: create an upstairs and a cellar

    _add_loot(new_map, miscellany.leather_armor, 1)
    _add_loot(new_map, miscellany.bandage, 3)
    _add_loot(new_map, miscellany.bandage, 3)
    _add_loot(new_map, miscellany.kumiss, 4)
    _add_loot(new_map, miscellany.arrow, 6)