def largeRatAi(obj, ratHoleX, ratHoleY): # Handles movement and combat abilities of the large rat. if libtcod.map_is_in_fov(fovMap, obj.x, obj.y): if obj.distanceTo(player.x, player.y) >= 2: pathToPlayer = libtcod.path_new_using_map(fovMap, 1) libtcod.path_compute(pathToPlayer, obj.x, obj.y, player.x, player.y) newX, newY = libtcod.path_walk(pathToPlayer, True) if newX is not None: newX = newX - obj.x newY = newY - obj.y else: newX, newY = 0 libtcod.path_delete(pathToPlayer) if isWalkable(obj.x+newX, obj.y+newY): obj.move(obj.x+newX, obj.y+newY) else: player.alive.takeDamage(obj.alive.damage) else: if obj.distanceTo(ratHoleX, ratHoleY) <= 5: num = random.randint(0, len(offsets)-1) newX = offsets[num][0] newY = offsets[num][1] else: pathToHole = libtcod.path_new_using_map(fovMap, 1) libtcod.path_compute(pathToHole, obj.x, obj.y, ratHoleX, ratHoleY) newX, newY = libtcod.path_walk(pathToHole, True) if newX is not None: newX = newX - obj.x newY = newY - obj.y else: newX, newY = 0 libtcod.path_delete(pathToHole) if isWalkable(obj.x+newX, obj.y+newY): obj.move(obj.x+newX, obj.y+newY)
def path_from_to(self, pos_origin, pos_destination): # For the moment, we do not handle Z movement x, y, z = pos_origin x2, y2, _ = pos_destination path = tcod.path_new_using_map(self.path_map[z]) tcod.path_compute(path, x, y, x2, y2) return path
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
def init_fov_and_pathfinding(self): print("initting fov and pathfinding") # init fov self.fov_map = tcod.map_new(self.width, self.height) self.update_fov_map() # init pathfinding self.path = tcod.path_new_using_map(self.fov_map, self.diagonal_cost)
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)
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)
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
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()
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
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)
def create_path(self, gamemap_instance): mymap = gamemap_instance.level #Create the path map self.path_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for x in range(1, MAP_WIDTH): for y in range(1, MAP_HEIGHT): libtcod.map_set_properties(self.path_map, x, y, not mymap[x][y].block_sight, not mymap[x][y].blocked) print 'Builder created self.path_map' self.is_pathmap_created = True # now use the path map to create the path from the explorer's current position to another spot: self.path = libtcod.path_new_using_map(self.path_map) destinationx, destinationy = self.pick_spot_to_work(gamemap_instance) if destinationx is not None: self.work_target = (destinationx, destinationy) print 'Builder chose a work target at ' + str(self.work_target[0]) +', ' + str(self.work_target[1]) + '.' libtcod.path_compute(self.path, self.owner.x, self.owner.y, destinationx, destinationy) #originx, originy = libtcod.path_get_origin(self.path) #destx, desty = libtcod.path_get_destination(self.path) elif destinationx is None: print 'destinationx is None.'
def move_towards(gamemap_instance, thisobject, target_x, target_y): """ Move towards a target_x, target_y coordinate. This method computes the A* path and uses move() to actually implement the movement. """ fov_map = gamemap_instance.fov_map path = libtcod.path_new_using_map(fov_map) libtcod.path_compute(path, thisobject.x, thisobject.y, target_x, target_y) pathx, pathy = libtcod.path_walk(path, True) # If the monster tries to move toward something, such as the player, which is standing # inside of a wall or other blocked spot, path_walk will return None but the dx and dy # calculations will crap out because you can't mix int and NoneType. if pathx is None or pathy is None: return dx = pathx - thisobject.x dy = pathy - thisobject.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, thisobject, dx, dy)
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)
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)
def gen_map(): global tile_map global explore_map global path_map global base_path gen_colors() tile_map = [[ wall_tile for y in range(MAP_HEIGHT) ] for x in range(MAP_WIDTH) ] explore_map = [[ False for y in range(MAP_HEIGHT) ] for x in range(MAP_WIDTH) ] rooms = [] num_rooms = 0 for r in range(dungeon_level+1): w = random.randint(ROOM_MIN_SIZE, ROOM_MAX_SIZE) h = random.randint(ROOM_MIN_SIZE, ROOM_MAX_SIZE) x = random.randint(1, MAP_WIDTH - w - 2) y = random.randint(1, MAP_HEIGHT - h - 2) new_room = Rect(x, y, w, h) failed = False for other_room in rooms: if new_room.intersect(other_room): failed = True break if not failed: carve_room(new_room) (new_x, new_y) = new_room.center() if num_rooms == 0: player.x = new_x player.y = new_y else: populate(new_room) (prev_x, prev_y) = rooms[num_rooms-1].center() if random.randint(0,1) == 1: carve_h_tunnel(prev_x, new_x, prev_y) carve_v_tunnel(prev_y, new_y, new_x) else: carve_h_tunnel(prev_x, new_x, new_y) carve_v_tunnel(prev_y, new_y, prev_x) rooms.append(new_room) num_rooms += 1 last_room = rooms[num_rooms-1] (stairs_x, stairs_y) = last_room.center() tile_map[stairs_x][stairs_y] = stair_tile path_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(path_map, x, y, not tile_map[x][y].blocks, not tile_map[x][y].blocks_sight) base_path = libtcod.path_new_using_map(path_map)
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
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)
def set_path(self): # there is no path, or the target has moved if self.path is None or (self.target_x, self.target_y) != libtcod.path_get_destination(self.path): self.path = libtcod.path_new_using_map(self.owner.map.libtcod_map, 1) # create the path; if failed, set path to None if not libtcod.path_compute(self.path, self.owner.x, self.owner.y, self.target_x, self.target_y): self.path = None
def __init__(self, x, y, u_class, name, speed, attack, armor, main_map, char): self.x = x self.y = y self.color = libtcod.red self.char = char self.u_class = u_class self.name = name self.speed = speed self.attack = attack self.armor = armor self.move_stat = 0 if u_class == 'infantry': self.path = libtcod.path_new_using_map(main_map.ground_map) if u_class == 'ship': self.path = libtcod.path_new_using_map(main_map.deepsea_map)
def find_path(source, target): fov_map = libtcod.map_new(Constants.MAP_WIDTH, Constants.MAP_HEIGHT) for y in range(Constants.MAP_HEIGHT): for x in range(Constants.MAP_WIDTH): libtcod.map_set_properties(fov_map, x, y, True, True) path = libtcod.path_new_using_map(fov_map, 1.5) libtcod.path_compute(path, source[0], source[1], target[0], target[1]) return path
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
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)
def create_path(self, coords, map): map_path = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(map_path, x, y, False, not map.cells[y][x].block_path) path = libtcod.path_new_using_map(map_path, 1.41) libtcod.path_compute(path, self.x, self.y, coords[0], coords[1]) return path
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
def set_full_explore_map(map, dijkstra=True): set_map = libtcod.map_new(map.map_width, map.map_height) for py in range(map.map_height): for px in range(map.map_width): libtcod.map_set_properties(set_map, px, py, not map.tile_is_sight_blocked(px, py), not map.tile_is_blocked(px, py)) if dijkstra: path = libtcod.dijkstra_new(set_map) else: path = libtcod.path_new_using_map(set_map) return path
def activate_autopilot(): options = map(lambda z: z.name, zones) index = menu('Autopilot to:\n', options, AUTOPILOT_WIDTH) if index is None: return None (x, y) = zones[index].center() path = libtcod.path_new_using_map(fov_map) libtcod.path_compute(path, player.x, player.y, x, y) return path
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
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]
def __init__(self, width, height): self.width = width self.height = height self.data = [[ Tile(False, False, chr(219), libtcod.light_blue, libtcod.black) for X in range(width) ] for Y in range(height)] self.pathdata = libtcod.map_new(width, height) #de-actived diagonal movement for pathfinding (7DRL) self.path = libtcod.path_new_using_map(self.pathdata, 0) self.focusTile = False
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
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)
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)
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)
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)
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)
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)
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)
def create_path(self, gamemap_instance): """Creates the initial path_map, and then on subsequent calls uses that path_map to play.""" mymap = gamemap_instance.level if not self.is_pathmap_created: #Create the path map self.path_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for x in range(1, MAP_WIDTH): for y in range(1, MAP_HEIGHT): libtcod.map_set_properties(self.path_map, x, y, not mymap[x][y].block_sight, not mymap[x][y].blocked) self.is_pathmap_created = True # now use the path map to create the path from the explorer's current position to another spot: self.path = libtcod.path_new_using_map(self.path_map) random_destination_x, random_destination_y = choose_random_unblocked_spot(mymap) libtcod.path_compute(self.path, self.owner.x, self.owner.y, random_destination_x, random_destination_y) originx, originy = libtcod.path_get_origin(self.path) destx, desty = libtcod.path_get_destination(self.path)
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)
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)
def move_towards(self, target_x, target_y): global fov_map path = libtcod.path_new_using_map(fov_map) libtcod.path_compute(path, self.x, self.y, target_x, target_y) x,y = libtcod.path_get(path, 0) if x is None: self.move(0, 0) else: dx = int(round(target_x - x)) dy = int(round(target_y - y)) if dx != 0: dx = dx/abs(dx) if dy != 0: dy = dy/abs(dy) self.move(dx, dy) libtcod.path_delete(path)
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)
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
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)
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
def handle_keys(game): libtcod.console_flush() event = libtcod.sys_check_for_event(1|4|8|16, key, mouse) mousestatus = libtcod.mouse_get_status() (a, b) = game.upper_left_of_map() (x, y) = (mousestatus.cx + a, mousestatus.cy + b) #If the player clicks an acceptable tile, build a path to that location and start pathing toward it. if mousestatus.lbutton_pressed and game.map[x][y].explored: game.state = 'pathing' fov_pathing_map = map.new_fov_pathing_map(game.map) game.player.mover.path = libtcod.path_new_using_map(fov_pathing_map, 1.41) libtcod.path_compute(game.player.mover.path, game.player.x, game.player.y, x, y) # Full screen / window switching if key.vk == libtcod.KEY_ENTER and (key.lalt | key.ralt): libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # This is a catch-all for situations where one needs to 'back out' of wherever one is. # An obvious one is to quit the game. if key.vk == libtcod.KEY_ESCAPE: return 'exit' # Movement keys - used if actually playing. if game.state == 'playing': dx=dy=0 key_char = chr(key.c) if key_char in ('q','w','e'): dy = -1 if key_char in ('q','a','z'): dx = -1 if key_char in ('z','x','c'): dy = 1 if key_char in ('c','d','e'): dx = 1 if key.vk == libtcod.KEY_UP: dy = -1 elif key.vk == libtcod.KEY_DOWN: dy = 1 elif key.vk == libtcod.KEY_LEFT: dx = -1 elif key.vk == libtcod.KEY_RIGHT: dx = 1 elif key_char in ('1'): game.debug_showexplored = not(game.debug_showexplored) elif key_char in ('2'): game.debug_troubletiles = not(game.debug_troubletiles) # Eventually, need keys for working with inventory and items. if (dx | dy): action = actors.player_move(game, dx, dy) if action is not 'blocked': game.map_movement = True return 'tookturn' elif game.state == 'in menu': pass else: return 'no action'
def direct_path(ox, oy, dx, dy, map): path = T.path_new_using_map(map) T.path_compute(path, ox, oy, dx, dy) (nx, ny) = T.path_walk(path, False) return (nx - ox, ny - oy)
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()
def __init__(self, creature, world): self.creature = creature self.world = world self.path = libtcod.path_new_using_map(self.world.map)
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
init = False hearts = 5 alive = True score = 0 if restart: restart = False punish = False speed = [1, 0] snake = [] snack = [] bait = [] grow = False growth = 0 grid = tcod.map_new(CW, CH) tcod.map_clear(grid, True, True) path = tcod.path_new_using_map(grid, 0) found = False for x in range(5): o = Obj(CW / 2 - x, CH / 2) snake.append(o) tcod.map_set_properties(grid, CW / 2 - x, CH / 2, False, False) if alive: # render snack tcod.console_set_default_foreground(CON, tcod.green) for s in snack: # collision if s.x == snake[0].x and s.y == snake[0].y: snack.remove(s) grow = True score += len(snake) #break
def update_pathfinding(self): tcod.path_delete(self.path) self.path = tcod.path_new_using_map(self.fov_map, self.diagonal_cost)
def create_path(self): self.path = libtcod.path_new_using_map(self.fov_map, dcost=0.0)
def move_towards(self, target_x, target_y): path = libtcod.path_new_using_map(fov_map) libtcod.path_compute(path, self.x, self.y, target_x, target_y) dx, dy = libtcod.path_get(path, 0) self.move_absolute(dx, dy) libtcod.path_delete(path)
def init_path(self): """ Initiates the path using the dungeon map, from the DungeonMask module. """ dungeon_map = self.parent.dungeon_mask.dungeon_map self._path = libtcod.path_new_using_map(dungeon_map, 1.0)