def generate_roads(self): # print('generate_roads') # Connect Start and End astar = tcod.path.AStar(self.game_map.tile_cost, 1.41) path = astar.get_path(self.start_area.center[1], self.start_area.center[0], self.end_area.center[1], self.end_area.center[0]) for x, y in path: if randint(1, 4) == 1: place_tile(self.game_map, y, x, '12') # Connect All Areas of Interest prev_y, prev_x = self.areas_of_interest[0].center for area in self.areas_of_interest[1:]: center_y, center_x = area.center astar = tcod.path.AStar(self.game_map.tile_cost, 1.41) path = astar.get_path(prev_x, prev_y, center_x, center_y) # print('\n\nstart:', prev_x, prev_y) # print('end:', center_x, center_y) # print('path:', path) for c_x, c_y in path: if self.game_map.tileset_tiles[c_x][c_y] == 37: # River Tile #TODO: Extend size of bridge to be (3) tiles wide place_tile(self.game_map, c_y, c_x, '12') prev_x, prev_y = center_x, center_y
def assign_terrain(self, entities, particles): # Place Floor for y in range(self.height): for x in range(self.width): if self.level[x][y] == 0: place_tile(self.game_map, x, y, "51") # create_floor(self.game_map, x, y) self.game_map.tile_cost[y][x] = 1
def assign_terrain(self): # Open floor to include a circular arena center_x, center_y = self.width // 2, self.height // 2 radius = (self.width + self.height) // 4 for x in range(self.width): for y in range(self.height): # Circular Arena if self.inside_circle(center_x, center_y, x, y, radius): place_tile(self.game_map, x, y, "51")
def generate_puddles(self, x, y): # Place Different Sized Puddles throughout Map size = randint(1, 2) place_tile(self.game_map, x, y, "17") if size == 2: # Iterate through different directions for dir_x, dir_y in [(x, y + 1), (x + 1, y), (x - 1, y), (x, y - 1), ]: if 0 <= dir_x < self.width and 0 <= dir_y < self.height: if self.grid[dir_x][dir_y] == 0: place_tile(self.game_map, dir_x, dir_y, '17')
def generate_castle_entrance(self): x = self.end_area.x y = self.end_area.y w = self.end_area.width h = self.end_area.height self.create_walled_room(x - w // 2, y, w, h, False) for _y in range(y + 1, y + w - 1): place_tile(self.game_map, _y + (x - w // 2), 0, "47") for i in range(1 + x - w // 2, x + w // 2): place_tile(self.game_map, i, y + h - 1, "35") create_floor(self.game_map, x, y + h - 1) for i in range(1 + x - w // 2, x + w // 2): create_floor(self.game_map, i, y + h)
def generate_vines(self, x, y): # Create a localized Layout of SizexSize and Use Astar to make a path for vines size = randint(2, 5) localized_layout = np.array([[1 for y in range(y-size, y+size)] for x in range(x-size, x+size)] if 0 <= x < self.width and 0 <= y < self.height else 999) astar = tcod.path.AStar(localized_layout, diagonal=1) goal_x, goal_y = (randint(x - size, x + size-1) + size, randint(y-size, y + size - 1) + size) final_path = astar.get_path(size, size, goal_x - x, goal_y - y) for i, j in final_path: if 0 <= x + i < self.width and 0 <= y + j < self.height: if self.grid[x + i][y + j] == 0: place_tile(self.game_map, x + i, y + j, "16") else: break
def assign_terrain(self, entities, particles): # Place Floor self.game_map.initialize_closed_map() for y in range(self.height): for x in range(self.width): if self.grid[x][y] == 0: place_tile(self.game_map, x, y, "51") # create_floor(self.game_map, x, y) self.game_map.tile_cost[y][x] = 1 # Place Floor Doodads for y in range(self.height): for x in range(self.width): if self.game_map.tileset_tiles[y][x] == 2: terrain = randint(1, 100) if terrain == 1: # puddle self.generate_puddles(x, y) elif terrain == 2: # vine # elif 2 <= terrain <= 10: # vine self.generate_vines(x, y)
def generate_rivers(self): # print('generate_rivers') # print(self.game_map.tile_cost) number_of_rivers = randint( 0, 1 + ((self.width + self.height) // (2 * 30))) # number_of_rivers = randint(1, 3) for i in range(number_of_rivers): river_width = randint(1, 3) # Cache River Starting Points direction = [[(0, randint(0, self.width - 1)), (self.height - 1, randint(0, self.width - 1))], [(randint(0, self.height - 1), 0), (randint(0, self.height - 1), self.width - 1)]] river_points = choice(direction) shuffle(river_points) start_x, start_y = river_points.pop() end_x, end_y = river_points.pop() # AStar Pathfind Around Obstacles to End of Area astar = tcod.path.AStar(self.game_map.tile_cost, 1.41) river_path = astar.get_path(start_x, start_y, end_x, end_y) river_path.extend([(start_x, start_y), (end_x, end_y)]) # Add Start and End points # Generate River According to Width # print('river_path:', river_path) for x, y in river_path: direction = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1), (x, y)] for c_x, c_y in direction: # TODO: Find a better way to adjust for width than this "try" statement try: 1 // (abs(c_y + 1) + c_y + 1) 1 // (abs(c_x + 1) + c_x + 1) # self.grid[c_y][c_x] = 2 place_tile(self.game_map, c_y, c_x, '37') except: pass
def create_walled_room(self, room_x, room_y, room_width, room_height, ruined=True): # Sets Tiles in to Become Passable, but add walls around for x in range(room_x, room_x + room_width): for y in range(room_y, room_y + room_height): if x == room_x or \ x == room_x + room_width - 1 or \ y == room_y or \ y == room_y + room_height - 1: if ruined: if randint(0, 100) < 80: create_wall(self.game_map, x, y) else: create_wall(self.game_map, x, y) else: if ruined and randint(0, 100) < 25: create_floor(self.game_map, x, y) else: place_tile(self.game_map, x, y, "47")
def assign_tiles(self, mold=False): # Assign Tiles from Grid for x in range(self.width): for y in range(self.height): if self.grid[x][y] == 1: if randint(0, 6) == 1 and mold: place_tile(self.game_map, x, y, '46') # normal tree else: place_tile(self.game_map, x, y, '13') # moldfy tree elif self.grid[x][y] == 0: if randint(0, 4) == 1: place_tile(self.game_map, x, y, '44') # normal grass elif randint(0, 6) == 1 and mold: place_tile(self.game_map, x, y, '45') # fungus grass else: create_floor(self.game_map, x, y)
def generate_road(self, x1, y1, x2, y2, wide=False): # Connect Roads between (2) Areas astar = tcod.path.AStar(self.game_map.tile_cost, 5) path = astar.get_path(y1, x1, y2, x2) for x, y in path: if self.game_map.tileset_tiles[y][x] == 2: if wide: place_tile(self.game_map, y, x, '12') place_tile(self.game_map, y + 1, x, '12') place_tile(self.game_map, y - 1, x, '12')
def activate_event(self, entities, particles): results = [] if self.event_type == 'spawn_mob': mob_indexes = self.function_kwargs.get('mobs') faction = self.function_kwargs.get('faction') ai_type = self.function_kwargs.get('ai_type') area = self.function_kwargs.get('area_of_interest') spawn_x, spawn_y = self.function_kwargs.get('position') target_entity = self.function_kwargs.get('target_entity') follow_entity = self.function_kwargs.get('follow_entity') origin_x = self.function_kwargs.get('origin_x') origin_y = self.function_kwargs.get('origin_y') e = Encounter(self.game_map, area, len(self.game_map.encounters) + 1, ai_type=ai_type) if self.game_map.player.position.distance_to(spawn_x, spawn_y) < 5: results.append({ 'message': Message( "You spot reinforcements coming from the above floor!", tcod.dark_yellow) }) else: results.append({ 'Message': Message("You hear barking and yelling in the distance...", tcod.dark_yellow) }) for mob_index in mob_indexes: x, y = self.game_map.obtain_closest_spawn_point( spawn_x, spawn_y) mob_stats = MOBS.get(mob_index) if x and y: self.game_map.tile_cost[y][x] = 99 entities.append( generate_mob(x, y, mob_stats, mob_index, e, faction, ai_type, entities, follow_entity=follow_entity, target_entity=target_entity, origin_x=origin_x, origin_y=origin_y)) else: print( 'Error! Coudn\'t find open spawn point for {} at ({}, {})' .format(mob_stats.get('name'), spawn_x, spawn_y)) # (x, y, mob_stats, mob_index, encounter_group, faction, ai, entities, dialogue_component=None): elif self.event_type == 'open_gate': # print('event_type:', self.event_type) map_objects = self.function_kwargs.get('map_objects') default_floor_tile = self.function_kwargs.get( 'default_floor_tile', "2") for map_object in map_objects: # print('removing : ', map_object) self.game_map.map_objects.remove(map_object) place_tile(self.game_map, map_object.position.x, map_object.position.y, default_floor_tile) # results.append({"change_map_object": [map_object, 2], "message": Message("The {} has opened!".format(map_object.name))}) results.append({ "message": Message("The {} has opened!".format(map_object.name)) }) return results
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