Exemplo n.º 1
0
def test_astar_callback(map_, path_callback):
    astar = libtcodpy.path_new_using_function(
        libtcodpy.map_get_width(map_),
        libtcodpy.map_get_height(map_),
        path_callback,
        )
    libtcodpy.path_compute(astar, *POINTS_AB)
    libtcodpy.path_delete(astar)
Exemplo n.º 2
0
def generate_map(level):
    arr = array(MAP_W, MAP_H, lambda: ' ')
    rooms = []
    for i in range(500):
        w, h = randrange(5,15), randrange(5,10)
        room = try_put_room(arr, w, h)
        if room:
            rooms.append(room)

    #randomly_place(arr, '<')
    if level < MAX_DLEVEL:
        randomly_place(arr, '>')

    costs = [(5, 40, 1),
             (5, 1, 2),
             (5, 40, 40)][3*level//(MAX_DLEVEL+1)]

    def corridor_path_func(x1, y1, x2, y2, data):
        if x2 == 0 or x2 == MAP_W-1 or y2 == 0 or y2 == MAP_H-1:
            return 0
        c = arr[x2][y2]
        if c == ' ':
            return costs[0]
        elif c == '#':
            return costs[1]
        else:
            return costs[2]


    path = T.path_new_using_function(
        MAP_W, MAP_H, corridor_path_func, None, 0.0)

    def connect(x1, y1, x2, y2):
        T.path_compute(path, x1, y1, x2, y2)
        for i in range(T.path_size(path)):
            x, y = T.path_get(path, i)
            c = arr[x][y]
            if c == '#' or c == ' ':
                arr[x][y] = '.'

    for i in range(len(rooms)-1):
        x1, y1, w1, h1 = rooms[i]
        x2, y2, w2, h2 = rooms[i+1]
        connect(x1+w1//2, y1+h1//2, x2+w2//2, y2+h2//2)

    #print_array(arr)
    T.path_delete(path)

    return array_to_tiles(arr)
Exemplo n.º 3
0
    def move_astar(self, target, entities, game_map):
        #create FOV map with dimensions of map
        fov = libtcod.map_new(game_map.width, game_map.height)

        #scan for and mark walls as blocked
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        #scan all obj to see if they must be navigated around
        #also check obj isn't self or target
        #AI class handles case if self adj to target

        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                #set tile as wall, so will be moved around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        #Allocate A* path
        # 1.41 is normal cost of diagonal, 0.0 if prohib
        my_path = libtcod.path_new_using_map(fov, 1.41)

        #compute path from self to target
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        #check if path eists, and < 25 tiles
        #path size matters if alt longer paths wanted
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y, = libtcod.path_walk(my_path, True)
            if x or y:
                #set self coord to next tile on path
                self.x = x
                self.y = y
        else:
            #normal move as fallback
            self.move_towards(target.x, target.y, game_map, entities)

        #delete path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 4
0
 def move_astar(self, target, entities, game_map):
     # Create a FOV map that has the dimensions of the map
     fov = initialize_fov(game_map)
     for entity in entities:
         if entity.blocks and entity != self and entity != target:
             # Set the tile as a wall so it must be navigated around
             tcod.map_set_properties(fov, entity.x, entity.y, True, False)
     my_path = tcod.path_new_using_map(fov, 1)
     tcod.path_compute(my_path, self.x, self.y, target.x, target.y)
     if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
         # Find the next coordinates in the computed full path
         x, y = tcod.path_walk(my_path, True)
         if x or y:
             # Set self's coordinates to the next path tile
             self.x = x
             self.y = y
     else:
         self.move_towards(target.x, target.y, game_map, entities)
     tcod.path_delete(my_path)
Exemplo n.º 5
0
    def move_astar(self, target, entities, game_map):
        # Create a FOV map that has the dimensions of the map
        fov = tcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                tcod.map_set_properties(fov, x1, y1,
                                        not game_map.tiles[x1][y1].block_sight,
                                        not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                tcod.map_set_properties(fov, entity.x, entity.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = tcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that if there are no paths (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            self.move_towards(target.x, target.y, game_map, entities)

            # Delete the path to free memory
        tcod.path_delete(my_path)
Exemplo n.º 6
0
    def move_astar(self, target, entities, game_map):
        # Create FOV map with dimensions of game map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or target (so start and end points are free
        # AI class handles case where self is next to target so no need to worry about that case
        for entity in entities:
            if entity != self and entity != target and entity.blocks:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate A* path
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute path between self and target
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if path exists, and if the path is shorter than 25 tiles
        # Makes sense to keep path size low to prevent monsters running around the map if there's an
        # alternate path far away
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # Find next coordinates in the path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Update coordinates to next tile
                self.x = x
                self.y = y
        else:
            # Kept as backup so that if there are no paths, it will still try to move towards the player
            self.move_towards(target.x, target.y, game_map, entities)

        # free memory
        libtcod.path_delete(my_path)
Exemplo n.º 7
0
Arquivo: util.py Projeto: dutt/formula
def find_path(source, target, entities, game_map):
    # Create a FOV map that has the dimensions of the map
    fov = tcod.map_new(game_map.width, game_map.height)

    # Scan the current map each turn and set all the walls as unwalkable
    for y1 in range(game_map.height):
        for x1 in range(game_map.width):
            tcod.map_set_properties(
                fov,
                x1,
                y1,
                not game_map.tiles[x1][y1].block_sight,
                not game_map.tiles[x1][y1].blocked,
            )

    # Scan all the objects to see if there are objects that must be navigated around
    # Check also that the object isn't self or the target (so that the start and the end points are free)
    # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
    for entity in entities:
        if entity.blocks and entity != source and entity != target:
            # Set the tile as a wall so it must be navigated around
            tcod.map_set_properties(fov, entity.pos.x, entity.pos.y, True,
                                    False)

    # Allocate a A* path
    # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
    my_path = tcod.path_new_using_map(fov, 0.0)

    # Compute the path between self's coordinates and the target's coordinates
    tcod.path_compute(my_path, source.pos.x, source.pos.y, target.pos.x,
                      target.pos.y)

    # Check if the path exists, and in this case, also the path is shorter than 25 tiles
    # The path size matters if you want the monster to use alternative longer paths (for example through other
    # rooms) if for example the player is in a corridor. It makes sense to keep path size relatively low to keep
    # the monsters from running around the map if there's an alternative path really far away
    has_path = not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25

    # Delete the path to free memory
    tcod.path_delete(my_path)

    return has_path
Exemplo n.º 8
0
    def move_astar(self, target, entities, game_map):
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate a A* path
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            self.move_towards(target.x, target.y, game_map, entities)

            # Delete the path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 9
0
 def move_astar(self, target, entities, game_map):
     fov = tcod.map_new(game_map.width, game_map.height)
     for y1 in range(game_map.height):
         for x1 in range(game_map.width):
             tcod.map_set_properties(fov, x1, y1,
                                     not game_map.tiles[x1][y1].block_sight,
                                     not game_map.tiles[x1][y1].blocked)
     for entity in entities:
         if entity.blocks and entity != self and entity != target:
             tcod.map_set_properties(fov, entity.x, entity.y, True, False)
     my_path = tcod.path_new_using_map(fov, 1.41)
     tcod.path_compute(my_path, self.x, self.y, target.x, target.y)
     if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
         x, y = tcod.path_walk(my_path, True)
         if x or y:
             self.x = x
             self.y = y
     else:
         self.move_towards(target.x, target.y, game_map, entities)
     tcod.path_delete(my_path)
Exemplo n.º 10
0
 def move_astar(self, target, entities, game_map):
     # Create a FOV map that has the dimensions of the map
     fov = libtcod.map_new(game_map.width, game_map.height)
     
     # Scan the current map each turn and set all walls as unwalkable
     for y1 in range(game_map.height):
         for x1 in range(game_map.width):
             libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked)
             
     # Scan all objects to see if there are objects that must be navigated around
     # Check also that object itself isn't self or target (so start and end points are free)
     # AI class handles situation if self is next to target so it will not use thia A* function anyway
     for entity in entities:
         if entity.blocks and entity != self and entity !=target:
             # Set the tile as wall so must be nav'd around
             libtcod.map_set_properties(fov, entity.x, entity.y, True, False)
             
     # Allocate a A* path
     # The 1.41  is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohib'd
     my_path = libtcod.path_new_using_map(fov, 1.41)
     
     # Compute the path between self and target's coords
     libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)
     
     # Check if path exists, and in this case if < 25 tiles
     # Path size matters if you want the monster to use alternative longer paths (eg through other rooms) if eg the player is in a corridor
     # Makes sense to keep path size low to keep monsters from taking far away alternative
     if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
         # Find next coords in computed full path
         x, y = libtcod.path_walk(my_path, True)
         if x or y:
             # Set self's coords to next path tile
             self.x = x
             self.y = y
             
     else:
         # Keep old move function as backup for when no paths exist (eg player blocks corridor)
         self.move_towards(target.x, target.y, game_map, entities)
         
         # Delete path to free mem
     libtcod.path_delete(my_path)
Exemplo n.º 11
0
    def move_astar(self, target, entities, game_map):
        fov = game_map.new_fov_map()

        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)

        my_path = libtcod.path_new_using_map(fov, 1.41)

        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y

        else:
            self.move_towards(target.x, target.y, game_map, entities)
        
        libtcod.path_delete(my_path)
Exemplo n.º 12
0
    def move_astar(self, target, entities, game_map):
        """
        Utilise l'algorithme de recherche de chemin A* pour le déplacement d'un monstre
        en direction du joueur. Est appelé dans ai.BasicMonster

        Parametres:
        ----------
        target : Entity

        entities : list

        game_map : GameMap


        Renvoi:
        -------
        Aucun

        """
        fov = libtcod.map_new(game_map.width, game_map.height)
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)
        my_path = libtcod.path_new_using_map(fov, 1.41)
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)
        libtcod.path_delete(my_path)
Exemplo n.º 13
0
    def move_astar(self, target, fov_map, game_map, entities):
        fov_map_astar = fov_map

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov_map_astar, entity.x, entity.y,
                                           True, False)

        # Allocate a A* path
        my_path = libtcod.path_new_using_map(fov_map_astar, 1.4)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths
        # (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running
        # around the map if there's an alternative path really far away
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 10:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)

            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that if there are no paths
            # (for example another monster blocks a corridor). It will still try
            # to move towards the player (closer to the corridor opening)
            self.move_towards(target, game_map, entities)

        # Delete the path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 14
0
    def move_astar(self, target, entities, game_map):
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isnt self or the target (so that the start and end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so that it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self coords and target coords
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check path Exists, then also make sure the path is shorter than 25 tiles
        # Path size matters if you want the monster to use alternative longer paths
        # It makes sense to keep path size low here
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coords to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup if there are no paths
            # It will still try to move towards the player
            self.move_towards(target.x, target.y, game_map, entities)
        libtcod.path_delete(my_path)
Exemplo n.º 15
0
    def move_astar(self, target, entities, game_map):
        # Create another FOV map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the map and set walls as blocked
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan for entities to path around
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate a A* path
        # NOTE: The diagonal movement cost is defined here, might want to put in a config somewhere
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # If the path exists and is not too long, walk along
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y

        # Use dumber pathfinding to just get closer if there is no complete path
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        # Deallocate path
        libtcod.path_delete(my_path)
Exemplo n.º 16
0
    def move_astar(self, target, entities, game_map):
        # Create FOV map that has the deminision of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, int(self.x), int(self.y), int(target.x),
                             int(target.y))

        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup, if there are no paths
            self.move_towards(target.x, target.y, game_map, entities)

        libtcod.path_delete(my_path)
Exemplo n.º 17
0
def test_astar(map_):
    astar = libtcodpy.path_new_using_map(map_)

    assert not  libtcodpy.path_compute(astar, *POINTS_AC)
    assert  libtcodpy.path_size(astar) == 0
    assert  libtcodpy.path_compute(astar, *POINTS_AB)
    assert  libtcodpy.path_get_origin(astar) == POINT_A
    assert  libtcodpy.path_get_destination(astar) == POINT_B
    libtcodpy.path_reverse(astar)
    assert libtcodpy.path_get_origin(astar) == POINT_B
    assert libtcodpy.path_get_destination(astar) == POINT_A

    assert libtcodpy.path_size(astar) != 0
    assert libtcodpy.path_size(astar) > 0
    assert not libtcodpy.path_is_empty(astar)

    for i in range(libtcodpy.path_size(astar)):
        x, y = libtcodpy.path_get(astar, i)

    while (x, y) != (None, None):
        x, y = libtcodpy.path_walk(astar, False)

    libtcodpy.path_delete(astar)
Exemplo n.º 18
0
def test_astar(map_):
    astar = libtcodpy.path_new_using_map(map_)

    assert not libtcodpy.path_compute(astar, *POINTS_AC)
    assert libtcodpy.path_size(astar) == 0
    assert libtcodpy.path_compute(astar, *POINTS_AB)
    assert libtcodpy.path_get_origin(astar) == POINT_A
    assert libtcodpy.path_get_destination(astar) == POINT_B
    libtcodpy.path_reverse(astar)
    assert libtcodpy.path_get_origin(astar) == POINT_B
    assert libtcodpy.path_get_destination(astar) == POINT_A

    assert libtcodpy.path_size(astar) != 0
    assert libtcodpy.path_size(astar) > 0
    assert not libtcodpy.path_is_empty(astar)

    for i in range(libtcodpy.path_size(astar)):
        x, y = libtcodpy.path_get(astar, i)

    while (x, y) != (None, None):
        x, y = libtcodpy.path_walk(astar, False)

    libtcodpy.path_delete(astar)
Exemplo n.º 19
0
    def move_astar(
        self,
        target,
        game_map,
        entities,
    ):
        map_copy = deepcopy(game_map)

        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                map_copy.walkable[entity.x][entity.y] = False

        astar = tcod.path.AStar(map_copy.walkable)
        new_path = astar.get_path(self.x, self.y, target.x, target.y)
        if new_path and len(new_path) < 25:
            x, y = new_path[0]
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        tcod.path_delete(new_path)
Exemplo n.º 20
0
    def move_astar(self, target, entities, game_map):
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as un-walkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around (and obj != self/target)
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate an A* path
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that if there are no paths
            self.move_towards(target.x, target.y, game_map, entities)

        libtcod.path_delete(my_path)
Exemplo n.º 21
0
    def Entity_Move(self, Self_X, Self_Y, Target_x, Target_y):
        # Checks for a number of entities which hold specific tags, (Hostile, Alien, etc) are on the current map.
        # Uses A* pathing
        fov = tcod.map_new(MAP_WIDTH, MAP_HEIGHT)
        for y1 in range(MAP_HEIGHT):
            for x1 in range(MAP_WIDTH):
                tcod.map_set_properties(fov, x1, y1, not map[x1][y1].block_sight, not map[x1][y1].blocked)

        for Entity, (Position, Blocks) in self.world.get_components(Components.Position, Components.Move_Through):
            if Blocks and not self.world.has_component(Entity, Components.Player):
                tcod.map_set_properties(fov, Position.X, Position.Y, True, False)

        My_Path = tcod.path_new_using_map(fov, 1.41)

        tcod.path_compute(My_Path, Self_X, Self_Y, Target_x, Target_y)

        if not tcod.path_is_empty(My_Path) and tcod.path_size(My_Path) < 25:
            x, y = tcod.path_walk(My_Path, True)
            if x or y:
                tcod.path_delete(My_Path)
                return x, y
        else:
            tcod.path_delete(My_Path)
            return Self_X, Self_Y
Exemplo n.º 22
0
 def path_delete(self, path):    libtcod.path_delete(path)
 # path data functions
 def path_get_cost_movement(self,xFrom,yFrom,xTo,yTo, data):
Exemplo n.º 23
0
    def act(self, game_map, player, fov_map=None, has_los=None):
        dist = self.owner.distance_to(player)

        if dist < 2:
            # Attack the player, even if the entity can't see
            return self.owner.fighter.attack_entity(player.fighter,
                                                    target_is_player=True)

        results = {}
        given_fov_map = fov_map is not None

        if (self.owner.sight and dist <= self.owner.sight.fov_radius
                or self.remaining_chase_turns > 0):
            owner_x = self.owner.x
            owner_y = self.owner.y
            player_x = player.x
            player_y = player.y

            if given_fov_map:
                tcod.map_set_properties(fov_map, owner_x, owner_y, True, True)
                tcod.map_set_properties(fov_map, player_x, player_y, True,
                                        True)
            else:
                # This second variable is necessary as creating another
                # variable called fov_map might shadow the parameter rather
                # than changing its value
                fov_map = game_map.generate_fov_map_with_entities(
                    [self.owner, player])

            if self.clairvoyant:
                # Clairvoyant entities can always sense the player when they're
                # nearby
                has_los = True

            if has_los is None:
                self.owner.sight.get_fov(fov_map)
                has_los = tcod.map_is_in_fov(fov_map, owner_x, owner_y)

            if has_los:
                # If the entity can see the player, reset the chase timer
                self.remaining_chase_turns = self.chase_duration

            chase = has_los

            if not has_los and self.remaining_chase_turns > 0:
                # Entities will continue chasing the player for chase_duration,
                # even if they don't have line of sight
                chase = True
                self.remaining_chase_turns -= 1

            if chase:
                # 1.41 approximates sqrt(2), the cost of a diagonal moves
                path = tcod.path_new_using_map(fov_map, 1.41)
                tcod.path_compute(path, owner_x, owner_y, player_x, player_y)

                if not tcod.path_is_empty(path) and tcod.path_size(path) < 25:
                    x, y = tcod.path_walk(path, True)
                    if x or y:
                        self.owner.move_to(x, y, game_map, face=True)
                else:
                    dx = player_x - owner_x
                    dy = player_y - owner_y

                    dx = int(round(dx / dist))
                    dy = int(round(dy / dist))

                    if game_map.is_tile_open(owner_x + dx, owner_y + dy):
                        self.owner.move(dx, dy, game_map)

                tcod.path_delete(path)

            if given_fov_map:
                tcod.map_set_properties(fov_map, self.owner.x, self.owner.y,
                                        True, False)
                tcod.map_set_properties(fov_map, player.x, player.y, True,
                                        False)
            else:
                tcod.map_delete(fov_map)
        else:
            if given_fov_map:
                # Remove the entity from the given FOV map
                tcod.map_set_properties(fov_map, self.owner.x, self.owner.y,
                                        True, True)

            # Wander around aimlessly
            self.owner.move(randint(-1, 1), randint(-1, 1), game_map)

            if given_fov_map:
                # Add the entity to the given FOV map
                tcod.map_set_properties(fov_map, self.owner.x, self.owner.y,
                                        True, False)

        return results