def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): self.game_map = game_map self.width = map_width self.height = map_height self.dungeon_level = dungeon_level self.room_max_size = min(map_height // 5, map_width // 5) self.room_min_size = min(map_height // 7, map_width // 7) rooms = [] num_rooms = 0 for r in range(max_rooms): # Random Width and Height w = randint(self.room_min_size, self.room_max_size) h = randint(self.room_min_size, self.room_max_size) # Random Position without going out of the boundaries of the map x = randint(0, map_width - w - 1) y = randint(0, map_height - h - 1) # "Rect" class makes rectangles easier to work with new_room = SquareRoom(x, y, w, h, len(game_map.rooms) + 1) # Check if Room Intersects with Existing Rooms for other_room in rooms: if new_room.intersect(other_room): break else: # No Intersections, so this room is Valid # "Paint" it to the map's tiles create_room(game_map, new_room) if num_rooms == 0: # 1st Room, Set Player to Start Here player.position.x, player.position.y = new_room.center game_map.tile_cost[player.position.y][ player.position.x] = 99 else: # Connect Every Room after 1st Room to Previous Room With Tunnel # Create connection between previous room and new room previous_map = rooms[num_rooms - 1] create_hall(game_map, previous_map, new_room) # Determine Monster Placement and Population place_entities(game_map, dungeon_level, new_room, entities, item_table, mob_table) # finally, append the new room to the list rooms.append(new_room) game_map.rooms.append(new_room) num_rooms += 1 # Add End-of-Level Stairs last_room_x, last_room_y = rooms[num_rooms - 1].center place_stairs(self.game_map, self.dungeon_level, last_room_x, last_room_y)
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): # Creates an empty 2D array or clears existing array self.walk_iterations = max(self.walk_iterations, (map_width * map_height * 10)) self.game_map = game_map self.dungeon_level = dungeon_level self.radius = max(map_width // 10, map_height // 10) self.random_walk_x = randint(self.radius, map_width - self.radius - 1) self.random_walk_y = randint(self.radius, map_height - self.radius - 1) # Modify Percent Goal Depending on Dungeon Level self._percentGoal = 0.1 + (self.dungeon_level * 0.015) self.filledGoal = map_width * map_height * self._percentGoal # Place Player at 1st Location # TODO: Sometimes player spawns inside a wall? x, y = self.random_walk_x, self.random_walk_y player.position.x, player.position.y = x, y self.game_map.tile_cost[y][x] = 99 create_floor(game_map, x, y) self.encounters.append((x, y)) for i in range(self.walk_iterations): self.walk(map_width, map_height) # Check for Encounter if self._filled % self.encounter_interval == 0: if self.encounter_within_proximity(self.random_walk_x, self.random_walk_y): if self.radius < self.random_walk_x < map_width - self.radius and self.radius < self.random_walk_y < map_height - self.radius: room = Circle(game_map, self.random_walk_x, self.random_walk_y, self.radius, len(game_map.rooms) + 1) game_map.rooms.append(room) place_entities(self.game_map, self.dungeon_level, room, entities, item_table, mob_table) self.encounters.append( (self.random_walk_x, self.random_walk_y)) else: # TODO: Find a way to not allow multiple iteration checks for encounter_within_proximity # Note: The below line is a lie. We're not really filling up more spaces. self._filled += 1 if self._filled >= self.filledGoal: break # Place Stairs at Last Location place_stairs(game_map, self.dungeon_level, self.random_walk_x, self.random_walk_y)
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): self.game_map = game_map self.dungeon_level = dungeon_level if self.dungeon_level == 5: self.width = map_width self.height = map_height self.generate(map_width, map_height) self.assign_terrain(entities, particles) # Throne Room/End Room room_width = 30 room_height = 15 x = self.map_width // 2 - room_width // 2 y = 0 self.end_room = self.add_custom_room(x, y, room_width, room_height, buffer=2) # Start Room room_width = 20 room_height = 10 x = self.map_width // 2 - room_width // 2 y = self.map_height - room_height - 1 self.start_room = self.add_custom_room(x, y, room_width, room_height, buffer=3) # Assign Player/Stair Locations self.game_map.player.position.x, self.game_map.player.position.y = self.map_width // 2, self.map_height - 1 # self.game_map.player.position.x, self.game_map.player.position.y = self.map_width // 2, 0 # self.game_map.player.position.x, self.game_map.player.position.y = center(self.start_room) place_stairs(self.game_map, self.dungeon_level, self.map_width // 2, 0) # place_stairs(self.game_map, self.dungeon_level, *center(self.end_room)) # Place Entities in each of the Sub rooms generated in Main Room for room in self.rooms: # for room in self.sub_rooms: place_entities(self.game_map, self.dungeon_level, room, entities, item_table, mob_table) game_map.rooms = self.rooms
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, item_table, mob_table): # def generate_level(self, game_map, map_width, map_height): # Creates an empty 2D array or clears existing array self.game_map = game_map self.dungeon_level = dungeon_level self.map_width = map_width self.map_height = map_height print('Random Fill Map') self.random_fill_map(map_width, map_height) print('Create Caves') self.create_caves(map_width, map_height) print('Get Caves') self.get_caves(map_width, map_height) print('Connect Caves') self.connect_caves(map_width, map_height) print('Clean Up Map') self.clean_up_map(map_width, map_height) # Find Center of Caves print('find_cave_centers') self.find_cave_centers() # Check if Caves were Actually Generation, Recall Same Generation if not self.cave_centers: print('Couldn\'t generate caves. Restarting...') self.reset_generation() entities = [player] self.generate_level(game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, item_table, mob_table) return False # Place Player and Stairs, Open Floor # TODO: Connect caves 1 and 2 player.position.x, player.position.y = self.cave_centers[0].center create_floor(game_map, player.position.x, player.position.y) x, y = self.cave_centers[-1].center entities.append(place_stairs(self.dungeon_level, x, y)) create_floor(game_map, x, y) # TODO: Ensure there is a path for player and path to stairs # Spawn Entities for cave in self.cave_centers: place_entities(game_map, dungeon_level, cave, entities, item_table, mob_table) # debug find centers # cx, cy = cave.center # print('cave center at: (%s, %s)' % (cx, cy)) create_floor(game_map, cave.x, cave.y) # create_floor(game_map, cave.x, cave.y) # print('cave center at: (%s, %s)' % (cave.x, cave.y)) self.print_generation_stats(entities)
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): self.game_map = game_map self.dungeon_level = dungeon_level self.width = map_width self.height = map_height self.assign_terrain() # Player/Stairs player.position.x, player.position.y = map_width // 2, map_height - 1 place_stairs(game_map, self.dungeon_level, map_width // 2, map_height - 1) # Generate Mobs area_width = map_width // 2 area_height = map_height // 5 area_x = map_width // 2 - area_width // 2 area_y = map_height // 4 area = AreaofInterest(x=area_x, y=area_y, width=area_width, height=area_height) self.areas_of_interest.append(area) number_of_mobs = randint(5, 10) ai_type = AI encounter = Encounter(self.game_map, area, len(self.game_map.encounters) + 1, ai_type) monster_chances = { mob: spawn_chance([stats for stats in mob_stats.get('spawn_chance')], randint(1, 6)) for mob, mob_stats in mob_table.items() } mob_list = generate_mobs(entities, game_map, number_of_mobs, mob_table, monster_chances, encounter, room=area) encounter.mob_list = mob_list self.game_map.encounters.append(encounter) self.game_map.rooms = self.areas_of_interest
def place_player_stairs(self, entities, player): # Assign room for Stairs and Player begin_end_select = randint(1, 2) if not self.sub_rooms: # no sub rooms and number of main rooms is less than 3 rooms = self.rooms if len(self.rooms) > 2: if begin_end_select == 1: start_x, start_y = rooms[0].center last_x, last_y = rooms[1].center start_room = rooms[0] end_room = rooms[1] else: last_x, last_y = rooms[1].center start_x, start_y = rooms[0].center start_room = rooms[1] end_room = rooms[0] else: half_way = len(self.sub_rooms) // 2 if begin_end_select == 1: start_room = choice(rooms[:half_way]) end_room = choice(rooms[half_way:]) start_x, start_y = start_room.center last_x, last_y = end_room.center else: end_room = choice(rooms[:half_way]) start_room = choice(rooms[half_way:]) last_x, last_y = start_room.center start_x, start_y = end_room.center else: if not self.sub_rooms: rooms = self.rooms else: rooms = self.sub_rooms half_way = len(self.sub_rooms) // 2 if begin_end_select == 1: start_room = choice(rooms[:half_way]) end_room = choice(rooms[half_way:]) start_x, start_y = start_room.center last_x, last_y = end_room.center else: end_room = choice(rooms[:half_way]) start_room = choice(rooms[half_way:]) last_x, last_y = end_room.center start_x, start_y = start_room.center # Place Player and Stairs self.start_room = start_room self.end_room = end_room # player.x, player.y = start_x, start_y entities.append( place_stairs(self.game_map.dungeon_level, last_x, last_y))
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): self.game_map = game_map self.dungeon_level = dungeon_level self.width = map_width self.height = map_height mold = False castle_entrance = False if dungeon_level == 1: # Cellular Automata Properties self.wall_chance = 40 self.min_count = 5 self.iterations = 1 self.pillar_iterations = 1 self.flood_tries = 5 self.goal_percentage = 30 # above 30% seems to be a good target self.encounter_spread_factor = 3 self.sparse_wall_density = 10 # Specific Dungeon Level Variables mold = False town = False elif dungeon_level == 2: # Cellular Automata Properties self.wall_chance = 40 self.min_count = 5 self.iterations = 2 self.pillar_iterations = 1 self.flood_tries = 5 self.goal_percentage = 30 # above 30% seems to be a good target self.encounter_spread_factor = 5 self.sparse_wall_density = 2 # Specific Dungeon Level Variables mold = True town = False elif dungeon_level == 3: # Cellular Automata Properties self.wall_chance = 40 self.min_count = 5 self.iterations = 2 self.pillar_iterations = 1 self.flood_tries = 5 self.goal_percentage = 30 # above 30% seems to be a good target self.encounter_spread_factor = 5 self.sparse_wall_density = 50 # Specific Dungeon Level Variables mold = True town = True castle_entrance = True else: # Cellular Automata Properties self.wall_chance = 40 self.min_count = 5 self.iterations = 1 self.pillar_iterations = 1 self.flood_tries = 5 self.goal_percentage = 30 # above 30% seems to be a good target self.encounter_spread_factor = 10 self.sparse_wall_density = 10 # Specific Dungeon Level Variables mold = True town = choice([False, True]) # Terrain Generation self.generate(castle_entrance) self.assign_tiles(mold=mold) # Terrain/Prefabs # self.generate_lake() if town: self.generate_town(room_min_size, room_max_size, entities, particles) self.generate_roads() self.generate_castle_entrance() # place_tile(self.game_map, x, y+h, "46") x1 = self.end_area.x y1 = self.end_area.y + self.end_area.height x2, y2 = self.town_center.x, self.town_center.y - 3 self.generate_road(x1, y1, x2, y2, True) else: self.generate_roads() # self.generate_rivers() # self.generate_monster_nests() # self.generate_bases() # Area of Interest Locations # for area in self.areas_of_interest: # place_tile(self.game_map, area.x, area.y, '3') # Select Player Starting Area # player.position.x, player.position.y = self.end_area.x, self.end_area.y player.position.x, player.position.y = self.start_area.x, self.start_area.y # max_tries = 30 # tries = 0 # while tries < max_tries: # rx, ry = randint(4, self.width-4), randint(4, self.height-4) # if self.game_map.walkable[ry][rx]: # player.position.x, player.position.y = rx, ry # self.game_map.tile_cost[ry][rx] = 99 # break # player.position.x, player.position.y = 10, 6 # Spawn Groups of Entities # for area in self.areas_of_interest: # self.generate_outpost(area, entities, particles) # self.ref_spawn_groups(entities) areas = deepcopy(self.areas_of_interest) for area in areas: place_entities(self.game_map, self.dungeon_level, area, entities, item_table, mob_table) # Game Map self.game_map = game_map self.dungeon_level = dungeon_level game_map.rooms = self.areas_of_interest place_stairs(game_map, self.dungeon_level, self.end_area.x, self.end_area.y + 2)
def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, particles, particle_systems, item_table, mob_table): self.game_map = game_map self.dungeon_level = dungeon_level if self.dungeon_level == 4: self.width = map_width self.height = map_height self.cell_block_min_size = 15 self.cell_block_depth = 2 self.cell_block_wall_buffer = 5 self.sub_room_depth = 3 self.initialize_grid() self.start_room = BSP(x=map_width//2, y=map_height-6, width=10, height=6) # create_floor(self.game_map, (map_width//2) + 5, map_height-6) # self.rooms[self.start_room] = [] # Generate Cell Blocks self.create_walled_room(self.start_room) self.end_room = BSP(x=map_width//2, y=0, width=10, height=6) # self.rooms[self.end_room] = [] self.create_walled_room(self.end_room) main_room = BSP(x=0, y=7, width=map_width, height=map_height-6-7) main_room.split_recursive( depth=self.cell_block_depth * 2, min_width=self.cell_block_min_size // 2, min_height=self.cell_block_min_size // 2, max_horizontal_ratio=1.25, max_vertical_ratio=1.25 ) self.rooms[main_room] = [] # Generate Rooms for cell in self.rooms.keys(): self.create_walled_room(cell, self.cell_block_wall_buffer) # self.rooms.pop(self.start_room) for node in main_room.pre_order(): if not node.children: self.create_walled_room(node, 0) self.rooms[main_room].append(node) self.sub_rooms.append(node) self.sub_rooms.append(self.end_room) # Connect All Rooms self.connect_rooms(self.rooms[main_room]) # Place Tiles self.assign_terrain(entities, particles) # Assign Player/Stair Locations self.game_map.player.position.x, self.game_map.player.position.y = center(self.start_room) place_stairs(self.game_map, self.dungeon_level, *center(self.end_room)) # Connect Start, Main and End Rooms for x in range((map_width // 2), (map_width // 2)+11): # start room to main place_tile(self.game_map, x, map_height - 6, "51") for x in range((map_width // 2), (map_width // 2)+11): # end Room to main # =map_height-6-7 place_tile(self.game_map, x, self.end_room.y+self.end_room.height, "51") place_tile(self.game_map, x, self.end_room.y + self.end_room.height+1, "51") # Place Map Objects # Levers self.create_lever_event(entities, particles) # Place Entities in each of the Sub rooms generated in Main Room for room in self.sub_rooms: place_entities(self.game_map, self.dungeon_level, room, entities, item_table, mob_table) game_map.rooms = self.rooms game_map.sub_rooms = self.sub_rooms