Example #1
0
    def get_map_bounds(self):
        """
        Returns a map with
        """
        left_most = 0
        right_most = 0
        top_most = 0
        bottom_most = 0

        for room in self.room_list:
            if room.position.x < left_most:
                left_most = room.position.x

            if room.position.x + room.size_vector.x > right_most:
                right_most = room.position.x + room.size_vector.x

            if room.position.y + room.size_vector.y > top_most:
                top_most = room.position.y + room.size_vector.y

            if room.position.y < bottom_most:
                bottom_most = room.position.y

        width = abs(right_most - left_most)
        height = abs(top_most - bottom_most)

        return {
            'dimensions': Vector2(width, height),
            'position': Vector2(left_most, bottom_most)
        }
Example #2
0
    def __init__(self,
                 level,
                 size_vector,
                 doors,
                 biome,
                 items,
                 enemies,
                 position=None,
                 entrance_direction=None,
                 exit_directions=None):

        self.level = level
        self.size_vector = Vector2(int(size_vector.x), int(size_vector.y))
        self.doors = doors
        self.biome = biome
        self.items = items
        self.enemies = enemies

        if not position:
            self.position = None
        else:
            self.position = Vector2(int(position.x), int(position.y))

        self.entrance_direction = entrance_direction
        self.exit_directions = exit_directions

        self.area = size_vector.x * size_vector.y
Example #3
0
def room_colision_test():
    room_1 = Room.empty(Vector2(15, 5), Vector2(-10, 10))
    room_2 = Room.empty(Vector2(15, 5), Vector2(-11, 14))
    if not room_1.check_collision(room_2):
        logger.warning('Room colision not expected!')
    room_2.position.y = 14
    if not room_1.check_collision(room_2):
        logger.warning('Room collision expected!')
Example #4
0
    def print_map(self, export_file=None):

        map_bounds = self.get_map_bounds()
        ascii_pixel_matrix = []

        for y in range(map_bounds['position'].y,
                       map_bounds['dimensions'].y + map_bounds['position'].y):
            ascii_pixel_row = ['']

            for x in range(
                    map_bounds['position'].x,
                    map_bounds['dimensions'].x + map_bounds['position'].x):

                pixel_collider = Room.empty(Vector2(1, 1), Vector2(x, y))
                collides = False

                room_level = 0
                for room in self.room_list:
                    if room.check_collision(pixel_collider):
                        collides = True
                        room_level = room.level

                if collides:
                    if room_level < 10:
                        ascii_pixel_row.append(f'{int(room_level)}')
                    else:
                        ascii_pixel_row.append('#')
                else:
                    ascii_pixel_row.append(' ')

            ascii_pixel_matrix.append(ascii_pixel_row)

        map_string = f'{map_bounds}\n'

        for room in self.room_list:
            map_string += f'Room level {room.level} dimensions: {room.size_vector}\n'

        for row in ascii_pixel_matrix:
            row_string = ''

            for pixel in row:
                row_string += pixel

            map_string = f'{map_string}\n{row_string}'

        if export_file:
            export_file = f'{os.path.dirname(os.path.realpath(__file__))}/Maps/{export_file}'

            with open(export_file, 'w') as file:
                file.seek(0)
                file.write(map_string)

        return map_string
Example #5
0
    def load_from_save(cls, attribute_dict):
        size_vector = Vector2.load_from_save(attribute_dict['size_vector'])
        position = Vector2.load_from_save(attribute_dict['position'])

        item_list = []
        for item in attribute_dict['items']:
            if item['item_stats'][
                    'item_type'] in items.Armour.armour_materials:
                item_list.append(items.Armour.load_from_save(item))

            elif item['item_stats']['item_type'] in items.Weapon.weapon_types:
                item_list.append(items.Weapon.load_from_save(item))

            elif item['item_stats']['item_type'] == 'chest':
                item_list.append(items.Chest.load_from_save(item))

        enemy_dict = []
        for enemy in attribute_dict['enemies']:
            enemy_dict.append(creatures.EnemyHumanoid.load_from_save(enemy))

        return cls(attribute_dict['level'], size_vector,
                   attribute_dict['doors'], attribute_dict['biome'], item_list,
                   enemy_dict, position)
Example #6
0
def map_bounds_test():
    room_list = [Room.empty(Vector2(15, 5), Vector2(15, -5)),
                 Room.empty(Vector2(15, 5), Vector2(-10, 12)),
                 Room.empty(Vector2(15, 5), Vector2(-11, 1))]

    map_bounds = Map(None, None, room_list).get_map_bounds()
    if list(map_bounds['position']) != [-11, -5]:
        logger.warning('map position wrong')
        print(map_bounds)
    if list(map_bounds['dimensions']) != [41, 22]:
        logger.warning('map dimentions wrong')
Example #7
0
    async def generate_map(cls,
                           map_size=None,
                           connectivity=None,
                           biome=None,
                           level=None,
                           level_interval=1,
                           current_map=[],
                           special_rooms=[],
                           special_room_occurance=0.01,
                           client=None,
                           progress_message=None):
        """
        Generates a series of linked rooms
        :param map_size: number of rooms in the map
        :param connectivity: how many hallways in the map
        :param biome: map biome
        :param level: map starting level, goes up by level_interval for each room
        :param current_map: The map that this map will build upon
        :param special_rooms: list of premade rooms
        :param special_room_occurance: how often premade rooms appear as percent (0, 1)
        :return: Map instance
        """

        start_time = datetime.datetime.now()

        if not map_size:
            map_size = random.randint(5, 30)
            logger.debug(map_size)

        if not connectivity:
            connectivity = random.uniform(0, 1)

        if not biome:
            biome = Room.biome_list[random.randint(0,
                                                   len(Room.biome_list) - 1)]

        if not level:
            level = 1

        if current_map:
            room_list = current_map
        else:
            room_list = [
                Room(items=None,
                     enemies=None,
                     doors={
                         'north': True,
                         'south': False,
                         'east': False,
                         'west': False
                     },
                     position=Vector2.zero(),
                     size_vector=Vector2(random.randint(2, 8),
                                         random.randint(2, 8)),
                     biome=biome,
                     level=level,
                     entrance_direction=None,
                     exit_directions=['north'])
            ]

        map_size = int(map_size)
        level = int(level)

        message_content = progress_message.content
        progress_message = await client.edit_message(
            progress_message, message_content + f'\nProgress: []')

        list_index = 0
        while list_index <= map_size - 2:
            last_room = room_list[list_index]
            room_succesful = False
            level += level_interval

            entrance_direction = GameObject.opposite_direction(
                last_room.exit_directions[random.randint(
                    0,
                    len(last_room.exit_directions) - 1)])

            room_tries = 0
            while room_tries < 100:

                doors = {
                    'north': random.randint(0, 1) == 1,
                    'south': random.randint(0, 1) == 1,
                    'east': random.randint(0, 1) == 1,
                    'west': random.randint(0, 1) == 1
                }
                pass  # get rid of pycharm formatting bug
                doors[entrance_direction] = True

                exit_directions = []

                for direction in doors:
                    if direction != entrance_direction and doors[direction]:
                        exit_directions.append(direction)

                if len(exit_directions) == 0:
                    # room_tries += 1
                    # logger.debug(f'No exit {room_tries}')
                    continue

                if random.uniform(
                        0,
                        1) < special_room_occurance and len(special_rooms) > 0:

                    room = special_rooms[random.randint(
                        0,
                        len(special_rooms) - 1)]

                else:

                    room = Room(items=None,
                                enemies=None,
                                doors=doors,
                                biome=biome,
                                level=level,
                                position=Vector2.zero(),
                                size_vector=Vector2(random.randint(2, 20),
                                                    random.randint(2, 20)),
                                entrance_direction=entrance_direction,
                                exit_directions=exit_directions)

                # if room is above last_room
                if entrance_direction == 'north':
                    room.position.x = random.randint(
                        last_room.position.x - room.size_vector.x + 1,
                        last_room.position.x + last_room.size_vector.x - 1)

                    room.position.y = int(last_room.position.y +
                                          last_room.size_vector.y)

                # if room is below last_room
                elif entrance_direction == 'south':
                    room.position.x = random.randint(
                        last_room.position.x - room.size_vector.x + 1,
                        last_room.position.x + last_room.size_vector.x - 1)

                    room.position.y = int(last_room.position.y -
                                          room.size_vector.y)

                # if room to the right of last_room
                elif entrance_direction == 'east':
                    room.position.x = int(last_room.position.x +
                                          last_room.size_vector.x)

                    room.position.y = room.position.y = random.randint(
                        last_room.position.y - room.size_vector.y + 1,
                        last_room.position.y + last_room.size_vector.y - 1)

                # if room to the left of last_room
                elif entrance_direction == 'west':
                    room.position.x = int(last_room.position.x -
                                          room.size_vector.x)

                    room.position.y = random.randint(
                        last_room.position.y - room.size_vector.y + 1,
                        last_room.position.y + last_room.size_vector.y - 1)

                if room.check_all_collision(room_list):
                    room_tries += 1
                    # logger.debug(f'room tries: {room_tries}')
                    continue

                room_list.append(room)
                logger.info(f'Generated level {level} room')
                # last_room = room
                room_tries = 100000
                room_succesful = True
                wip_map = Map(level, biome, room_list)
                wip_map.print_map(f'{level}.txt')
                list_index += 1

            if not room_succesful:
                logger.info(f'level {level} room unsuccesful')
                level -= 1 * level_interval
                for _ in range(0, 5):
                    if list_index > 0:
                        level -= int(1 * level_interval)
                        list_index -= 1
                        del (room_list[-1])

            progress_string = GameObject.progress_bar(
                int((len(room_list) / map_size) * 100), map_size)

            progress_message = await client.edit_message(
                progress_message,
                message_content + f'\nProgress: {progress_string}')

        # for room in room_list:
        #     for other_room in room_list:
        #
        #         hallway = None
        #
        #         # if room is underneath or above other_room
        #         if cls.check_horizontal_alignment(room, other_room) and \
        #                 random.uniform(0, 1) < connectivity:
        #
        #             hallway_pos = Vector2.zero()
        #             hallway_size = Vector2(2, 0)
        #
        #             # if room is below other_room
        #             if room.position.y - other_room.position.y < 0:
        #                 if other_room.position.y - room.position.y < 15 > 2 and \
        #                         room.doors['north'] and other_room.doors['south']:
        #
        #                     hallway_pos.y = room.position.y + room.size_vector.y
        #                     hallway_size.y = other_room.position.y - room.position.y + room.size_vector.y
        #
        #                     if hallway_size.y < 2:
        #                         continue
        #                 else:
        #                     continue
        #
        #             # if room is above other_room
        #             elif room.position.y - other_room.position.y > 0:
        #                 if room.position.y - other_room.position.y < 15 > 2 and \
        #                         room.doors['south'] and other_room.doors['north']:
        #
        #                     hallway_pos.y = other_room.position.y + other_room.size_vector.y
        #                     hallway_size.y = room.position.y - other_room.position.y + other_room.size_vector.y
        #
        #                     if hallway_size.y < 2:
        #                         continue
        #                 else:
        #                     continue
        #
        #             hallway_pos.x = ((room.position.x + room.size_vector.x / 2) +
        #                              (other_room.position.x + other_room.size_vector.x / 2)) // 2
        #
        #             hallway = Room.generate_room(doors={
        #                 'north': True,
        #                 'south': True,
        #                 'east': False,
        #                 'west': False},
        #                 level=int(level/2),
        #                 size_vector=hallway_size,
        #                 position=hallway_pos
        #             )
        #
        #             if hallway.check_all_collision(room_list):
        #                 hallway = None
        #             else:
        #                 logger.debug(f'Created vertical hallway between {hallway.position.y} and {hallway.position.y + hallway.size_vector.y}')
        #
        #         # if room is to the left or right of other_room
        #         if cls.check_vertical_alignment(room, other_room) and \
        #                 random.uniform(0, 1) < connectivity:
        #
        #             hallway_pos = Vector2.zero()
        #             hallway_size = Vector2(0, 2)
        #
        #             # if room is to the left of other room
        #             if room.position.x - other_room.position.x < 0:
        #                 if other_room.position.x - room.position.x < 15 and \
        #                         room.doors['east'] and other_room.doors['west']:
        #
        #                     hallway_pos.x = room.position.x + room.size_vector.x
        #                     hallway_size.x = other_room.position.x - room.position.x + room.size_vector.x
        #
        #                     if hallway_size.x < 2:
        #                         continue
        #                 else:
        #                     continue
        #
        #             # if room is to the right of other_room
        #             else:
        #                 if room.position.x - other_room.position.x < 15 and \
        #                         room.doors['west'] and other_room.doors['east']:
        #
        #                     hallway_pos.x = other_room.position.x + other_room.size_vector.x
        #                     hallway_size.x = room.position.x - other_room.position.x + other_room.size_vector.x
        #
        #                     if hallway_size.x < 2:
        #                         continue
        #                 else:
        #                     continue
        #
        #             hallway_pos.y = ((room.position.y + room.size_vector.y / 2) +
        #                              (other_room.position.y + other_room.size_vector.y / 2)) // 2
        #
        #             hallway = Room.generate_room(doors={
        #                 'north': False,
        #                 'south': False,
        #                 'east': True,
        #                 'west': True},
        #                 level=int(level / 2),
        #                 size_vector=hallway_size,
        #                 position=hallway_pos
        #             )
        #
        #             if hallway.check_all_collision(room_list):
        #                 hallway = None
        #             else:
        #                 logger.debug(f'Created horizontal hallway between {hallway.position.x} and {hallway.position.x + hallway.size_vector.x}')
        #
        #         if hallway:
        #             room_list.append(hallway)
        #             await asyncio.sleep(0.1)

        room_list.sort(key=Map.room_level_sort_key)

        for room in room_list:
            populated_room = Room.generate_room(
                room.doors,
                room.size_vector,
                room.level,
                biome=biome,
                position=room.position,
                entrance_direction=room.entrance_direction,
                exit_directions=room.exit_directions)
            room_list.remove(room)
            room_list.append(populated_room)

        generation_time = datetime.datetime.now() - start_time
        logger.info(f'Map of size {map_size} generated in {generation_time}')

        return cls(level, biome, room_list)
Example #8
0
 def generate_collider_grid(cls, size_vector=Vector2.zero()):
     pass
Example #9
0
    def generate_room(cls,
                      doors=None,
                      size_vector=None,
                      level=None,
                      enemy_power=None,
                      total_loot=None,
                      biome=None,
                      enemy_distribution=None,
                      loot_distribution=None,
                      position=None,
                      entrance_direction=None,
                      exit_directions=None):

        if not doors:
            doors = {
                'north': random.randint(0, 1) == 1,
                'south': random.randint(0, 1) == 1,
                'east': random.randint(0, 1) == 1,
                'west': random.randint(0, 1) == 1,
            }
        if not size_vector:
            size_vector = Vector2(0, 0)
            size_vector.x = random.randint(2, 20)
            size_vector.y = random.randint(2, 20)
        if not level:
            level = GameObject.get_level() * 10

        if not enemy_power:
            enemy_power = (level**2 * GameObject.get_level() *
                           1) - (random.randint(-5, 13))

        if not total_loot:
            total_loot = GameObject.get_level() * (
                (size_vector.x * size_vector.y) /
                500) * (level**2 - GameObject.zero_to_range(level**2))

        if not biome:
            biome = cls.biome_list[random.randint(0, len(cls.biome_list) - 1)]

        if not enemy_distribution:
            enemy_distribution = random.uniform(0.5, 2)

        if not loot_distribution:
            loot_distribution = random.uniform(0.5, 2)

        level = int(level)
        enemy_power = int(enemy_power)
        total_loot = int(total_loot)

        loot_list = items.Item.generate_loot(level, total_loot,
                                             loot_distribution)

        chest_list = []
        for _ in range(0, 3):
            if random.uniform(0, 1) < 0.1 or len(loot_list) > 5:
                chest_inventory = []
                chest_value = total_loot
                chest_value = chest_value // 3

                while chest_value > 0 and len(loot_list) > 0:
                    loot_item = loot_list[-1]
                    chest_inventory.append(loot_item)
                    chest_value -= loot_item.total_value
                    loot_list.remove(loot_item)

                chest_list.append(items.Chest(None, chest_inventory))

        for chest in chest_list:
            chest.position = Vector2(random.randint(0, size_vector.x),
                                     random.randint(0, size_vector.y))

            chest.inventory.sort(key=items.Item.value_sort_key, reverse=True)
            loot_list.append(chest)

        for item in loot_list:
            item.position = Vector2(random.randint(0, size_vector.x),
                                    random.randint(0, size_vector.y))

        enemy_list = creatures.EnemyHumanoid.generate_enemies(
            level, enemy_power, enemy_distribution)
        enemy_list.sort(key=creatures.Creature.power_sort_key, reverse=True)

        for enemy in enemy_list:
            enemy.position = Vector2(random.randint(0, size_vector.x),
                                     random.randint(0, size_vector.y))

        room_instance = cls(level, size_vector, doors, biome, loot_list,
                            enemy_list, position, entrance_direction,
                            exit_directions)

        return room_instance
Example #10
0
 def empty(cls, size_vector=Vector2.zero(), position=Vector2.zero()):
     return cls(None, size_vector, None, None, None, None, position, None,
                None)