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 _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 _test_map_repeatability(): """ Require that two calls to _build_map() with the same seed produce the same corridors and rooms. """ map1 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3) map1.random_seed = libtcod.random_save(0) _build_map(map1) map2 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3) map2.random_seed = map1.random_seed _build_map(map2) assert map1.terrain == map2.terrain
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.Map(config.MAP_HEIGHT, config.MAP_WIDTH, 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) for new_room in new_map.rooms: _place_objects(new_map, new_room, player) player.pos = new_map.rooms[0].center() new_map.initialize_fov() return new_map
def test_random(): rand = libtcodpy.random_get_instance() rand = libtcodpy.random_new() libtcodpy.random_delete(rand) rand = libtcodpy.random_new_from_seed(42) libtcodpy.random_set_distribution(rand, libtcodpy.DISTRIBUTION_LINEAR) libtcodpy.random_get_int(rand, 0, 1) libtcodpy.random_get_int_mean(rand, 0, 1, 0) libtcodpy.random_get_float(rand, 0, 1) libtcodpy.random_get_double(rand, 0, 1) libtcodpy.random_get_float_mean(rand, 0, 1, 0) libtcodpy.random_get_double_mean(rand, 0, 1, 0) backup = libtcodpy.random_save(rand) libtcodpy.random_restore(rand, backup) libtcodpy.random_delete(rand) libtcodpy.random_delete(backup)
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.DungeonMap(config.MAP_WIDTH, config.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) player.pos = _build_map(new_map) _inhabit_pool(new_map) _place_random_creatures(new_map, player) new_map.initialize_fov() return True
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
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
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()
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()
def make_final_map(player, dungeon_level): """ """ old_map = player.current_map new_map = map.DungeonMap(FINAL_DUNGEON_SIZE, FINAL_DUNGEON_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) entry_stairs = old_map.dungeon_stairs mine_cartographer._link_up_stairs(new_map, old_map, entry_stairs) mine_cartographer._create_entries(new_map, entry_stairs) mine_cartographer._descend_stairs(new_map, player, entry_stairs) num_rooms = 3 for r in range(3, MAX_ROOMS): w = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE) h = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE) x = libtcod.random_get_int(new_map.rng, 0, new_map.width - w - 1) y = libtcod.random_get_int(new_map.rng, 0, new_map.height - h - 1) new_room = map.Room(x, y, w, h) failed = False for other_room in new_map.rooms: if new_room.intersect(other_room): failed = True break if not failed: # There are no intersections, so this room is valid. _create_room(new_map, new_room, num_rooms) new_ctr = new_room.center() prev_ctr = new_map.rooms[num_rooms-3].center() if libtcod.random_get_int(new_map.rng, 0, 1) == 1: _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, prev_ctr.y) _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, new_ctr.x) else: _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, prev_ctr.x) _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, new_ctr.y) new_map.rooms.append(new_room) new_map.room_entered.append(False) num_rooms += 1 # TODO: should be floodfill from one stair, make *sure* the other two are # connected for i in range(3): stair_pos = entry_stairs[i].dest_position ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y, map.TERRAIN_GROUND, map.TERRAIN_FLOOR) _add_doors(new_map) for i in range(3, num_rooms - 1): if (new_map.rnd(1, 2) == 1): foe = bestiary.dvergr(new_map, new_map.rooms[i].center(), player) _new_equipment(foe, miscellany.handaxe()) _new_equipment(foe, miscellany.roundshield()) if new_map.rnd(1, 2) == 1: _new_item(foe, miscellany.bandage(1)) if new_map.rnd(1, 2) == 1: _new_item(foe, miscellany.kumiss(1)) foe = bestiary.tepegoz(new_map, new_ctr, player) _new_equipment(foe, miscellany.maguffin()) _new_equipment(foe, miscellany.spear()) _new_equipment(foe, miscellany.roundshield()) 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()
def make_final_map(player, dungeon_level): """ """ old_map = player.current_map new_map = map.DungeonMap(FINAL_DUNGEON_SIZE, FINAL_DUNGEON_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) entry_stairs = old_map.dungeon_stairs mine_cartographer._link_up_stairs(new_map, old_map, entry_stairs) mine_cartographer._create_entries(new_map, entry_stairs) mine_cartographer._descend_stairs(new_map, player, entry_stairs) num_rooms = 3 for r in range(3, MAX_ROOMS): w = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE) h = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE) x = libtcod.random_get_int(new_map.rng, 0, new_map.width - w - 1) y = libtcod.random_get_int(new_map.rng, 0, new_map.height - h - 1) new_room = map.Room(x, y, w, h) failed = False for other_room in new_map.rooms: if new_room.intersect(other_room): failed = True break if not failed: # There are no intersections, so this room is valid. _create_room(new_map, new_room, num_rooms) new_ctr = new_room.center() prev_ctr = new_map.rooms[num_rooms - 3].center() if libtcod.random_get_int(new_map.rng, 0, 1) == 1: _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, prev_ctr.y) _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, new_ctr.x) else: _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, prev_ctr.x) _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, new_ctr.y) new_map.rooms.append(new_room) new_map.room_entered.append(False) num_rooms += 1 # TODO: should be floodfill from one stair, make *sure* the other two are # connected for i in range(3): stair_pos = entry_stairs[i].dest_position ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y, map.TERRAIN_GROUND, map.TERRAIN_FLOOR) _add_doors(new_map) for i in range(3, num_rooms - 1): if (new_map.rnd(1, 2) == 1): foe = bestiary.dvergr(new_map, new_map.rooms[i].center(), player) _new_equipment(foe, miscellany.handaxe()) _new_equipment(foe, miscellany.roundshield()) if new_map.rnd(1, 2) == 1: _new_item(foe, miscellany.bandage(1)) if new_map.rnd(1, 2) == 1: _new_item(foe, miscellany.kumiss(1)) foe = bestiary.tepegoz(new_map, new_ctr, player) _new_equipment(foe, miscellany.maguffin()) _new_equipment(foe, miscellany.spear()) _new_equipment(foe, miscellany.roundshield()) 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()