Exemple #1
0
    def _ReadItemsAndLocationsRecursively(
            self, level_num: LevelNum, room_num: RoomNum,
            entrance_direction: Direction) -> None:
        print("Reading room %x" % room_num)
        if room_num not in Range.VALID_ROOM_NUMBERS:
            return  # No escaping back into the overworld! :)
        room = self.data_table.GetRoom(level_num, room_num)
        if room.IsMarkedAsVisited():
            return
        room.MarkAsVisited()

        item = room.GetItem()
        if item.IsMajorItem() or item == Item.TRIFORCE:
            self.item_shuffler.AddLocationAndItem(
                Location.LevelRoom(level_num, room_num), item)

        # Staircase cases (bad pun intended)
        if room.IsItemStaircase():
            return  # Dead end, no need to traverse further.
        if room.IsTransportStairway():
            for upstairs_room in [
                    room.GetStairwayRoomLeftExit(),
                    room.GetStairwayRoomRightExit()
            ]:
                self._ReadItemsAndLocationsRecursively(level_num,
                                                       upstairs_room,
                                                       Direction.STAIRCASE)
            return
        # Regular (non-staircase) room case.  Check all four cardinal directions, plus "down".
        for direction in (Direction.WEST, Direction.NORTH, Direction.EAST,
                          Direction.SOUTH):
            if direction == entrance_direction:
                continue
            if room.GetWallType(direction) != WallType.SOLID_WALL:
                self._ReadItemsAndLocationsRecursively(
                    level_num, RoomNum(room_num + direction),
                    direction.Reverse())
        if room.HasStairs():
            self._ReadItemsAndLocationsRecursively(level_num,
                                                   room.GetStairsDestination(),
                                                   Direction.STAIRCASE)
Exemple #2
0
    def _RecursivelyTraverseLevel(self, level_num: LevelNum, room_num: RoomNum,
                                  entry_direction: Direction) -> None:
        log.debug("Visiting level %d room %x" % (level_num, room_num))
        if not room_num in Range.VALID_ROOM_NUMBERS:
            return
        room = self.data_table.GetRoom(level_num, room_num)
        if room.IsMarkedAsVisited():
            return
        room.MarkAsVisited()
        current_location = Location.LevelRoom(level_num, room_num)

        # An item staircase room is a dead-end, so no need to recurse after picking up the item.
        if room.IsItemStaircase():
            self.inventory.AddItem(room.GetItem(), current_location)
            return

        # For a transport staircase, we don't know whether we came in through the left or right.
        # So try to leave both ways; the one that we came from will have already been marked as
        # visited and just return.
        if room.IsTransportStaircase():
            for room_num_to_visit in [
                    room.GetStairwayRoomLeftExit(),
                    room.GetStairwayRoomRightExit()
            ]:
                self._RecursivelyTraverseLevel(level_num, room_num_to_visit,
                                               Direction.STAIRCASE)
            return

        if self._CanGetRoomItem(entry_direction, room) and room.HasItem():
            self.inventory.AddItem(room.GetItem(), current_location)
        if room.GetEnemy() == Enemy.THE_BEAST:
            if self.inventory.HasBowSilverArrowsAndSword(
            ) and self.inventory.Has(Item.LADDER):
                # TODO: Doesn't address the case where ladder isn't obtained
                log.info("Got the triforce of power!")
                self.inventory.AddItem(Item.TRIFORCE_OF_POWER,
                                       current_location)
        if room.GetEnemy() == Enemy.THE_KIDNAPPED:
            log.info("Found the kidnapped")
            if self.inventory.Has(Item.TRIFORCE_OF_POWER):
                log.info("And rescued the kidnapped! :)")
                self.inventory.AddItem(Item.RESCUED_KIDNAPPED_VIRTUAL_ITEM,
                                       current_location)

        for direction in (Direction.WEST, Direction.NORTH, Direction.EAST,
                          Direction.SOUTH):
            if direction == entry_direction:
                continue
            if not self.inventory.HasReusableWeapon() and room.GetEnemy(
            ).HasHardCombatEnemies():
                continue
            if self._CanMove(entry_direction, direction, level_num, room_num,
                             room):
                self._RecursivelyTraverseLevel(level_num,
                                               RoomNum(room_num + direction),
                                               direction.Reverse())
        if room.GetRoomType().HasUnobstructedStairs() or (
                room.HasStairs() and self._CanDefeatEnemies(room)):
            if entry_direction != Direction.STAIRCASE:
                self._RecursivelyTraverseLevel(level_num,
                                               room.GetStairsDestination(),
                                               Direction.STAIRCASE)