Ejemplo n.º 1
0
    def path_towards_astar(self, game, origin, target):
        # getting the fov vamp from currentDrawMap doesn't work in debug mode since it isn't initialized
        # so for the moment I'm recomputing it every time, it's super wasteful but the game chugs along nicely
        fov = libtcod.map_new(self.width, self.height)

        list(
            map(
                lambda tile: libtcod.map_set_properties(
                    fov, tile.x, tile.y, tile.trasparent, not tile.block),
                self.get_map_list()))

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

        my_path = libtcod.path_new_using_map(fov, 0.0)

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

        return_direction = (0, 0)
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 30:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                x1 = 1 if origin.x < x else -1 if origin.x > x else 0
                y1 = 1 if origin.y < y else -1 if origin.y > y else 0
                return_direction = (x1, y1)
        else:
            return_direction = self.get_step_towards(origin.x, origin.y,
                                                     target.x, target.y)

        libtcod.path_delete(my_path)
        return return_direction
Ejemplo n.º 2
0
    def set_spawns(self):

        stop = False
        for i in range(200):
            self.randomize_spawn()
            for j in range(1000):
                self.randomize_monster_spawn()

                path = libtcod.path_new_using_map(self.map.pathdata, 0)
                libtcod.path_compute(path, self.spawn[0], self.spawn[1],
                                     self.monster_spawn[0],
                                     self.monster_spawn[1])
                siz = libtcod.path_size(path)

                libtcod.path_delete(path)

                print siz
                if siz < 16 or siz > 40:
                    break
                else:
                    stop = True
                    print siz
                    break

            if stop:
                break

        print 'done?'

        if stop:
            return True
        else:
            return False
Ejemplo n.º 3
0
 def move_astar(self, source, target, map):
     if self.has_required_components(source) and self.has_required_components(target):
         src = source.get_component(Components.POSITION)
         fov = source.get_component(Components.FOV)
         trg = target.get_component(Components.POSITION)
         # 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 map.entities:
             if self.has_required_components(entity):
                 pos = entity.get_component(Components.POSITION)
                 if pos.solid and entity != source and entity != target:
                     # Set the tile as a wall so it must be navigated around
                     tcod.map_set_properties(fov.fov, pos.x, 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.fov, 1.41)
         # Compute the path between self's coordinates and the target's coordinates
         tcod.path_compute(my_path, src.x, src.y, trg.x, trg.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
                 src.x = x
                 src.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.basic_movement.move_towards(trg.x, trg.y, map)
             # Delete the path to free memory
             tcod.path_delete(my_path)
Ejemplo n.º 4
0
    def move_astar(self, target, entities, game_map):
        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)

        max_path_length = 25

        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < max_path_length:
            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)
Ejemplo n.º 5
0
	def move_astar(self, target):
		fov = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT)
		
		#set move, sight blockers
		for y1 in range(MAP_HEIGHT):
			for x1 in range(MAP_WIDTH):
				libtcod.map_set_properties(fov, x1, y1, not map[x1][y1].sight_blocker, not map[x1][y1].move_blocker)
			
		#Treat tiles occupied by monsters as move blocked
		for obj in objects:
			if obj.move_blocker and obj != self and obj != target:
				libtcod.map_set_properties(fov, obj.x, obj.y, True, False)
				
		#Allocate path. Use roguelike geometry (diagonals = cardinals).
		my_path = libtcod.path_new_using_map(fov, 1.0)
		
		#Compute path
		libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)
		
		#Confirm path was found, and is short, then take step.
		if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < MAX_ASTAR_PATH_LENGTH:
			x, y = libtcod.path_walk(my_path, True)
			if x or y:
				#self.move takes dx, dy so don't use that
				self.x = x
				self.y = y
		#If the path is bad, take direct path to player.
		#This happens if, say, player is behind a monster in a corridor.
		else:
			self.move_towards(target.x, target.y)
			
		#Deallocate path memory
		libtcod.path_delete(my_path)
Ejemplo n.º 6
0
    def moveAStar(self, target, entities, gameMap):
        # Create a new FOV map
        fov = tcod.map_new(gameMap.mapWidth, gameMap.mapHeight)
        # Scan current map and set all walls as unwalkable
        for y1 in range(gameMap.mapHeight):
            for x1 in range(gameMap.mapWidth):
                tcod.map_set_properties(fov, x1, y1,
                                        not gameMap.tiles[x1][y1].blockSight,
                                        not gameMap.tiles[x1][y1].blocked)

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

        # Allocate A* Path - No Diagonal Movement
        path = tcod.path_new_using_map(fov, 0.0)
        # Compute path
        tcod.path_compute(path, self.x, self.y, target.x, target.y)

        # Check if path exists and is shorter than 25 moves
        if not tcod.path_is_empty(path) and tcod.path_size(path) < 25:
            x, y = tcod.path_walk(path, recompute = True)
            # Set X and Y coordinates
            if x or y:
                self.x = x
                self.y = y
        else:
            # Backup Move Function
            self.moveTowards(target.x, target.y, gameMap, entities)
        
        tcod.path_delete(path)
Ejemplo n.º 7
0
    def move_astar(self, target):
        fov = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT)

        for y1 in range(MAP_HEIGHT):
            for x1 in range(MAP_WIDTH):
                libtcod.map_set_properties(fov, x1, y1,
                                           not map[x1][y1].block_sight,
                                           not map[x1][y1].blocked)

        for obj in objects:
            if obj.blocks and obj != self and obj != target:
                libtcod.map_set_properties(fov, obj.x, obj.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)

        libtcod.path_delete(my_path)
Ejemplo n.º 8
0
def astar(source, target):
    # create a FOV map that has the dimensions of the map
    fov = lib.map_new(var.MAP_WIDTH, var.MAP_HEIGHT)

    # scan the current map each turn and set all walls as unwalkable
    for y1 in range(var.MAP_HEIGHT):
        for x1 in range(var.MAP_WIDTH):
            lib.map_set_properties(fov, x1, y1, not var.map[x1][y1].block_sight, not var.map[x1][y1].blocked)

    # scan all objects to see if there are objects that must be navigated around
    # check also that the object isn't self or the target (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 ent in var.entities:
        if ent.blocks and ent != var.player and ent != target:
            # set the tile as a wall so it must be navigated around
            lib.map_set_properties(fov, ent.x, ent.y, True, False)
    # allocate the A* path
    # The 1.41 is the normal diagonal cost of moving, set to 0 if diagonals are prohibited
    my_path = lib.path_new_using_map(fov, 1.41)
    # compute the path between self's coordinates and the targets
    lib.path_compute(my_path, source.x, source.y, target.x, target.y)

    # check if the path exists, and in this case, also the path is shorter than 25 tiles
    if not lib.path_is_empty(my_path) and lib.path_size(my_path) < 25:
        # find the next coordinates in the computed full path
        (x, y) = lib.path_walk(my_path, True)
    else:
        (x, y) = (None, None)

    # delete the path
    lib.path_delete(my_path)
    return x, y
Ejemplo n.º 9
0
    def move_astar(self,
                   target,
                   entities,
                   game_map,
                   check_explored=False,
                   max_path=25):
        # 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):
                if check_explored:
                    libtcod.map_set_properties(
                        fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                        not game_map.tiles[x1][y1].blocked
                        and game_map.tiles[x1][y1].explored)
                else:
                    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
        # 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'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) < max_path:
            # 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
                return True
            else:
                return False
        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)
            return self.move_towards(target.x, target.y, game_map, entities)

            # Delete the path to free memory
        libtcod.path_delete(my_path)
Ejemplo n.º 10
0
 def moveTo(self, x, y, facility):
     """Cancel the current path and take a general direction.
     If the move is illegal, do not change the current path."""
     self.currentPath = None
     self.currentPath = facility.circulation.path_from_to(
         self.location.getX(), self.location.getY(), x, y)
     if libtcod.path_size(self.currentPath) == 0:
         libtcod.path_delete(self.currentPath)
         self.currentPath = None
Ejemplo n.º 11
0
    def get_move_cost(self, pos1, pos2):

        path = libtcod.path_new_using_map(self.path_map, 0)
        libtcod.path_compute(path, pos1[0], pos1[1], pos2[0], pos2[1])
        siz = libtcod.path_size(path)

        libtcod.path_delete(path)

        return siz
Ejemplo n.º 12
0
def move_astar(entity, entities, target, fov_map):
    """Use the A* algorithm to find a path to target, returning the next step along that path"""

    # TODO: maybe we re-use the existing fov map, but just un-set this entity and the target temporarily
    # that should save an entities iteration for making everything but entity and target unwalkable

    # Create a FOV map that has the dimensions of the map
    fov = libtcod.map_new(init.map_width, init.map_height)

    # Scan the current map each turn and set all the walls as unwalkable
    for ent in entities:
        if ent != entity and ent != target and 'Position' in ent:
            libtcod.map_set_properties(fov, ent['Position']['x'], ent['Position']['y'], ent['Opacity'] < 0.5, ent['Solid'] < 0.5)

    # 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's coordinates and the target's coordinates
    libtcod.path_compute(my_path, entity['Position']['x'], entity['Position']['y'], target['Position']['x'], target['Position']['y'])

    # Debugging A*
    for i in range (libtcod.path_size(my_path)):
        (x, y) = libtcod.path_get(my_path, i)
        for ent in entities:
            if (i < libtcod.path_size(my_path) - 1) and 'Position' in ent and ent['Position']['x'] == x and ent['Position']['y'] == y and 'A*Highlight' in ent:
                ent['A*Highlight'] = True

    # 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) < 25:
        # Find the next coordinates in the computed full path
        (next_x, next_y) = libtcod.path_walk(my_path, True)
        dx = next_x - entity['Position']['x']
        dy = next_y - entity['Position']['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)
        (dx, dy) = from_a_to_b(entity['Position']['x'], entity['Position']['y'], target['Position']['x'], target['Position']['y'])

    # Delete the path to free memory
    libtcod.path_delete(my_path)
    return (dx, dy)
Ejemplo n.º 13
0
 def moveTo(self, x, y, facility):
     """Cancel the current path and take a general direction.
     If the move is illegal, do not change the current path."""
     self.currentPath = None
     self.currentPath = facility.circulation.path_from_to(self.location.getX(),
                                     self.location.getY(),
                                     x,
                                     y)
     if libtcod.path_size(self.currentPath) == 0:
         libtcod.path_delete(self.currentPath)
         self.currentPath = None
Ejemplo n.º 14
0
 def batAiUpdate(self, player):
   path = libtcod.path_compute(self.path, self.creature.x, self.creature.y, player.x, player.y)
   if path:
     length = libtcod.path_size(self.path)
     if length > 1:#self.creature.attackRange
       (x, y) = libtcod.path_walk(self.path, False)
       self.creature.moveTo(x, y)
     else:
       self.creature.attackCreature(player)
       
   else:
     pass
Ejemplo n.º 15
0
    def get_astar_distance_to(self, x, y, target_x, target_y):
        ''' Gets distance using A* algo - how far an entity would actually have to walk to get somewhere '''
        # Handle case where the target is the same as the initial location
        if (x, y) == (target_x, target_y):
            return 0

        # Otherwise, compute the path
        libtcod.path_compute(self.path_map, x, y, target_x, target_y)
        # A length of 0 here should mean that it was not possible to reach the location
        # It could mean that the initial loc == the target loc, but we've tested that above
        new_path_len = libtcod.path_size(self.path_map)

        # Therefore, a len of 0 here should mean unreachable - so return None
        return new_path_len if new_path_len else None
Ejemplo n.º 16
0
    def process(self, game):
        visible =self.game.fov.is_visible(self.x, self.y)
        moved = False

        if visible:
            self.seen += 1
            self.color = tcod.color_lerp(tcod.dark_gray, self.orig_color,
                                         (self.seen % 50) / 100.0)
            if self.seen % 50 == 0:
                self.game.duplicate(self)

            if self.seen == 200:
                self.character = 'o'
                self.movement = 0.4

            elif self.seen == 400:
                self.character = 'O'
                self.movement = 0.6

            path = tcod.path_new_using_map(self.game.fov.fov, 1.0)
            tcod.path_compute(path, self.x, self.y, self.game.player.x,
                              self.game.player.y)

            if tcod.path_size(path) > 2:
                self.points += self.movement
                if self.points >= 1:
                    self.points -= 1
                    x, y = tcod.path_get(path, 1)
                    self.move(x - self.x, y - self.y)
                    moved = True
            tcod.path_delete(path)

        if not moved:
            self.points += self.movement
            if self.points >= 1:
                self.points -= 1
                movement = [
                    (0, 0),
                    (0, 1),
                    (0, -1),
                    (1, 0),
                    (-1, 0),
                    (1, 1),
                    (-1, -1),
                    (-1, 1),
                    (1, -1)
                ]
                self.move(*random.choice(movement))

        return True
Ejemplo 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)
Ejemplo n.º 18
0
    def get_astar_distance_to(self, x, y, target_x, target_y):
        ''' Gets distance using A* algo - how far an entity would actually have to walk to get somewhere '''
        # Handle case where the target is the same as the initial location
        if (x, y) == (target_x, target_y):
            return 0

        # Otherwise, compute the path
        libtcod.path_compute(self.path_map, x, y, target_x, target_y)
        # A length of 0 here should mean that it was not possible to reach the location
        # It could mean that the initial loc == the target loc, but we've tested that above
        new_path_len = libtcod.path_size(self.path_map)

        # Therefore, a len of 0 here should mean unreachable - so return None
        return new_path_len if new_path_len else None
Ejemplo n.º 19
0
 def compute_path(self, world_map, creature):
     if not creature.is_at_pos(self.dest):
         self.path = world_map.path_from_to(creature.to_pos(), self.dest)
         self.path_length = tcod.path_size(self.path)
         if self.path_length == 0:
             self.fail()
             raise ImpossibleTask('No path from %d, %d, %d to %d, %d, %d' %
                                  (creature.to_pos() + self.dest))
         # The tick time MUST be reset, in case we recompute path
         # during the task.
         self.tick_time = 0
     else:
         self.path = None
         self.path_length = 0
         self.finish()
Ejemplo n.º 20
0
Archivo: astar.py Proyecto: nwolfe/pyro
def astar(game, from_pos, to_pos):
    # Create a FOV map that has the dimensions of the map
    fov = game.stage.map.make_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 actor in game.stage.actors:
        if actor.pos.x != to_pos.x and actor.pos.y != to_pos.y:
            # Set the tile as a wall so it must be navigated around
            libtcod.map_set_properties(fov, actor.pos.x, actor.pos.y, isTrans=True, isWalk=False)

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

    # Compute the path between self's coordinates and the target's coordinates
    libtcod.path_compute(path, from_pos.x, from_pos.y, to_pos.x, to_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). 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(path) and libtcod.path_size(path) < 25:
        # Find the next coordinates in the computed full path
        next_x, next_y = libtcod.path_walk(path, True)
        libtcod.path_delete(path)
        return pyro.direction.from_vector(next_x - from_pos.x, next_y - from_pos.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).
        # Vector from this object to the target, and distance
        dx = to_pos.x - from_pos.x
        dy = to_pos.y - from_pos.y
        distance = math.sqrt(dx ** 2 + dy ** 2)

        # Normalize it to length 1 (preserving direction), then round it and
        # convert to integer so the movement is restricted to the map grid
        dx = int(round(dx / distance))
        dy = int(round(dy / distance))
        libtcod.path_delete(path)
        return pyro.direction.from_vector(dx, dy)
Ejemplo n.º 21
0
    def move_astar(self, target):
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT)

        # Scan the current map each turn and set all the wall unwalkable
        for y1 in range(MAP_HEIGHT):
            for x1 in range(MAP_WIDTH):
                libtcod.map_set_properties(fov, x1, y1, not map[x1][y1].block_sight,
                                           not map[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 obj in objects:
            if obj.blocks and obj != self and obj != target:
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov, obj.x, obj.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving (sqrt(2)).
        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
        #
        # 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) < 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 (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)

        # Delete the path to free memory
        libtcod.path_delete(my_path)
Ejemplo n.º 22
0
    def move_astar(self, target):
        import Pathing
        print "Astar for " + self.name

        path = Pathing.astar((self.x, self.y), (target.x, target.y))

        if not path:
            return False

        self.path = libtcod.path_new_using_map(Fov.get_fov_map(), 1.41)
        libtcod.path_compute(self.path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(
                self.path) and libtcod.path_size(self.path) < 75:
            self.walk_path()
        else:
            self.move_towards(target.x, target.y)
Ejemplo n.º 23
0
    def move_astar(self, target, entities, game_map):
        # create FOV map that has dimensions of game map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # scan current map each turn and set all walls to be blocking
        for y in range(game_map.height):
            for x in range(game_map.width):
                libtcod.map_set_properties(
                    fov,
                    x,
                    y,
                    not game_map.tiles[x][y].block_sight,
                    not game_map.tiles[x][y].blocked
                )

        # Scan all objects to see if something needs to be navigated around.
        # Also check that the object isn't self or the target.
        # Ignore situation where self is next to target -- AI class handles this.
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)  # set wall so it must be navigated around

        # Allocate A* path.
        # 1.41 is the normalized diagonal cost of moving. If diagonal movement is not allowed, then set to 0.
        my_path = libtcod.path_new_using_map(fov, 1.41)

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

        # Check if path exists and is shorter than 25 tiles.
        # Keep path size low to prevent monsters from running around the map.
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in computed full path.
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to next path tile
                self.x = x
                self.y = y
        else:
            # Keep old move function as a backup e.g. if something blocks a doorway,
            # self will still move towards target.
            self.move_towards(target.x, target.y, game_map, entities)

        # delete path to free memory
        libtcod.path_delete(my_path)
Ejemplo n.º 24
0
    def move_astar(self, target, entities, game_map):
        # マップの寸法を持つFOVマップを作成。
        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)

        # すべてのオブジェクトをスキャンして,移動しなければならないオブジェクトがあるかどうかを確認
        # オブジェクトが自己または対象ではないことも確認(開始点と終了点が自由になるように)。
        # AIクラスは、自己がターゲットの隣にいる場合の状況を処理するので、このA*関数を使用しない。
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # タイルを壁として設定し,その周りを移動.
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # A*pathを割り当てる
        # 1.41は通常の対角線上の移動コストで、対角線上の移動が禁止されている場合は0.0とすることができる。
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # 自己の座標とターゲットの座標の間のpathを計算.
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # pathが存在するかどうかを確認し,この場合もpathが25タイルより短いかどうかを確認
        # 例えばプレイヤーが廊下にいる場合など、モンスターに別の長めのパスを使わせたい場合、pathの大きさは重要になる
        # もし本当に遠くに代替の道があるならば、モンスターがマップを走り回らないようにするために、pathのサイズを比較的小さくしておくのは理にかなっている。
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # 計算されたfull pathの次の座標を探す
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # 次のpathタイルに自己の座標を設定
                self.x = x
                self.y = y
        else:
            # 古い移動機能をバックアップとして残しておくことで,パスがない場合(例えば他のモンスターが通路を塞いでしまった場合)には,その機能を利用することができる.
            # プレイヤーに向かって移動しようとする(通路の開口部に近づけます)
            self.move_towards(target.x, target.y, game_map, entities)

            # 空きメモリへのpathを削除します
        libtcod.path_delete(my_path)
Ejemplo n.º 25
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
		# 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'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) < 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 (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)
Ejemplo n.º 26
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 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 an A* path
        # 1.41 is diagonal cost of moving
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute path between self's coordinate 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 (e.g. through other rooms) if e.g. the player is in a corridor
        # Makes sense to keep relatively low to stop monsters running around map
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            # Find 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 old move function as a backup
            self.move_towards(target.x, target.y, game_map, entities)

        # Delete path to free memory
        libtcod.path_delete(my_path)
Ejemplo n.º 27
0
    def move_astar(self, target, entities, game_map):
        # create a fov map at the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # scan 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 objets to see if there are objects that must be navigated around.
        # check also if object isn't self or the target
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                #set the tile as a wall so it muyst be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # allocate a A* path
        # 1.31 normal diag cost of moving, to put to 0 if diagonal forbiden
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # compute path between self coordinates and the target coordinate
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # check if path exists && shorter than 25 tiles
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # find next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # set self coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # old move function if no path
            self.move_towards(target.x, target.y, game_map, entities)

        # delete the path to free memeory
        libtcod.path_delete(my_path)
Ejemplo n.º 28
0
def can_hear(obj, x,y, volume):
    if ( on(obj,DEAD) or on(obj,DEAF) or not obj.stats.get('hearing') ):
         return False
    dist=maths.dist(obj.x, obj.y, x, y)
    maxHearDist=volume*obj.stats.get('hearing')/AVG_HEARING
    if (obj.x == x and obj.y == y): return (0,0,maxHearDist,)
    if dist > maxHearDist: return False
    # calculate a path
    path=path_init_sound()
    path_compute(path, obj.x,obj.y, x,y)
    pathSize=libtcod.path_size(path)
    if dist >= 2:
        semifinal=libtcod.path_get(path, 0)
        xf,yf=semifinal
        dx=xf - obj.x
        dy=yf - obj.y
    else:
        dx=0
        dy=0
    path_destroy(path)
    loudness=(maxHearDist - pathSize - (pathSize - dist))
    if loudness > 0:
        return (dx,dy,loudness)
Ejemplo n.º 29
0
	def tick(self,world):
		if self.explored: return
		if not self.goal:
			[self.goal,self.path] = self.findExplorePoint(world)
			if not self.goal:
				path=world.getPathable()
				self.explored=True
				unseen=0
				for n in path:
					if not world.isSeen(n[0],n[1]):unseen=unseen+1
				
				print "Exploration done,",unseen,"unseen tiles"
				
				return
			self.path_progress=0
		
		[next_x,next_y]=libtcod.path_get(self.path, self.path_progress)
		self.x=next_x
		self.y=next_y
		self.path_progress=self.path_progress+1
		if libtcod.path_size(self.path)==self.path_progress:
			self.goal=None
			self.path=None
Ejemplo n.º 30
0
    def move_astar(self, target):
        # Create a FOV map for the actor in question
        fov = tcod.map_new(settings.MAP_WIDTH, settings.MAP_HEIGHT)

        # Scan the current map and set all walls as unwalkable
        for y1 in range(settings.MAP_HEIGHT):
            for x1 in range(settings.MAP_WIDTH):
                tcod.map_set_properties(
                    fov, x1, y1, not settings.dungeon_map[x1][y1].block_sight,
                    not settings.dungeon_map[x1][y1].blocked)

        # Scan all objects to see if anything must be navigated around
        # Check also that the object isn't self or the target (so that start and endpoints are free)
        for obj in settings.objects:
            if obj.blocks and obj != self and obj != target:
                tcod.map_set_properties(fov, obj.x, obj.y, True, False)

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

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

        # Check if the path exists and is shorter than 25 tiles
        # The path size matters for the monster to use alternative longer paths (player in another room, corridor, etc)
        # If the path size is too big monsters will run weird routes around the map
        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:
                # set self's coords to the next path tile
                self.combatant.set_direction(x - self.x, y - self.y)
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y)

        tcod.path_delete(my_path)
Ejemplo n.º 31
0
def map_init_dungeon(width, height):
    def path_cost(xFrom, yFrom, xTo, yTo, alg_array):
        if alg_array[xTo][yTo] == 0:
            return 1
        if alg_array[xTo][yTo] == 3:
            return 0.01
        else:
            return 10

    room_prefabs_10x10 = []
    f = open('resources/map_prefabs/map_prefabs[10x10].csv',
             'r').read().split('\n')  # 10x10
    for i in range(len(f[0]) // 10):
        for j in range(len(f) // 10):
            room = ''
            for y in range(10):
                for x in range(10):
                    room += f[j * 10 + x][i * 10 + y]
            room_prefabs_10x10.append(room)
    room_prefabs_5x5 = []
    f = open('resources/map_prefabs/map_prefabs[5x5].csv',
             'r').read().split('\n')  # 10x10
    for i in range(len(f[0]) // 5):
        for j in range(len(f) // 5):
            room = ''
            for y in range(5):
                for x in range(5):
                    room += f[j * 5 + x][i * 5 + y]
            room_prefabs_5x5.append(room)
    monsters_pool = [[game_content.m_slime], []]

    alg_array = [[0 for j in range(height)] for i in range(width)]
    terrain = [[0 for j in range(height)] for i in range(width)]
    items = []
    entities = []
    creatures = []

    rooms = []
    room_exits = []
    room_connections = []
    rooms_size = [(10, 10), (5, 5)]

    rooms.append((width // 2 - 3, height // 2 - 3, 6, 6))
    for x in range(width // 2 - 3, width // 2 + 3):
        for y in range(height // 2 - 3, height // 2 + 3):
            if y == height // 2 and (x == width // 2 - 3
                                     or x == width // 2 + 3):
                alg_array[x][y] = 7
                room_exits.append((x, y, -1))
            else:
                alg_array[x][y] = 2
    available_spots = [
        (x, y) for x in range(width) for y in range(height)
        if x > 6 and x < width - 12 and y > 6 and y < height - 12
    ]
    for x in range(len(available_spots)):
        append = True
        i, j = available_spots.pop(random.randint(0, len(available_spots) - 1))
        w, h = random.choice(rooms_size)
        newRoom = (i, j, w, h)  #X, Y, W, H
        for room in rooms:
            if util.rectangle_intersects(newRoom, room):
                append = False
        if append == True:
            rooms.append(newRoom)
    for roomIndex in range(len(rooms))[0:]:
        room = rooms[roomIndex]
        if room[2] == 10 and room[3] == 10:
            room_layout = random.choice(room_prefabs_10x10)
            for x in range(room[2]):
                for y in range(room[3]):
                    alg_array[x + room[0]][y + room[1]] = int(
                        room_layout[x * 10 + y])
                    if int(room_layout[x * 10 + y]) == 7:
                        room_exits.append(
                            (x + room[0], y + room[1], roomIndex))
        elif room[2] == 5 and room[3] == 5:
            room_layout = random.choice(room_prefabs_5x5)
            for x in range(room[2]):
                for y in range(room[3]):
                    alg_array[x + room[0]][y + room[1]] = int(
                        room_layout[x * 5 + y])
                    if int(room_layout[x * 5 + y]) == 7:
                        room_exits.append(
                            (x + room[0], y + room[1], roomIndex))
    for exit_init in room_exits:
        path = libtcodpy.path_new_using_function(width, height, path_cost,
                                                 alg_array, 0)
        other_exits = sorted([
            exit_other
            for exit_other in room_exits if exit_other[2] != exit_init[2] and (
                exit_other[2], exit_init[2]) not in room_connections
        ],
                             key=lambda e: util.simpledistance(
                                 (exit_init[0], exit_init[1]), (e[0], e[1])))
        if len(other_exits) > 0:
            exit_end = other_exits[0]
        else:
            exit_end = sorted([
                exit_other
                for exit_other in room_exits if exit_other[2] != exit_init[2]
            ],
                              key=lambda e: util.simpledistance(
                                  (exit_init[0], exit_init[1]),
                                  (e[0], e[1])))[0]
        room_connections.append((exit_init[2], exit_end[2]))
        room_connections.append((exit_end[2], exit_init[2]))
        libtcodpy.path_compute(path, exit_init[0], exit_init[1], exit_end[0],
                               exit_end[1])
        for i in range(libtcodpy.path_size(path) - 1):
            x, y = libtcodpy.path_get(path, i)
            alg_array[x][y] = 3

    for x in range(len(alg_array)):
        for y in range(len(alg_array[x])):
            if alg_array[x][y] in [0, 1]:
                terrain[x][y] = game_content.t_cave_wall(x, y)
            else:
                terrain[x][y] = game_content.t_cave_floor(x, y)
            if alg_array[x][y] == 4:
                creatures.append(
                    random.choice(monsters_pool[GAME.level])(x, y))
            if alg_array[x][y] == 7:
                entities.append(
                    game_content.n_door(
                        x, y,
                        game_content.SPRITESHEET_ENTITIES.image_at(
                            (0, 32, 32, 32)),
                        game_content.SPRITESHEET_ENTITIES.image_at(
                            (32, 32, 32, 32),
                            colorkey=game_constants.COLOR_COLORKEY)))
                terrain[x][y].passable = False
                terrain[x][y].transparent = False
    return terrain, items, entities, creatures
Ejemplo n.º 32
0
def libtcod_path_to_list(path_map):
    ''' get a libtcod path into a list '''
    return [
        libtcod.path_get(path_map, i)
        for i in xrange(libtcod.path_size(path_map))
    ]
Ejemplo n.º 33
0
    def get_astar_distance_to(self, x, y, target_x, target_y):
        libtcod.path_compute(self.path_map, x, y, target_x, target_y)
        new_path_len = libtcod.path_size(self.path_map)

        return new_path_len
Ejemplo n.º 34
0
    def update(self):
        tcod_map = self.game.dungeon.tcod_map        
        if not self.path:
            self.path = libtcod.path_new_using_map(tcod_map)

        pos = self.entity.pos
        visible = self.game.player.fov(*pos)
    
        done = False
        while not done:
            if self.state == AI_INACTIVE: #not used yet
                done = True
            elif self.state == AI_SLEEPING:
                wake_up = False
                for s in self.sounds:
                    if self.game.rng.percent(min(95,s[0]*(self.creature.perception+5)/10)):
                        wake_up = True
                if self.creature.health < self.creature.max_health:
                    wake_up = True
                if wake_up:
                    self.state = AI_RESTING
                    self.entity.notify(Event(EVENT_WAKE_UP,
                                            actor=self.entity))
                else: #continue sleeping
                    done = True

            elif self.state == AI_RESTING:
                self.creature.fov.refresh()
                if self.check_for_player():
                    self.state = AI_FIGHTING
                    self.entity.notify(Event(EVENT_NOTICE,
                                            actor=self.entity))
                else: #continue to rest or wander?
                    if self.game.rng.percent(20):
                        done = True
                    else:
                        self.state = AI_WANDERING

            elif self.state == AI_WANDERING:
                self.creature.fov.refresh()
                if self.check_for_player():
                    self.state = AI_FIGHTING
                    self.entity.notify(Event(EVENT_NOTICE,
                                            actor=self.entity))
                else:
                    direction = (0,0)
                    while not (self.valid_movement(direction) or
                               self.game.cur_level.get_tile(self.entity.x+direction[0],self.entity.y+direction[1]).creature==self.game.player):

                        directions = [(1,1),(1,-1),(-1,1),(-1,-1),
                                      (0,1),(0,-1),(1,0),(-1,0)]
                        if self.prev_dir:
                            directions += [self.prev_dir]*6
                            if self.prev_dir[0]==0:
                                directions += [(1,self.prev_dir[1])]*2
                                directions += [(-1,self.prev_dir[1])]*2
                            elif self.prev_dir[1]==0:
                                directions += [(self.prev_dir[0],1)]*2
                                directions += [(self.prev_dir[0],-1)]*2
                            else:
                                directions += [(self.prev_dir[0],0)]*2
                                directions += [(0,self.prev_dir[1])]*2
                        direction = self.game.rng.choose(directions)
                    t = self.game.cur_level(self.entity.x+direction[0],
                                            self.entity.y+direction[1])
                    if self.game.rng.percent(10):
                        self.state = AI_RESTING
                        done=True
                    elif t.creature is self.game.player:
                        self.entity.notify(EVENT_NOTICE,
                                          actor=self.entity)
                        self.state = AI_FIGHTING
                    else:
                        self.entity.move_to(self.entity.x+direction[0],
                                           self.entity.y+direction[1])
                        self.prev_dir=direction
                        done=True

            elif self.state == AI_FIGHTING:
                if self.creature.fov(*self.game.player.pos):
                    self.last_saw_player = 0
                else: #increase last_saw_player and fall asleep if it's been too long
                    self.last_saw_player += 1
                    if self.last_saw_player >= 5:
                        self.state = AI_SLEEPING

                new_player_pos = self.game.player.pos #get latest player pos and recalculate path if needed
                if self.player_pos != new_player_pos:
                    self.player_pos = new_player_pos
                    self.compute_path(*self.player_pos)

                if (self.path_index < libtcod.path_size(self.path)
                    and self.game.player.creature.alive):#walk path
                    x,y = libtcod.path_get(self.path, self.path_index)
                    event = self.entity.move_to(x,y)
                    if event.event_type == EVENT_MOVE: #successfully moved, increase path index
                        self.path_index += 1
                        done = True
                    elif self.entity.distance_to(*self.player_pos) < 2:
                        #didn't move but can attack player
                        self.creature.attack(self.game.player)
                        done = True
                    else: #didn't move or attack, try new path
                        self.compute_path(*self.player_pos)
                else: #end of path and don't know where to go now
                    done = True

        self.sounds = []
        if self.state != AI_INACTIVE and self.state != AI_SLEEPING:
            self.creature.fov.refresh()
Ejemplo n.º 35
0
 def size(self):
     return libtcod.path_size(self.path)
Ejemplo n.º 36
0
    def get_astar_distance_to(self, x, y, target_x, target_y):
        libtcod.path_compute(self.path_map, x, y, target_x, target_y)
        new_path_len = libtcod.path_size(self.path_map)

        return new_path_len
Ejemplo n.º 37
0
	def findExplorePoint(self,world):
		if self.explored: return (False,False) #expecting a list
		t0 = time.time()
		
		px=self.x
		py=self.y
		
		ww=world.getWidth()
		wh=world.getHeight()
		
		# Scan in expanding circle outwards
		distance=1
		edge=1
		searchEffort=60
		pathEffort=3
		
		potentials=[]
		edges=[1,2,3,4]
		goodPath=False
		
		while not goodPath:
			while len(potentials)<=searchEffort:
				# scan edges
				for i in edges:
					for j in xrange(edge):
						[cx,cy]=self.edgeCalc(i,j,edge,distance)
						if cx<0 or cx>=ww: continue
						if cy<0 or cy>=wh: continue
						if world.isBlocked(cx,cy) or world.isSeen(cx,cy): continue
						#if world.isPathable(cx,cy):
						potentials.append((cx,cy))
							#world.putThing(cx,cy)
							
				# and corners
				for i in edges:
					[cx,cy]=self.cornerCalc(i,distance,px,py)
					if cx<0 or cx>=ww: continue
					if cy<0 or cy>=wh: continue
					if world.isBlocked(cx,cy) or world.isSeen(cx,cy): continue
					#if world.isPathable(cx,cy):
					potentials.append((cx,cy))
						#world.putThing(cx,cy)
						
				distance=distance+1
				edge=edge+2
				
				if distance>max(ww*2,wh*2):
					if len(potentials): break
					self.explored=True
					return (False,False)
			
			
			#print len(potentials)
			# now pop random for effort amount and pick shortest path
			distRank={}
			for cd in potentials:
				dst=abs(px-cd[0])+abs(py-cd[1])
				while dst in distRank: dst=dst+1
				distRank[dst]=cd
			
			potentials=[]
			dkKeys=sorted(distRank)
			for i in xrange(min(searchEffort,len(dkKeys))):
				potentials.append(distRank[dkKeys[i]])
				#world.putThing(potentials[i][0],potentials[i][1])
				
			pselect=random.sample(potentials,min(pathEffort,len(dkKeys)))
			distRank={}
			if not self.pathMap: self.pathMap=world.getBlockedMap()
			for cd in pselect:
				#world.putThing(cd[0],cd[1],"*")
				path=libtcod.path_new_using_map(self.pathMap,0)
				libtcod.path_compute(path,self.x,self.y,cd[0],cd[1])
				ps=libtcod.path_size(path)
				if ps==0: 
					print "Zero-len path:",cd,px,py
					print "Is blocked:",world.isBlocked(cd[0],cd[1])
					print "Is pathable:",world.isPathable(cd[0],cd[1])
					print "Is seen:",world.isSeen(cd[0],cd[1])
				
				while ps in distRank: ps=ps+1
				distRank[ps]=(cd,path)
			
			# get closest path len - if it is very high compared to distance, reject and expand search
			dkKeys=sorted(distRank)
			if dkKeys[0] < distance*4 and dkKeys[0]>0:
				ret=distRank[dkKeys[0]]
				goodPath=True
				print "Successful search at pl",dkKeys[0],"distance",distance,"took",int(math.floor((time.time()-t0)*1000)),"ms"
			else:
				print "Rejected search at pl",dkKeys[0],"distance",distance,"took",int(math.floor((time.time()-t0)*1000)),"ms"
		
		return ret
Ejemplo n.º 38
0
Archivo: helpers.py Proyecto: pangal/it
def libtcod_path_to_list(path_map):
    ''' get a libtcod path into a list '''
    return [libtcod.path_get(path_map, i) for i in xrange(libtcod.path_size(path_map))]
Ejemplo n.º 39
0
 def read_path(self, path, limit):
     if not libtcod.path_is_empty(path):
         if libtcod.path_size(path) <= limit:
             x, y = libtcod.path_walk(path, True)
             return [x, y]
     libtcod.path_delete(path)
Ejemplo n.º 40
0
 def size(self):
     return libtcod.path_size(self.path)
Ejemplo n.º 41
0
def render_map():
	# recompute FOV if needed (the player moved or something)
	libtcod.console_rect(0, game.MAP_X, game.MAP_Y, game.MAP_WIDTH, game.MAP_HEIGHT, True)
	if game.fov_recompute:
		find_map_viewport()
		fov_radius()
		initialize_fov(True)
		libtcod.map_compute_fov(game.fov_map, game.char.x, game.char.y, game.FOV_RADIUS, game.FOV_LIGHT_WALLS, game.FOV_ALGO)
		game.fov_recompute = False

	# 'torch' animation
	if game.fov_torch:
		game.fov_torchx += 0.2
		tdx = [game.fov_torchx + 20.0]
		dx = libtcod.noise_get(game.fov_noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5
		tdx[0] += 30.0
		dy = libtcod.noise_get(game.fov_noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5
		di = 0.4 * libtcod.noise_get(game.fov_noise, [game.fov_torchx], libtcod.NOISE_SIMPLEX)

	# go through all tiles, and set their background color according to the FOV
	for y in range(game.MAP_HEIGHT):
		for x in range(game.MAP_WIDTH):
			px = x + game.curx
			py = y + game.cury
			if not libtcod.map_is_in_fov(game.fov_map, px, py):
				if game.draw_map and game.current_map.tile_is_explored(px, py):
					if game.current_map.tile_is_animated(px, py):
						libtcod.console_put_char_ex(game.con, x, y, game.current_map.tile[px][py]['icon'], game.current_map.tile[px][py]['dark_color'], game.current_map.tile[px][py]['dark_back_color'])
					else:
						libtcod.console_put_char_ex(game.con, x, y, game.current_map.tile[px][py]['icon'], game.current_map.tile[px][py]['dark_color'], game.current_map.tile[px][py]['back_dark_color'])
			else:
				if not game.fov_torch:
					if 'animate' in game.current_map.tile[px][py] or 'duration' in game.current_map.tile[px][py]:
						(front, back, game.current_map.tile[px][py]['lerp']) = render_tiles_animations(px, py, game.current_map.tile[px][py]['color'], game.current_map.tile[px][py]['back_light_color'], game.current_map.tile[px][py]['back_dark_color'], game.current_map.tile[px][py]['lerp'])
						libtcod.console_put_char_ex(game.con, x, y, game.current_map.tile[px][py]['icon'], front, back)
					elif game.draw_map:
						libtcod.console_put_char_ex(game.con, x, y, game.current_map.tile[px][py]['icon'], game.current_map.tile[px][py]['color'], game.current_map.tile[px][py]['back_light_color'])
				else:
					base = game.current_map.tile[px][py]['back_light_color']
					r = float(px - game.char.x + dx) * (px - game.char.x + dx) + (py - game.char.y + dy) * (py - game.char.y + dy)
					if r < game.SQUARED_TORCH_RADIUS:
						l = (game.SQUARED_TORCH_RADIUS - r) / game.SQUARED_TORCH_RADIUS + di
						if l < 0.0:
							l = 0.0
						elif l > 1.0:
							l = 1.0
						base = libtcod.color_lerp(base, libtcod.gold, l)
					libtcod.console_put_char_ex(game.con, x, y, game.current_map.tile[px][py]['icon'], game.current_map.tile[px][py]['color'], base)
				if not game.current_map.tile_is_explored(px, py):
					game.current_map.tile[px][py].update({'explored': True})

	# draw all objects in the map (if in the map viewport), except the player who his drawn last
	for obj in reversed(game.current_map.objects):
		if obj.y in range(game.cury, game.cury + game.MAP_HEIGHT) and obj.x in range(game.curx, game.curx + game.MAP_WIDTH) and game.current_map.tile_is_explored(obj.x, obj.y) and obj.name != 'player':
			if game.draw_map and obj.entity is not None:
				if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y) and not obj.entity.is_identified():
					skill = game.player.find_skill('Mythology')
					if (game.player.skills[skill].level * 0.8) + 20 >= roll_dice(1, 100):
						obj.entity.flags.append('identified')
						game.message.new('You properly identify the ' + obj.entity.unidentified_name + ' as ' + obj.entity.get_name(True) + '.', game.turns)
						game.player.skills[skill].gain_xp(3)
			if obj.entity is not None and not obj.entity.is_identified():
				obj.draw(game.con, libtcod.white)
			else:
				obj.draw(game.con)
	game.char.draw(game.con)
	libtcod.console_blit(game.con, 0, 0, game.MAP_WIDTH, game.MAP_HEIGHT, 0, game.MAP_X, game.MAP_Y)
	game.draw_map = False

	# move the player if using mouse
	if game.mouse_move:
		if mouse_auto_move() and not libtcod.path_is_empty(game.path):
			game.char.x, game.char.y = libtcod.path_walk(game.path, True)
			game.fov_recompute = True
			game.player_move = True
		else:
			items_at_feet()
			game.mouse_move = False

	# check where is the mouse cursor if not in the act of moving while using the mouse
	if not game.mouse_move:
		(mx, my) = (game.mouse.cx - game.MAP_X, game.mouse.cy - 1)
		px = mx + game.curx
		py = my + game.cury
		game.path_dx = -1
		game.path_dy = -1
		if my in range(game.MAP_HEIGHT) and mx in range(game.MAP_WIDTH):
			libtcod.console_set_char_background(0, mx + game.MAP_X, my + 1, libtcod.white, libtcod.BKGND_SET)
			if game.current_map.tile_is_explored(px, py) and not game.current_map.tile_is_blocked(px, py):
				game.path_dx = px
				game.path_dy = py
				if game.mouse.lbutton_pressed:
					target = [obj for obj in game.current_map.objects if obj.y == py and obj.x == px and obj.entity]
					if target:
						mouse_auto_attack(px, py, target[0])
					else:
						game.mouse_move = mouse_auto_move()
				# draw a line between the player and the mouse cursor
				if not game.current_map.tile_is_blocked(game.path_dx, game.path_dy):
					libtcod.path_compute(game.path, game.char.x, game.char.y, game.path_dx, game.path_dy)
					for i in range(libtcod.path_size(game.path)):
						x, y = libtcod.path_get(game.path, i)
						if (y - game.cury) in range(game.MAP_HEIGHT) and (x - game.curx) in range(game.MAP_WIDTH):
							libtcod.console_set_char_background(0, game.MAP_X + x - game.curx, game.MAP_Y + y - game.cury, libtcod.desaturated_yellow, libtcod.BKGND_SET)

	libtcod.console_set_default_foreground(0, libtcod.light_yellow)
	libtcod.console_print_rect(0, game.MAP_X, game.MAP_Y, game.MAP_WIDTH - 18, game.MAP_HEIGHT, get_names_under_mouse())
	if game.debug.enable:
		libtcod.console_print_ex(0, game.MAP_X + game.MAP_WIDTH - 1, game.MAP_Y, libtcod.BKGND_NONE, libtcod.RIGHT, str(game.gametime.hour) + ':' + str(game.gametime.minute).rjust(2, '0') + ' (%3d fps)' % libtcod.sys_get_fps())
	if game.hp_anim:
		render_floating_text_animations()