def move_astar(self, target, entities, game_map): #Create an FOV map with the dimensions of the map fov = tcod.map_new(game_map.width, game_map.height) #Scan the map each turn and set all the walls as unwalkable for y1 in range(game_map.height): for x1 in range(game_map.width): tcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked) #Scan all objects to see if there are objects that must be navigated around (generally enemies) #Checks if each object isn't self or target (so the start and end points are not marked as unwalkable) 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 the A* path #1.41 is the rough cost of diagonal movement (sqrt 2) my_path = tcod.path_new_using_map(fov, 1.41) # tcod.path_compute(my_path, self.x, self.y, target.x, target.y) if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25: x, y = tcod.path_walk(my_path, True) if x or y: self.x = x self.y = y else: self.move_towards(target.x, target.y, game_map, entities) tcod.path_delete(my_path)
def connect_rooms(cls, taken_spaces_map, exits): path_map = tcod.map_new(len(taken_spaces_map), len(taken_spaces_map[0])) for x in range(path_map.width): for y in range(path_map.height): if (x, y) not in exits: tcod.map_set_properties(path_map, x, y, False, taken_spaces_map[x][y] != 1) else: tcod.map_set_properties(path_map, x, y, False, True) connected_exits = list() for exit in exits: if exit not in connected_exits: path = tcod.dijkstra_new(path_map, 0) destination = None tries = 5 while destination in [exit, None ] + connected_exits and tries > 0: destination = random.choice(exits) tries -= 1 tcod.dijkstra_compute(path, exit[0], exit[1]) if tcod.dijkstra_path_set(path, destination[0], destination[1]): keep_destination = False for index in range(tcod.dijkstra_size(path)): point = tcod.dijkstra_get(path, index) if taken_spaces_map[point[0]][point[1]] == 3: keep_destination = True break taken_spaces_map[point[0]][point[1]] = 3 connected_exits.append(exit) if not keep_destination: connected_exits.append(destination) for exit in set(exits) - set(connected_exits): taken_spaces_map[exit[0]][exit[1]] = 4
def move_astar(self, target, entities, game_map): fov = tcod.map_new(game_map.width, game_map.height) # Walls are impassable of course for y1 in range(game_map.height): for x1 in range(game_map.width): tcod.map_set_properties( fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].block_movement) for entity in entities: if entity.block_movement and entity != self and entity != target: # Treat allies as transparent but impassable tcod.map_set_properties(fov, entity.x, entity.y, True, False) # The 1 is diagonal cost, normally would be 1.41, but my_path = tcod.path_new_using_map(fov, 1) tcod.path_compute(my_path, self.x, self.y, target.x, target.y) # Low path size so that monsters won't run off in some random lil corridor if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 20: x, y = tcod.path_walk(my_path, True) # True means to recompute path if x or y: # wtf self.x = x self.y = y else: # Backup option if not movable (corridor stuck) self.move_towards(target.x, target.y, game_map, entities) # Freeing some ram tcod.path_delete(my_path)
def move_astar(self, target, game_map, mobs): if not self.stats or time.time( ) - self.stats.mv_time < self.stats.mv_wait: return self.stats.mv_time = time.time() fov = tc.map_new(game_map.wd, game_map.ht) for x in range(0, game_map.wd): for y in range(0, game_map.ht): tc.map_set_properties(fov, x, y, not game_map.cells[x][y].is_discovered, not game_map.cells[x][y].is_blocked) for mob in mobs: if mob != self and mob != target: tc.map_set_properties(fov, mob.x, mob.y, True, False) path = tc.path_new_using_map(fov, 0) tc.path_compute(path, self.x, self.y, target.x, target.y) if not tc.path_is_empty(path) and tc.path_size(path) < 30: x, y = tc.path_walk(path, True) if x or y: self.x = x self.y = y else: self.move_to_target(target.x, target.y, game_map, mobs) tc.path_delete(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) if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25: x, y = libtcod.path_walk(my_path, True) if x or y: self.x = x self.y = y else: self.move_towards(target.x, target.y, game_map, entities) libtcod.path_delete(my_path)
def map_(): map_ = libtcodpy.map_new(MAP_WIDTH, MAP_HEIGHT) for y, line in enumerate(MAP): for x, ch in enumerate(line): libtcodpy.map_set_properties(map_, x, y, ch == ' ', ch == ' ') yield map_ libtcodpy.map_delete(map_)
def move_astar(self, target, game_map): """ """ logger.debug(f"{self.name} A* Observe") fov = tcod.map_new(game_map.w, game_map.h) for tile in game_map: tcod.map_set_properties(fov, tile.x, tile.y, not tile.opaque, not tile.blocked) for entity in game_map.entities: if entity == self: continue if entity.kind != Entities.ITEM: tcod.map_set_properties(fov, entity.x, entity.y, True, False) my_path = tcod.path_new_using_map(fov, 1.41) logger.debug(f"{self.name} A* Orient") tcod.path_compute(my_path, self.x, self.y, target.x, target.y) logger.debug(f"{self.name} A* Decide") if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25: logger.debug("{self.name} A* Act 0") self.position = tcod.path_walk(my_path, True) else: logger.debug(f"{self.name} A* Act 1") self.move_towards(target.x, target.y, game_map) tcod.path_delete(my_path)
def move_astar(self, alvo, entidades, mapa): fov = libtcod.map_new(mapa.largura, mapa.altura) for y1 in range(mapa.altura): for x1 in range(mapa.largura): libtcod.map_set_properties(fov, x1, y1, not mapa.tiles[x1][y1].bloqueio_visao, not mapa.tiles[x1][y1].bloqueado) for entidade in entidades: if entidade.bloqueia and entidade != self and entidade != alvo: libtcod.map_set_properties(fov, entidade.x, entidade.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, alvo.x, alvo.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: self.mover_para(alvo.x, alvo.y, mapa, entidades) # Delete libtcod.path_delete(my_path)
def move_astar(self, target, entities, game_map): # mapの寸法を持つfovマップを作製する fov = libtcod.map_new(game_map.width, game_map.height) # 現在の地図を毎回スキャンし、全ての壁を歩けないように設定する for y1, x1 in itertools.product(range(game_map.height), range(game_map.width)): libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked) # 全てのオブジェクトをスキャンして移動させるオブジェクトを確認する for entity in entities: if entity.blocks and entity != self and entity != target: libtcod.map_set_properties(fov, entity.x, entity.y, True, False) my_path = libtcod.path_new_using_map(fov, 1.41) libtcod.path_compute(my_path, self.x, self.y, target.x, target.y) if not libtcod.path_is_empty( my_path) and libtcod.path_size(my_path) < 25: x, y = libtcod.path_walk(my_path, True) if x or y: self.x = x self.y = y else: self.move_towards(target.x, target.y, game_map, entities) libtcod.path_delete(my_path)
def move_astar(self, target): fov = tcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y1 in range(MAP_HEIGHT): for x1 in range(MAP_WIDTH): tcod.map_set_properties(fov, x1, y1, not map[x1][y1].block_sight, not map[x1][y1].blocked) for obj in objects: if obj.blocks and obj != self and obj != target: tcod.map_set_properties(fov, obj.x, obj.y, True, False) path = tcod.path_new_using_map(fov, 0) # 0: 대각선 금지, 1.41: 대각선 코스트(루트 2) tcod.path_compute(path, self.x, self.y, target.x, target.y) if not tcod.path_is_empty(path) and tcod.path_size(path) < 25: x, y = tcod.path_walk(path, True) if x or y: self.x = x self.y = y self.wait = self.speed else: self.move_towards(target.x, target.y) tcod.path_delete(path)
def move_astar(self, target, entities, game_map): # Create FOV map with dimensions of game map fov = libtcod.map_new(game_map.width, game_map.height) # Set walls as blocked for y1 in range(game_map.height): for x1 in range(game_map.width): libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked) # Check for entities that are blocked and need to be navigated around for entity in entities: if entity.blocks and entity != self and entity != target: libtcod.map_set_properties(fov, entity.x, entity.y, True, False) # Allocate an A* path my_path = libtcod.path_new_using_map(fov, 1.41) libtcod.path_compute(my_path, self.x, self.y, target.x, target.y) if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25: x, y = libtcod.path_walk(my_path, True) if x or y: self.x = x self.y = y else: self.move_towards(target.x, target.y, game_map, entities) libtcod.path_delete(my_path)
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): fov.transparent[y1][ x1] = not game_map.tiles[x1][y1].block_sight fov.walkable[y1][x1] = not game_map.tiles[x1][y1].blocked for entity in entities: if entity.blocks and entity != self and entity != target: fov.transparent[entity.y][entity.x] = True fov.walkable[entity.y][entity.x] = False my_path = libtcod.path_new_using_map(fov, 1.41) libtcod.path_compute(my_path, self.x, self.y, target.x, target.y) if not libtcod.path_is_empty( my_path) and libtcod.path_size(my_path) < 25: x, y = libtcod.path_walk(my_path, True) if x or y: self.x = x self.y = y else: self.move_towards(target.x, target.y, game_map, entities) libtcod.path_delete(my_path)
def initialize_fov(game_map): fov_map = libtcod.map_new(game_map.width, game_map.height) for y in range(game_map.height): for x in range(game_map.width): libtcod.map_set_properties(fov_map, x, y, not game_map.tiles[x][y].block_sight, not game_map.tiles[x][y].blocked) return fov_map
def updateFOVmap(self): self.fov_map = libtcod.map_new(self.worldMap.MAP_WIDTH, self.worldMap.MAP_HEIGHT) for y in range(self.worldMap.MAP_HEIGHT): for x in range(self.worldMap.MAP_WIDTH): libtcod.map_set_properties(self.fov_map, x, y, not self.mapArray[x][y].block_sight, not self.mapArray[x][y].blocked)
def initialize_fov(self): self.log.debug("Initializing FOV map...") fov_map = libtcod.map_new(self.config.map.width, self.config.map.height) for entity, (position, optics) in self.world.get_components(Position, Optics): fov_map.transparent[position.y][position.x] = optics.transparent return fov_map
def create_fov_map(self): fov_map = tcod.map_new(self.width, self.height) for y in range(self.height): for x in range(self.width): tcod.map_set_properties(fov_map, x, y, not self.tile_map[x][y].block_sight, not self.tile_map[x][y].block) return fov_map
def new_fov_map(self): fov = libtcod.map_new(self.width, self.height) for y1 in range(self.height): for x1 in range(self.width): libtcod.map_set_properties(fov, x1, y1, not self.tiles[x1][y1].block_sight, not self.tiles[x1][y1].blocked) return fov
def initializeFOV(map): fovMap = tcod.map_new(map.width, map.height) for y in range(map.height): for x in range(map.width): tcod.map_set_properties(fovMap, x, y, not map.tiles[x][y].blockSight, not map.tiles[x][y].blocked) return fovMap
def init_fov(stage: Stage) -> tcod.map.Map: fov_map = tcod.map_new(stage.size.w, stage.size.h) for (x, y) in stage.size.each(): tcod.map_set_properties(fov_map, x, y, not stage.tile_at(x, y).is_blocked_sight, not stage.tile_at(x, y).is_blocked) return fov_map
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 # # THIS IS THE PROBLEM! We're not passing entities for movement, we're using Coords so the player blocks the target for entity in entities: if entity.blocks and entity != self and not (entity.x == target.x and entity.y == target.y): # 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 if constants['AI_allow_diagonal']: diagonal_cost=1.41 else: diagonal_cost=0.0 my_path = libtcod.path_new_using_map(fov, diagonal_cost) # 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 #Print path debugging info #print("Pathing from [" + str(self.x) + ", "+ str(self.y) + "] to ["+ str(target.x) +", "+ str(target.y) +"]") #print (my_path) #for i in range(0, libtcod.path_size(my_path)): # print (libtcod.path_get(my_path, i)) if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 200: # Find the next coordinates in the computed full path x, y = libtcod.path_walk(my_path, True) #print ("moving to [" +str(x)+ "," +str(y)+ "]") #DEBUG if x or y: # Set self's coordinates to the next path tile self.x = x self.y = y else: #print("using fallback pathing method") #DEBUG # 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 initialize(game_map): fov_map = tcod.map_new(game_map.height, game_map.width) for y in range(game_map.height): for x in range(game_map.width): tcod.map_set_properties(fov_map, y, x, not game_map.tiles[y][x].block_sight, not game_map.tiles[y][x].blocker) return fov_map
def initialize_fov(game_map): fov_map = tcod.map_new(game_map.width, game_map.height) for y in range(game_map.height): for x in range(game_map.width): #If it's not blocked or block_sight add it to the fov map tcod.map_set_properties(fov_map, x, y, not game_map.tiles[x][y].block_sight, not game_map.tiles[x][y].blocked) return fov_map
def inicializa_visao(mapa): visao = libtcod.map_new(mapa.largura, mapa.altura) for y in range(mapa.altura): for x in range(mapa.largura): libtcod.map_set_properties(visao, x, y, not mapa.tiles[x][y].bloqueio_visao, not mapa.tiles[x][y].bloqueado) return visao
def _make_fow_map(self): #create the FOV map, according to the generated map self._fov_map = libtcodpy.map_new(settings.MAP_WIDTH, settings.MAP_HEIGHT) for y in range(settings.MAP_HEIGHT): for x in range(settings.MAP_WIDTH): libtcodpy.map_set_properties( self._fov_map, x, y, not self._game_map[x][y].block_sight, not self._game_map[x][y].blocked)
def move_astar(self, target, entities, game_map): """Moves towards a target using the A* algorithm. TODO: Refactor this method to use new TCOD functions. TODO: Rewrite docstring to better document A* algorithm. TODO: Study and pick apart A* to understand how it works. Args: target(Entity): The Entity object to plot a path to. entities(list): A list of Entities. game_map(Map): The Map object used for displaying the game. """ # 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) fov.transparent[y1, x1] = not game_map.tiles[x1][y1].block_sight fov.walkable[y1, x1] = 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) fov.transparent[entity.y, entity.x] = True fov.walkable[entity.y, entity.x] = 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 map_make_fov(incoming_map): global FOV_MAP FOV_MAP = tcod.map_new(con.MAP_WIDTH, con.MAP_HEIGHT) for y in range(con.MAP_HEIGHT): for x in range(con.MAP_WIDTH): tcod.map_set_properties(FOV_MAP, x, y, not incoming_map[x][y].block_path, not incoming_map[x][y].block_path)
def intialize_fov(game_map): fov_map = libtcod.map_new(game_map.map_width, game_map.map_height) for y in range(game_map.map_height): for x in range(game_map.map_width): fov_map.transparent[y][x] = not game_map.tiles[x][y].block_sight fov_map.walkable[y][x] = not game_map.tiles[x][y].blocked return fov_map
def initialize_fov(): global fov_recompute, fov_map libtcod.console_clear(con) fov_recompute = True fov_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].blocked)
def initialize_fov(game_map): fov_map = tcod.map_new(game_map.width, game_map.height) for y in range(game_map.height): for x in range(game_map.width): tcod.map_set_properties(fov_map, x, y, game_map.field[x][y].transparent, not game_map.field[x][y].walkable) return fov_map
def initialize_fov(): libtcod.console_clear(con) global fov_recompute, fov_map fov_recompute = True #create the FOV map, according to the generated map fov_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].blocked)
def test_map(): map = libtcodpy.map_new(16, 16) assert libtcodpy.map_get_width(map) == 16 assert libtcodpy.map_get_height(map) == 16 libtcodpy.map_copy(map, map) libtcodpy.map_clear(map) libtcodpy.map_set_properties(map, 0, 0, True, True) assert libtcodpy.map_is_transparent(map, 0, 0) assert libtcodpy.map_is_walkable(map, 0, 0) libtcodpy.map_is_in_fov(map, 0, 0) libtcodpy.map_delete(map)
def initialize_fov(): global fov_recompute, fov_map fov_recompute = True #create the FOV map, according to the generated map fov_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].blocked) libtcod.console_clear(con) #unexplored areas start black (which is the default background color)
def __init__(self, level): self.tiles = generate_map(level) self.level = level self.player = None self.mobs = [] self.fov_map = T.map_new(MAP_W, MAP_H) for x in range(MAP_W): for y in range(MAP_H): tile = self.tiles[x][y] T.map_set_properties(self.fov_map, x, y, tile.transparent, tile.walkable) self.populate() if self.level == MAX_DLEVEL: self.place_monsters(Boss)
self.astar = tcod.path_new_using_map(maps[i]) def run(self): while 1: job, obj = jobs.get() if job == 'fov': tcod.map_compute_fov(obj, MAP_WIDTH // 2, MAP_HEIGHT // 2) elif job == 'astar': tcod.path_compute(self.astar, 0, 0, MAP_WIDTH - 1 , MAP_HEIGHT - 1) x, y = tcod.path_walk(self.astar, False) while x is not None: x, y = tcod.path_walk(self.astar, False) jobs.task_done() maps = [tcod.map_new(MAP_WIDTH, MAP_HEIGHT) for i in range(MAP_NUMBER)] jobs = queue.Queue() threads = [JobConsumer(i) for i in range(THREADS)] def test_fov_single(): for m in maps: tcod.map_compute_fov(m, MAP_WIDTH // 2, MAP_HEIGHT // 2) def test_fov_threads(): for m in maps: jobs.put(('fov', m)) jobs.join() def test_astar_single(): astar = tcod.path_new_using_map(maps[0]) for _ in range(PATH_NUMBER):
con = libtcod.console_new(SCREEN_WIDTH, SCREEN_HEIGHT) #create object representing the player player = Object(SCREEN_WIDTH//2, SCREEN_HEIGHT//2, '@', libtcod.white) #create an NPC npc = Object(SCREEN_WIDTH//2 - 5, SCREEN_HEIGHT//2, '@', libtcod.yellow) #the list of objects with those two objects = [npc, player] #generate map (at this point it's not drawn to the screen) make_map() #create the FOV map, according to the generated map fov_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): libtcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].blocked) fov_recompute = True while not libtcod.console_is_window_closed(): #render the screen render_all() libtcod.console_flush() #erase all objects at their old locations, before they move