Exemplo n.º 1
0
    def get_path_pos(self, pos1, pos2, dist):

        chemin = libtcod.path_new_using_map(self.path_map, 0)
        print pos1, pos2
        libtcod.path_compute(chemin, pos1[0], pos1[1], pos2[0], pos2[1])
        print libtcod.path_is_empty(chemin)

        x, y = libtcod.path_get(chemin, dist)

        #	for i in range(dist):
        #		x,y=libtcod.path_walk(path,False)
        #	print x,y
        libtcod.path_delete(chemin)
        return [x, y]
Exemplo n.º 2
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)
Exemplo n.º 3
0
def find_astar(origin, dest, 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.is_opaque(
                (x1, y1)), game_map.is_passable((x1, y1)))

    # 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 pos in [actor.pos for actor in game_map.actors]:
        if pos != origin and pos != dest:
            # Set the tile as a wall so it must be navigated around
            tcod.map_set_properties(fov, pos[0], pos[1], True, False)

    # Allocate a A* path
    my_path = tcod.path_new_using_map(fov, 1)

    # Compute the path between self's coordinates and the target's coordinates
    tcod.path_compute(my_path, origin[0], origin[1], dest[0], dest[1])

    # Check if the path exists
    if not tcod.path_is_empty(my_path):
        # Find the next coordinates in the computed full path
        x, y = tcod.path_walk(my_path, True)
        # Delete the path to free memory
        tcod.path_delete(my_path)
        if x or y:
            delta = (x - origin[0], y - origin[1])
            for act, move in MOVES.items():
                if move == delta:
                    return act
Exemplo n.º 4
0
    def move_astar_xy(self, target_x, target_y, force=False):
        if self.path is None or force:
            # print "a* self.path is None"
            # Create a FOV map that has the dimensions of the map

            if self.x == target_x and self.y == target_y:
                return

            # 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(
                GameState.current_level.get_fov_map(), 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):
                self.path = my_path
                return self.walk_path()
            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)
                return False
        else:
            # print "Had path so walked it"
            return self.walk_path()
Exemplo 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)
Exemplo n.º 6
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)
Exemplo n.º 7
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)
Exemplo n.º 8
0
def missile_attack(sx, sy, dx, dy, trap=False):
	cx, cy = sx, sy
	if sx == dx:
		char = '|'
	if sy == dy:
		char = chr(196)
	if (sx < dx and sy > dy) or (sx > dx and sy < dy):
		char = '/'
	if (sx < dx and sy < dy) or (sx > dx and sy > dy):
		char = '\\'
	path = util.set_full_explore_map(game.current_map, False)
	libtcod.path_compute(path, sx, sy, dx, dy)
	while not libtcod.path_is_empty(path):
		cx, cy = libtcod.path_walk(path, False)
		libtcod.console_blit(game.con, 0, 0, game.MAP_WIDTH, game.MAP_HEIGHT, 0, game.MAP_X, game.MAP_Y)
		libtcod.console_put_char_ex(0, game.MAP_X + cx - game.curx, game.MAP_Y + cy - game.cury, char, libtcod.light_gray, libtcod.black)
		libtcod.console_flush()
		time.sleep(0.05)

	if trap:
		for obj in game.current_map.objects:
			if obj.x == dx and obj.y == dy and not obj.item:
				damage = util.roll_dice(1, 6)
				if obj.name == 'player':
					game.message.new('You are hit by an arrow for ' + str(damage) + ' pts of damage!', game.turns, libtcod.Color(160, 0, 0))
					game.player.take_damage(damage, 'an arrow trap')
				else:
					obj.entity.take_damage(obj.x, obj.y, damage, 'an arrow', True)
Exemplo n.º 9
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
Exemplo n.º 10
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)
Exemplo n.º 11
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
Exemplo n.º 12
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)
Exemplo n.º 13
0
def libtcod_path_to_list(path_map):
    ''' get a libtcod path into a list '''
    path = []
    while not libtcod.path_is_empty(path_map):
        x, y = libtcod.path_walk(path_map, True)
        path.append((x, y))

    return path
Exemplo n.º 14
0
 def takepath(self):
     # libtcod.path_compute(game.player.path, game.player.destination[0], game.player.destination[1], ...)
     if libtcod.path_is_empty(self.path):
         return "empty"
     else:
         x, y = libtcod.path_get(self.path, 0)
         self.owner.x, self.owner.y = libtcod.path_walk(self.path, True)
         return "pathing"
Exemplo n.º 15
0
def libtcod_path_to_list(path_map):
    ''' get a libtcod path into a list '''
    path = []
    while not libtcod.path_is_empty(path_map):
        x, y = libtcod.path_walk(path_map, True)
        path.append((x, y))

    return path
Exemplo n.º 16
0
    def move(self):
        if self.move_stat != 50 - self.speed:
            self.move_stat += 1 
            return
        else:
        	self.move_stat = 0

        if not libtcod.path_is_empty(self.path):
        	self.x,self.y = libtcod.path_walk(self.path, True)
Exemplo n.º 17
0
	def path_to(self, dx, dy):
		# use algorithm to move (A*)
		path = libtcod.path_new_using_map(fov_map,1.41)
		libtcod.path_compute(path, self.owner.x, self.owner.y, dx, dy)	
		if not libtcod.path_is_empty(path):
			x,y = libtcod.path_walk(path,True)
			if not x is None:
				self.move_towards(x,y)
		libtcod.path_delete(path)
Exemplo n.º 18
0
def path_effect(game,ox,oy,dx,dy,decay_time):
    libtcod.path_compute(game.path,ox,oy,dx,dy)
    px,py = ox,oy
    while not libtcod.path_is_empty(game.path):
        x,y = libtcod.path_walk(game.path,True)
        cell = line_directions[(px-x,py-y)]
        px,py = x,y
        p = Particle(x,y,decay_time,libtcod.yellow,cell,game.ticker,game.con)
        game.particles.append(p)
Exemplo n.º 19
0
def connected_cells(source, target):

    my_path = libtcod.path_new_using_map(Engine.Fov.get_fov_map(), 1.41)

    libtcod.path_compute(my_path, source[0], source[1], target[0], target[1])

    if not libtcod.path_is_empty(my_path):
        return True
    else:
        return False
Exemplo n.º 20
0
def path_effect(game, ox, oy, dx, dy, decay_time):
    libtcod.path_compute(game.path, ox, oy, dx, dy)
    px, py = ox, oy
    while not libtcod.path_is_empty(game.path):
        x, y = libtcod.path_walk(game.path, True)
        cell = line_directions[(px - x, py - y)]
        px, py = x, y
        p = Particle(x, y, decay_time, libtcod.yellow, cell, game.ticker,
                     game.con)
        game.particles.append(p)
Exemplo n.º 21
0
def connected_cells(source, target):

    my_path = libtcod.path_new_using_map(Engine.Fov.get_fov_map(), 1.41)

    libtcod.path_compute(my_path, source[0], source[1], target[0], target[1])

    if not libtcod.path_is_empty(my_path):
        return True
    else:
        return False
Exemplo n.º 22
0
 def test(self, abs_src_x, abs_src_y, abs_dst_x, abs_dst_y):
     self.compute_path_abs(abs_src_x, abs_src_y, abs_dst_x, abs_dst_y)
     if libtcod.path_is_empty(self.path):
         log.info("Path is empty")
     while True:
         loc = libtcod.path_walk(self.path, False)
         if loc != (None, None):
             loc_abs = (loc[0] + self.x_start, loc[1] + self.y_start)
             log.info("abs ({},{})".format(*loc_abs))
             #print("({},{})".format(*loc))
         else:
             break
Exemplo n.º 23
0
 def takepath(self, game):
     #libtcod.path_compute(game.player.path, game.player.destination[0], game.player.destination[1], ...)
     if libtcod.path_is_empty(self.path):
         return 'empty'
     else:
         #x,y = libtcod.path_get(self.path, 0)
         x, y = libtcod.path_walk(self.path, True)
         if (x, y) == (None, None):
             return 'empty'
         self.owner.x, self.owner.y = x, y
         #if self.move(game, dx, dy) == 'blocked':
             #return 'empty'
         return 'pathing'
Exemplo n.º 24
0
    def check_stairs_reachable(self, player, endtile):
        star = libtcod.map_new(self.width, self.height)

        for y1 in range(self.height):
            for x1 in range(self.width):
                libtcod.map_set_properties(star, x1, y1,
                                           not self.tiles[x1][y1].block_sight,
                                           not self.tiles[x1][y1].blocked)

        path = libtcod.path_new_using_map(star, 1)
        libtcod.path_compute(path, player.x, player.y, endtile[0], endtile[1])

        if libtcod.path_is_empty(path):
            return False
        return True
Exemplo n.º 25
0
Arquivo: astar.py Projeto: 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)
Exemplo n.º 26
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)
Exemplo n.º 27
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)
Exemplo n.º 28
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)
Exemplo n.º 29
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)
Exemplo n.º 30
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)
Exemplo n.º 31
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)
Exemplo n.º 32
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)
Exemplo n.º 33
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)
Exemplo n.º 34
0
def render(mouse):
    libtcod.console_clear(0)
    libtcod.console_clear(unit_panel.console)
    main_map.draw(0, cam)
    
    #unit_panel rendering

    #unit rendering
    libtcod.console_set_alignment(0, libtcod.CENTER)
    libtcod.console_set_default_background(0, libtcod.black)

    for u in main_map.units:
    	u.draw(0,cam)
        #Draw name function
        if (u.x == mouse.cx + cam.x and u.y == mouse.cy + cam.y) or u == main_map.selected_unit:
            libtcod.console_print(0, u.x - cam.x, u.y - cam.y -1, u.name)
            #Draw the destination if moving
            x,y = libtcod.path_get_destination(u.path)
            if not libtcod.path_is_empty(u.path):
        	    libtcod.console_set_char(0, x - cam.x, y - cam.y, libtcod.CHAR_ARROW_S)
    
    unit_panel.draw(main_map)
Exemplo n.º 35
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.º 36
0
    def move_to_target(self, Map):
        #dx = x - owner.x
        #dy = y - owner.y
        #distance = math.sqrt(dx ** 2 + dy ** 2)

        #dx = int(round(dx / distance))
        #dy = int(round(dy / distance))
        #self.owner.move(dx, dy)
        
        #if path doesnt exist make new path to target
        owner = self.owner
        target = owner.target
        fov_map = Map.fov_map
        path = libtcod.path_new_using_map(fov_map)
        libtcod.path_compute(path, owner.x, owner.y, target.x, target.y)
        
        # use the path ... 
        if not libtcod.path_is_empty(path) :
            x,y=libtcod.path_walk(path,True)
            if not x is None :
                owner.put(x,y)
                
        owner.moved = True
Exemplo n.º 37
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)
Exemplo n.º 38
0
    def take_turn(self, gamemap_instance):

        mymap = gamemap_instance.level
        object_list = gamemap_instance.objects

        if not self.is_pathmap_created:
            self.create_path(gamemap_instance)

        if not libtcod.path_is_empty(self.path):
            pathx, pathy = libtcod.path_walk(self.path, True)
            #print 'Explorer is trying to move from (' + str(self.owner.x) + ', ' + str(self.owner.y) + 
                #') to (' + str(pathx) + ', ' + str(pathy) +').'
            dx = pathx - self.owner.x
            dy = pathy - self.owner.y
            distance = 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))
            move(gamemap_instance, self.owner, dx, dy)        
        else:
            #print 'The Explorer ' + self.owner.name + ' has finished their path. Choosing a new one...'
            self.create_path(gamemap_instance)
Exemplo n.º 39
0
def move_player(x, y):
    # Set globals.
    global turns, fov_recompute

    # Create path.
    player_path = roguelib.path_new_using_map(fov_map, 1.41)

    # Compute path to walk.
    roguelib.path_compute(player_path, player.x, player.y, x, y)

    while not roguelib.path_is_empty(player_path):

        xx, yy = roguelib.path_walk(player_path, True)

        if not is_blocked(xx, yy):
            # Move player.
            player.x = xx
            player.y = yy

            # Increase turns.
            turns += 1

            # Recompute FOV.
            fov_recompute = True
Exemplo n.º 40
0
def move_player(x, y):
    # Set globals.
    global turns, fov_recompute

    # Create path.
    player_path = roguelib.path_new_using_map(fov_map, 1.41)

    # Compute path to walk.
    roguelib.path_compute(player_path, player.x, player.y, x, y)

    while not roguelib.path_is_empty(player_path):

        xx, yy = roguelib.path_walk(player_path, True)

        if not is_blocked(xx, yy):
            # Move player.
            player.x = xx
            player.y = yy

            # Increase turns.
            turns += 1

            # Recompute FOV.
            fov_recompute = True
Exemplo n.º 41
0
    def take_turn(self, gamemap_instance):
        """
        Current bugs:
        1) The worked-on Tile doesn't turn to gravel- why not?
        2) The loop doesn't really go back around. They don't pick a new target, especially if they
            get stuck while walking. They just give up after the first time they bump into something
            dynamic. 
        """
        fov_map = gamemap_instance.fov_map
        object_list = gamemap_instance.objects
        mymap = gamemap_instance.level

        if not self.is_pathmap_created:
            print 'Builder needs to create_path'
            self.create_path(gamemap_instance)

        if not libtcod.path_is_empty(self.path):
            pathx, pathy = libtcod.path_walk(self.path, True)
            #print 'Explorer is trying to move from (' + str(self.owner.x) + ', ' + str(self.owner.y) + 
                #') to (' + str(pathx) + ', ' + str(pathy) +').'
            dx = pathx - self.owner.x
            dy = pathy - self.owner.y
            distance = 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))
            move(gamemap_instance, self.owner, dx, dy)        
        elif self.work_target[0] is not None:
            (x, y) = self.work_target
            (my_x, my_y) = self.owner.x, self.owner.y

            # The following logic checks to see if they are standing in any of the 8 squares around
            # the target Tile. I definitely had to draw a diagram for this.
            if ((my_x+1 == x) and ( (my_y+1 == y) or (my_y == y) or (my_y-1 == y)) ) \
                or ((my_x == x) and ( (my_y+1 == y) or (my_y == y) or (my_y-1 == y)) ) \
                or ((my_x-1 == x) and ( (my_y+1 == y) or (my_y == y) or (my_y-1 == y)) ):

                # We have arrived at a Tile that needs work done. Now begin work:
                print 'Builder is standing at (' + str(my_x) +', '+ str(my_y)+') ' \
                    'and is beginning work at (' + str(x) + ', ' + str(y) +').'


                # Using a switch statement here because eventually there will be other states like
                # 'building' or 'installing' something, etc
                for case in switch(mymap[x][y].designation_type):
                    if case('clearing'): 
                        mymap[x][y].blocked = False
                        mymap[x][y].block_sight = False
                        mymap[x][y].fore = color_ground
                        mymap[x][y].back = color_ground
                        mymap[x][y].char = GRAVEL

                        # Then reset the tile:
                        mymap[x][y].designated = False
                        mymap[x][y].designation_type = None
                        mymap[x][y].designation_char = None
                        mymap[x][y].being_worked_on = False

                        #gamemap_instance.initialize_fov()
                        print 'Finished work, resetting work_target to None, None.'
                        self.work_target = (None, None)
                        self.is_pathmap_created = False
                        break

                    if case(): break # default
        else:
            self.pick_spot_to_work(gamemap_instance)
            self.create_path(gamemap_instance)
Exemplo n.º 42
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)
Exemplo n.º 43
0
	def take_turn(self):
		self.get_target()
		
		# we have a target
		if self.target:
			# target is close enough to attack
			if self.owner.distance_to_actor(self.target) == 1:
				self.unset_temp_blocking()
				
				return self.owner.melee_attack(self.target)
			
			# too far to attack, so try to chase
			else:
				self.set_path()
		
		# if there is a path, try to walk along it
		if self.path:
			# the path is empty, remove the target
			if libtcod.path_is_empty(self.path):
				self.target = None
				self.target_x = None
				self.target_y = None
				self.path = None
				
				return False
			
			# try to walk the path
			else:
				x, y = libtcod.path_walk(self.path, False)
				if x is None:
					self.path = None
					
					return False
				
				actor = self.owner.map.actor_at(x, y)
				feature = self.owner.map.feature_at(x, y)
				
				# there is an actor in the way
				if actor:
					self.path = None
					
					self.set_temp_blocking(actor)
					
					return False
				
				# there is a closed door in the way, open it
				elif self.owner.opens_doors and feature.is_door and feature.open == False:
					self.path = None
					self.unset_temp_blocking()
					
					return feature.interact(self.owner)
				
				# otherwise, the space is free; move to that space
				else:
					self.owner.move_to(x, y)
					self.unset_temp_blocking()
					
					return True
		
		# no path, so just do nothing
		else:
			for actor in self.temporary_blocking:
				if actor.faction == 'neutral' and self.owner.distance_to_actor(actor) == 1:
					self.owner.melee_attack(actor)
			
			self.unset_temp_blocking()
			return True
Exemplo n.º 44
0
def play_game():
    global key, mouse, autopilot_on

    mouse = libtcod.Mouse()
    key = libtcod.Key()
    autopilot_on = False

    tutorial = True

    while not libtcod.console_is_window_closed():
        if game_state == GAME_STATE_VICTORY or game_state == GAME_STATE_PLAYER_DEAD:
            break

        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)
        libtcod.console_set_default_foreground(0, libtcod.white)

        renderer.render_all(player=player, objects=objects, game_map=game_map, con=con, panel=panel,
                            projectiles=projectiles, game_msgs=game_msgs, dungeon_level=dungeon_level, mouse=mouse,
                            non_interactive_objects=non_interactive_objects)

        libtcod.console_flush()

        renderer.clear_objects(con, objects)
        renderer.clear_objects(con, projectiles)

        if tutorial:
            msgbox("Welcome to the game!\n\n"
                   "You're tasked with a very important mission! The most talented diplomat the Earthlings have is "
                   "travelling to Epsilon Gruis I, where he'll attend peace talks with The Safe Ones and possibly gain "
                   "their support! Obviously this cannot happen, so you must ASSASSINATE THE DIPLOMAT!\n\n"
                   "To reach the diplomat, you must navigate through nine sectors (all crawling with hostiles by the "
                   "way) by using the naturally occurring JUMP POINTS. Our spies have provided INTEL pickups on the way"
                   " that will give you the disposition of the enemy forces in the next sector. If you don't pick up "
                   "the INTEL you'll be flying blind and probably die!\n\n"
                   "Your ship is equipped with a 3-tile cutting laser. End your turn within a distance of 3 to an enemy"
                   " to attack. It's pretty powerful against small ships, but be wary of extended engagements.\n\n"
                   "Good luck captain!\n\n"
                   "CONTROLS:\n"
                   "KEYPAD: Movement\n"
                   "a: autopilot to zone\n"
                   "g: pick up an item in your tile\n"
                   "i: view inventory and use items\n"
                   "d: drop items\n"
                   "r: view sector reports (DO THIS)\n"
                   "<: jump to the next sector (must be on the jump point)\n"
                   "ESC: quit to menu",
                   70)
            tutorial = False

        # TODO: Kind of messy way of structuring this!
        time = time_to_next_event(objects, projectiles)
        for obj in objects:
            if obj.fighter and (obj.ai or obj == player):
                obj.fighter.pass_time(time)
        for projectile in projectiles:
            projectile.fighter.pass_time(time)

        # Take turn if not autopiloting
        if player.fighter.time_until_turn == 0 and not autopilot_on:
            check_level_up()
            player_action = handle_keys()
            if player_action == 'exit':
                break
            elif player_action != GAME_STATE_DIDNT_TAKE_TURN:
                player.fighter.end_turn()
        # Autopilot
        elif player.fighter.time_until_turn == 0:
            # Check if there are nearby enemies
            nearest = closest_monster(TORCH_RADIUS)
            if key.vk != libtcod.KEY_NONE:
                autopilot_on = False
                message('Disengaging autopilot on pilot input!')
            if nearest:
                autopilot_on = False
                message('Enemy ships nearby! Autopilot disengaging!')
            elif libtcod.path_is_empty(autopilot_path):
                autopilot_on = False
                message('You have reached your destination! Autopilot disengaging!')
            else:
                (x, y) = libtcod.path_walk(autopilot_path, False)
                player.move_towards(x, y, game_map, objects)
                player.fighter.end_turn()
        else:
            player_action = None

        if game_state == GAME_STATE_PLAYING and player_action != GAME_STATE_DIDNT_TAKE_TURN:
            for o in objects:
                if o.fighter and o.fighter.time_until_turn == 0 and o.ai:
                    o.ai.take_turn()
                    o.fighter.end_turn()
            for projectile in projectiles:
                if projectile.fighter.time_until_turn == 0:
                    projectile.ai.take_turn()
                    projectile.fighter.end_turn()
Exemplo n.º 45
0
    def make_map(self, max_rooms, room_min_size, room_max_size, map_width,
                 map_height, player, entities, tile_data):
        rooms = []
        num_rooms = 0

        center_of_last_room_x = None
        center_of_last_room_y = None

        for r in range(max_rooms):
            w = randint(room_min_size, room_max_size)
            h = randint(room_min_size, room_max_size)

            x = randint(0, map_width - w - 1)
            y = randint(0, map_height - h - 1)

            if randint(0, 1):  #Make either a rectangular or circular room
                new_room = Room(x, y, w, h)
            else:
                new_room = Room.make_circle_room(x, y, min(w, h))

            for other_room in rooms:
                if new_room.intersect(other_room):
                    break
            else:
                self.place_room(new_room, tile_data)
                (new_x, new_y) = new_room.center()

                center_of_last_room_x = new_x
                center_of_last_room_y = new_y

                if num_rooms == 0:
                    player.x = new_x
                    player.y = new_y
                else:
                    (prev_x, prev_y) = rooms[num_rooms - 1].center()
                    if randint(0, 1) == 1:
                        self.create_h_tunnel(prev_x, new_x, prev_y)
                        self.create_v_tunnel(prev_y, new_y, new_x)
                    else:
                        self.create_v_tunnel(prev_y, new_y, prev_x)
                        self.create_h_tunnel(prev_x, new_x, new_y)

                self.place_entities(new_room, entities)

                rooms.append(new_room)
                num_rooms += 1
        stairs_component = Stairs(self.floor + 1)
        down_stairs = Entity(center_of_last_room_x,
                             center_of_last_room_y,
                             '>',
                             lc.white,
                             'Stairs',
                             render_order=RenderOrder.STAIRS,
                             stairs=stairs_component)
        entities.append(down_stairs)

        #Check to make sure a path exists from the player to the down stairs
        fov_map = lc.map_new(self.width, self.height)
        for y in range(0, self.height):
            for x in range(0, self.width):
                lc.map_set_properties(fov_map, x, y, True,
                                      not self.tiles[x][y].blocked)
        lc.map_compute_fov(fov_map, 0, 0, 100, True, 0)
        path = lc.path_new_using_map(fov_map, 1)
        lc.path_compute(path, player.x, player.y, down_stairs.x, down_stairs.y)

        if lc.path_is_empty(
                path):  #If no path exists, make a tunnel to the down stairs
            if randint(0, 1) == 1:
                self.create_h_tunnel(down_stairs.x, player.x, down_stairs.y)
                self.create_v_tunnel(down_stairs.y, player.y, player.x)
            else:
                self.create_v_tunnel(down_stairs.y, player.y, down_stairs.x)
                self.create_h_tunnel(down_stairs.x, player.x, player.y)
Exemplo n.º 46
0
def generate_river():
    river_start_x = 0
    river_start_y = 0
    river_end_x = MAP_WIDTH - 1
    river_end_y = MAP_HEIGHT - 1

    river_noise = [[0 for y in range(MAP_WIDTH)] for x in range(MAP_HEIGHT)]

    for i in range(MAP_HEIGHT):
        river_noise[i] = map(lambda a: (2+a)**4, noise_map[i])  # scaled up

    def river_cost(xFrom, yFrom, xTo, yTo, river_noise):
        return river_noise[yTo][xTo]

    path = libtcod.path_new_using_function(MAP_WIDTH, MAP_HEIGHT,
                                           river_cost, river_noise)
    # wish I could just use
    # (lambda xFrom, yFrom, xTo, yTo, river_noise: river_noise[xTo][yTo])
    libtcod.path_compute(path, river_start_x, river_start_y,
                         river_end_x, river_end_y)

    while not libtcod.path_is_empty(path):
        x, y = libtcod.path_walk(path, True)
        g.level_map[y][x] = Tile(tile_types.SHALLOW_WATER)
        # make a wider river by making all the neighbors water

        # we need to initialize these separately, but I don't know why
        x_in_min = False
        x_in_max = False
        y_in_min = False
        y_in_max = False

        if x-1 >= 0:          x_in_min = True
        if x+1 <  MAP_WIDTH:  x_in_max = True
        if y-1 >= 0:          y_in_min = True
        if y+1 <  MAP_HEIGHT: y_in_max = True
        # left
        if x_in_min:
            g.level_map[y][x-1] = Tile(tile_types.SHALLOW_WATER)
            # bottom left
            if y_in_min:
                g.level_map[y-1][x-1] = Tile(tile_types.SHALLOW_WATER)
            # top left
            if y_in_max:
                g.level_map[y+1][x-1] = Tile(tile_types.SHALLOW_WATER)
        # right
        if x_in_max:
            g.level_map[y][x+1] = Tile(tile_types.SHALLOW_WATER)
            # bottom right
            if y_in_min:
                g.level_map[y-1][x+1] = Tile(tile_types.SHALLOW_WATER)
            # top right
            if y_in_max:
                g.level_map[y+1][x+1] = Tile(tile_types.SHALLOW_WATER)
        # bottom
        if y_in_min:
            g.level_map[y-1][x] = Tile(tile_types.SHALLOW_WATER)
        # top
        if y_in_max:
            g.level_map[y+1][x] = Tile(tile_types.SHALLOW_WATER)

    # Iterate through all the tiles. Remove trees on shallow water tiles.
    for j in range(MAP_HEIGHT):
        for i in range(MAP_WIDTH):
            if g.level_map[j][i].type == tile_types.SHALLOW_WATER:
                for feature in g.terrain_features:
                    if feature.x == i and feature.y == j:
                        g.terrain_features.remove(feature)
Exemplo n.º 47
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()
Exemplo n.º 48
0
def playerInput():
	# Handles reacting to player input.
	
	global fovCompute, turns, actionMenu, gameState, widgets
	
	for widget in widgets:
		
		if widget.console != topGuiConsole:
		
			widget.checkSelected(mouse.cx, mouse.cy-topGuiHeight)
		
		else:
			
			widget.checkSelected(mouse.cx, mouse.cy)
		
	if mouse.lbutton_pressed:
		
		if actionMenu[0]:
			
			if mouse.cx > actionMenu[3] and mouse.cx < actionMenu[3]+actionWidth:
				
				if mouse.cy-topGuiHeight > actionMenu[4] and mouse.cy-topGuiHeight < actionMenu[4]+actionHeight:
				
					for widget in widgets:
						
						if widget.selected:
							
							if actionMenu[5] == "stairs":
								
								widget.action()

							else:
								
								widget.action(player, actionMenu[1], actionMenu[2])
							
							# Deletes all widgets created for action menu and resets action menu container.
							actionMenu = [False, 0, 0, 0, 0, ""]
							del widgets[2:6]
							return "ENDTURN"
			
		else:
		
			if libtcod.map_is_in_fov(fovMap, mouse.cx, mouse.cy-topGuiHeight) and gameState == "ACTIVE":
				
				if isWalkable(mouse.cx, mouse.cy-topGuiHeight):
					
					if player.distanceTo(mouse.cx, mouse.cy-topGuiHeight) >= 2:
						
						pathToCoords = libtcod.path_new_using_map(fovMap, 1)
						libtcod.path_compute(pathToCoords, player.x, player.y, mouse.cx, mouse.cy-topGuiHeight)
						
						while not libtcod.path_is_empty(pathToCoords):
						
							newX, newY = libtcod.path_walk(pathToCoords, True)
						
							if newX is not None:
					
								newX = newX - player.x
								newY = newY - player.y
							
							player.move(player.x+newX, player.y+newY)
							turns += 1
							
							if isNpcInFov():
								
								break
								
						libtcod.path_delete(pathToCoords)
						fovCompute = True
						return "ENDTURN"
						
					else:
						
						player.move(mouse.cx, mouse.cy-topGuiHeight)
						turns += 1
						fovCompute = True
						return "ENDTURN"
						
		if not actionMenu[0]:
			
			for widget in widgets:
				
				if widget.selected:
					
					widget.action()
				
	if mouse.rbutton_pressed:
	
		if actionMenu[0]:
		
			# Deletes all widgets created for action menu and resets action menu container.
			actionMenu = [False, 0, 0, 0, 0, ""]
			del widgets[2:6]

		elif gameState != "ACTIVE":
		
			gameState = "ACTIVE"
			widgets = widgets[0:2]
			
		else:
		
			if libtcod.map_is_in_fov(fovMap, mouse.cx, mouse.cy-topGuiHeight):
			
				getAction(mouse.cx, mouse.cy-topGuiHeight)
				fovCompute = True
	
	if key.pressed and key.vk == libtcod.KEY_SPACE:
		
		displayMsgHistory()
		
	if key.vk == libtcod.KEY_ESCAPE:	
		
		if actionMenu[0]:
			
			# Deletes all widgets created for action menu and resets action menu container.
			actionMenu = [False, 0, 0, 0, 0, ""]
			del widgets[2:6]
			
		if gameState != "ACTIVE":

			gameState = "ACTIVE"
			widgets = widgets[0:2]
		
	return False