Example #1
0
 def solve_trivia(self):
     """Solves trivia question."""
     question = self.emulator.get_screen_text(
         ui_element=ui.DAILY_TRIVIA_QUESTION)
     logger.debug(f"Found question: {question}")
     answers = [
         value for key, value in self.trivia.items()
         if is_strings_similar(question, key)
     ]
     if not answers:
         logger.error(f"Can find answer for question: {question}")
         return False
     logger.debug(f"Found answers: {answers}, selecting.")
     for answer in answers:
         for i in range(1, 5):
             available_answer_ui = ui.get_by_name(
                 f'DAILY_TRIVIA_ANSWER_{i}')
             available_answer = self.emulator.get_screen_text(
                 ui_element=available_answer_ui)
             logger.debug(f"Found available answer: {available_answer}.")
             if is_strings_similar(answer, available_answer):
                 logger.debug(
                     f"Found correct answer on UI element: {available_answer_ui}, clicking."
                 )
                 self.emulator.click_button(available_answer_ui)
                 return self.close_daily_trivia_answer_notification()
     else:
         logger.error("No available answers was found for trivia question.")
         random_answer_ui = ui.get_by_name(
             f'DAILY_TRIVIA_ANSWER_{randint(1, 4)}')
         logger.warning(f"Selecting random answer: {random_answer_ui}.")
         self.emulator.click_button(random_answer_ui)
         return self.close_daily_trivia_answer_notification()
Example #2
0
    def _buy_item_once(self, item):
        """Buys item from Alliance Store once.

        :param str item: name of the UI element of the item to buy.

        :return: was item bought or not.
        :rtype: bool
        """
        if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.get_by_name(item)):
            self.emulator.click_button(ui.get_by_name(item))
            if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_STORE_PURCHASE):
                logger.debug("Purchasing via Alliance Tokens.")
                self.emulator.click_button(ui.ALLIANCE_STORE_PURCHASE)
                if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_STORE_PURCHASE_CLOSE):
                    logger.info("Item was bought.")
                    self.emulator.click_button(ui.ALLIANCE_STORE_PURCHASE_CLOSE)
                    return True
                if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_STORE_PURCHASE_NO_TOKENS):
                    logger.info("Not enough Alliance Tokens for purchase.")
                    self.emulator.click_button(ui.ALLIANCE_STORE_PURCHASE_NO_TOKENS)
                    return False
                if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_STORE_PURCHASE_LIMIT):
                    logger.info("Reached daily limit for purchasing.")
                    self.emulator.click_button(ui.ALLIANCE_STORE_PURCHASE_LIMIT)
                    return False
        logger.warning(f"Item {item} was not found in the Alliance Store.")
        return False
Example #3
0
    def start_missions(self,
                       mode=MODE.ULTIMATE,
                       difficulty=0,
                       boss=BOSS.TODAYS_BOSS):
        """Starts World Boss battles.

        :param str mode: mode of battles to start (beginner or normal or ultimate).
        :param int difficulty: difficulty of Ultimate mode.
        :param str boss: boss to play.
        """
        logger.info(
            f"{self.stages} stages available, running {mode} mode with difficulty = {difficulty}."
        )
        if mode != self.MODE.BEGINNER and mode != self.MODE.NORMAL and mode != self.MODE.ULTIMATE:
            return logger.error(f"Got wrong mode for battles: {mode}.")
        if not self.open_world_boss():
            return logger.error("Can't get in battles lobby.")
        if boss != self.BOSS.TODAYS_BOSS and ui.get_by_name(boss):
            logger.debug(f"Selecting boss {boss}")
            self.emulator.click_button(ui.get_by_name(boss))
        self.emulator.click_button(ui.WB_MISSION_BUTTON)
        if not wait_until(self.emulator.is_ui_element_on_screen,
                          ui_element=ui.WB_READY_BUTTON):
            return logger.error(
                f"Can't find {ui.WB_READY_BUTTON} button after selecting the boss."
            )
        if mode == self.MODE.BEGINNER:
            logger.info("Starting BEGINNER battle.")
            self.emulator.click_button(ui.WB_BEGINNER_MODE)
        if mode == self.MODE.NORMAL:
            logger.info("Starting NORMAL battle.")
            self.emulator.click_button(ui.WB_NORMAL_MODE)
        if mode == self.MODE.ULTIMATE:
            logger.info("Starting ULTIMATE/LEGEND battle.")
            self.emulator.click_button(ui.WB_ULTIMATE_MODE)
            self._select_stage_level(level_num=difficulty)

        while self.stages > 0:
            if not self._start_world_boss_battle():
                logger.error("Failed to start battle. Returning to main menu.")
                return self.game.go_to_main_menu()
            if self.emulator.is_ui_element_on_screen(ui_element=ui.WB_RESPAWN):
                logger.info("Lost battle. Respawning.")
                self.emulator.click_button(ui.WB_RESPAWN)
                if not wait_until(self.emulator.is_ui_element_on_screen,
                                  timeout=10,
                                  ui_element=ui.WB_SCORE):
                    logger.error(
                        "Something went wrong while respawning after lost battle."
                    )
            else:
                self.stages -= 1
            logger.debug(f"{self.stages} stages left to complete.")
            if self.stages > 0:
                self.press_repeat_button(repeat_button_ui=ui.WB_REPEAT_BUTTON,
                                         start_button_ui=ui.WB_READY_BUTTON)
            else:
                self.press_home_button(home_button=ui.WB_HOME_BUTTON)
        logger.info("No more stages.")
Example #4
0
    def _acquire_chest(self, chest_index):
        """Acquires chest by chest index.

        :param int chest_index: chest index (from 1 to max chests + 1)

        :return: was chest acquired or not.
        :rtype: bool
        """
        logger.debug(f"Trying to acquire chest #{chest_index}")
        chest_ui = ui.get_by_name(f'INVASION_CHEST_AVAILABLE_{chest_index}')
        if wait_until(self.emulator.is_ui_element_on_screen,
                      timeout=1,
                      ui_element=chest_ui):
            logger.debug(f"Chest {chest_index} is available. Trying to open.")
            self.emulator.click_button(chest_ui)
            if wait_until(self.emulator.is_ui_element_on_screen,
                          ui_element=ui.INVASION_SKIP_CHEST):
                while self.emulator.is_ui_element_on_screen(
                        ui_element=ui.INVASION_SKIP_CHEST):
                    logger.debug("Skipping chests items.")
                    self.emulator.click_button(ui.INVASION_SKIP_CHEST,
                                               min_duration=0.5,
                                               max_duration=0.8)
                while not self.emulator.is_ui_element_on_screen(
                        ui_element=ui.INVASION_CHESTS_MENU_LABEL):
                    self.emulator.click_button(ui.INVASION_SKIP_CHEST,
                                               min_duration=0.5,
                                               max_duration=0.8)
                logger.debug("Chest acquired, going back to chest's menu.")
                return True
        logger.debug(f"Chest #{chest_index} isn't available.")
        return False
Example #5
0
 def _deploy_characters(self):
     """Deploys 3 characters to battle."""
     if self._sync_character_and_ally_teams:
         logger.debug(f"Selecting Character Team #{self.stages}")
         self.emulator.click_button(
             ui.get_by_name(f'WB_SELECT_CHARACTER_TEAM_{self.stages}'))
     no_main = self.emulator.is_image_on_screen(
         ui_element=ui.WB_NO_CHARACTER_MAIN)
     no_left = self.emulator.is_image_on_screen(
         ui_element=ui.WB_NO_CHARACTER_LEFT)
     no_right = self.emulator.is_image_on_screen(
         ui_element=ui.WB_NO_CHARACTER_RIGHT)
     if no_main or no_left or no_right:
         self.emulator.click_button(ui.WB_CHARACTER_FILTER,
                                    min_duration=1,
                                    max_duration=1)
         # selecting ALL filter for top characters
         self.emulator.click_button(ui.WB_CHARACTER_FILTER,
                                    min_duration=1,
                                    max_duration=1)
     if no_main:
         self.emulator.click_button(ui.WB_NON_FEATURED_CHARACTER_1)
     if no_left:
         self.emulator.click_button(ui.WB_NON_FEATURED_CHARACTER_2)
     if no_right:
         self.emulator.click_button(ui.WB_NON_FEATURED_CHARACTER_3)
Example #6
0
    def upgrade_iso8(self, times_for_each_upgrade=0, iso_to_upgrade=None, iso_to_use=None, stars_to_use=None):
        """Upgrades ISO-8 from Inventory.
        Starting from bottom right clicks on every ISO-8 and detects whether it's available for upgrade.
        Uses Quick Upgrade toggle.

        :param int times_for_each_upgrade: how many times upgrade each of ISO-9 type.
        :param str | list[str] iso_to_upgrade: list of ISO-8 types to upgrade. See `ISO8_TYPE` class.
        :param str | list[str] iso_to_use: list of ISO-8 types to use for upgrade. See `ISO8_TYPE_TO_USE` class.
        :param str | list[str] stars_to_use: list of ISO-8 ranks to use for upgrade. See `ISO8_STARS_TO_USE` class.
        :return:
        """
        if not times_for_each_upgrade or not iso_to_upgrade or not iso_to_use or not stars_to_use:
            logger.warning("Nothing to upgrade.")
            return self.game.go_to_main_menu()
        if isinstance(iso_to_upgrade, str):
            iso_to_upgrade = [iso_to_upgrade]

        logger.info(f"ISO-8: upgrading {times_for_each_upgrade} times each of given types: {iso_to_upgrade}.")
        if not self.open_iso8_tab():
            logger.error("Can't get to ISO-8 tab in the inventory.")
            return self.game.go_to_main_menu()

        for iso_type in iso_to_upgrade:
            logger.info(f"Starting to upgrade {iso_type} type.")
            self.emulator.click_button(ui.get_by_name(iso_type))
            self._select_and_upgrade_iso8(times=times_for_each_upgrade, iso_to_use=iso_to_use,
                                          stars_to_use=stars_to_use)
        self.game.go_to_main_menu()
Example #7
0
    def lock_iso8(self, iso_to_lock, options_to_lock):
        """Locks ISO-8 from Inventory.
        Starting from bottom right clicks on every ISO-8 and detects whether it's options is good for locking.

        :param str | list[str] iso_to_lock: list of ISO-8 types to upgrade. See `ISO8_TYPE` class.
        :param str | list[str] options_to_lock: list of options to look for locking. See `ISO8_LOCK` class.
        """
        if not iso_to_lock or not options_to_lock:
            logger.warning("Nothing to lock.")
            return self.game.go_to_main_menu()
        if isinstance(iso_to_lock, str):
            iso_to_lock = [iso_to_lock]
        if isinstance(options_to_lock, str):
            options_to_lock = [options_to_lock]

        logger.info(f"ISO-8: locking options {options_to_lock} for each of given types: {iso_to_lock}.")
        if not self.open_iso8_tab():
            logger.error("Can't get to ISO-8 tab in the inventory.")
            return self.game.go_to_main_menu()

        for iso_type in iso_to_lock:
            logger.info(f"Starting to looking at {iso_type} type.")
            self.emulator.click_button(ui.get_by_name(iso_type))
            self._select_and_lock_iso8(options_to_lock=options_to_lock)
        self.game.go_to_main_menu()
Example #8
0
 def upgrade_all_cards(self):
     """Upgrades all available Comic Cards."""
     self.game.go_to_comic_cards()
     logger.info("Comic Cards: upgrading all available cards.")
     if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.CARDS_UPGRADE_ALL):
         self.emulator.click_button(ui.CARDS_UPGRADE_ALL)
         for card_index in range(1, 6):
             card_select_ui = ui.get_by_name(f'CARDS_SELECT_GRADE_{card_index}')
             self.emulator.click_button(card_select_ui)
             logger.debug(f"Comic Cards: starting to upgrade UI Element {card_select_ui}")
             if not wait_until(self.emulator.is_image_on_screen, ui_element=card_select_ui):
                 logger.warning("Comic Cards: can't select card's grade.")
                 continue
             logger.debug(f"Comic Cards: successfully selected UI Element {card_select_ui}")
             self.emulator.click_button(ui.CARDS_SELECT_GRADE)
             if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.CARDS_UPGRADE_CONFIRM):
                 self.emulator.click_button(ui.CARDS_UPGRADE_CONFIRM)
                 if wait_until(self.emulator.is_ui_element_on_screen, timeout=10,
                               ui_element=ui.CARDS_UPGRADE_RESULTS_OK):
                     logger.debug(f"Comic Cards: successfully upgraded UI Element {card_select_ui}")
                     self.emulator.click_button(ui.CARDS_UPGRADE_RESULTS_OK)
                     wait_until(self.emulator.is_image_on_screen, ui_element=card_select_ui)
                     continue
     if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.CARDS_UPGRADE_ALL_CANCEL):
         self.emulator.click_button(ui.CARDS_UPGRADE_ALL_CANCEL)
         self.close_after_mission_notifications()
         self.game.go_to_main_menu()
Example #9
0
 def _select_character_for_normal_mode(self):
     """Selects best available character for NORMAL battle."""
     popular_character_indexes, characters_images = self._get_all_characters_info_for_normal_mode(
     )
     while not self.emulator.is_ui_element_on_screen(
             ui_element=ui.DANGER_ROOM_BATTLE_BEGINS_SOON_NORMAL):
         if self._check_game_canceled():
             return False
         best_character = None
         for character_index in popular_character_indexes:
             character_ui = ui.get_by_name(
                 f'DANGER_ROOM_CHARACTER_{character_index + 1}')
             if self._is_character_available(
                     character_ui=character_ui,
                     character_image=characters_images[character_index]):
                 best_character = character_ui
         if not best_character and not self.emulator.is_ui_element_on_screen(
                 ui_element=ui.DANGER_ROOM_BATTLE_BEGINS_SOON_NORMAL):
             logger.error("Can't find best character for NORMAL mode.")
             return False
         if best_character:
             logger.debug(f"Selecting character {best_character}")
             self.emulator.click_button(best_character)
             r_sleep(1)
     logger.debug("Battle is ready to begin.")
     return True
Example #10
0
    def buy_artifact_chest(self, chests_to_buy=None):
        """Buys artifact chest from the Store by it's UI element.

        :param str | list[str] chests_to_buy: UI elements of chest to buy.
        """
        if not self.open_artifact_store():
            return logger.error("Can't open Artifact Store.")
        self._drag_store_list_to_the_right()
        r_sleep(1)  # Wait for animations
        self._drag_store_list_to_the_right()
        for chest in chests_to_buy:
            chest_ui = ui.get_by_name(chest)
            if wait_until(self.emulator.is_ui_element_on_screen, ui_element=chest_ui):
                logger.debug(f"Buying Artifact Chest: {chest_ui.name}")
                self.emulator.click_button(chest_ui)
                if wait_until(self.emulator.is_ui_element_on_screen,
                              ui_element=ui.STORE_ARTIFACT_FREE_CHEST_PURCHASE):
                    self.emulator.click_button(ui.STORE_ARTIFACT_FREE_CHEST_PURCHASE)
                    if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.SKIP_CUTSCENE):
                        self.emulator.click_button(ui.SKIP_CUTSCENE)
                        if wait_until(self.emulator.is_ui_element_on_screen,
                                      ui_element=ui.STORE_ARTIFACT_FREE_CHEST_PURCHASE_CLOSE):
                            self.emulator.click_button(ui.STORE_ARTIFACT_FREE_CHEST_PURCHASE_CLOSE)
                            logger.info(f"Artifact Chest {chest_ui.name} acquired.")
                    if wait_until(self.emulator.is_ui_element_on_screen,
                                  ui_element=ui.STORE_RECHARGE_ENERGY_VIA_POINTS_LIMIT):
                        logger.info(f"Reached daily limit for {chest_ui.name}.")
                        self.emulator.click_button(ui.STORE_RECHARGE_ENERGY_VIA_POINTS_LIMIT)
        self.game.go_to_main_menu()
Example #11
0
    def _select_and_lock_iso8(self, options_to_lock):
        """Selects each ISO-8 from inventory's grid, checks it's options and then locks it
        if option meets requirements.

        :param str | list[str] options_to_lock: list of options to look for locking. See `ISO8_LOCK` class.
        """
        for row in range(self.INVENTORY_ROW, 0, -1):
            for col in range(self.INVENTORY_COL, 0, -1):
                iso8_ui = ui.get_by_name(f"ISO8_ITEM_{row}_{col}")
                if self.emulator.is_image_on_screen(iso8_ui):
                    continue
                self.emulator.click_button(iso8_ui)
                text = self.emulator.get_screen_text(ui.ISO8_OPTION_TEXT)
                for option in options_to_lock:
                    if option in self.ISO8_LOCK.multi_line():
                        matched = regex.match(option, text) is not None
                    else:
                        # `match is not None` is required because `any()` can't cast `match` to bool
                        matched = any([regex.match(option, line) is not None for line in text.split("\n")])
                    if not matched:
                        continue
                    logger.debug(f"Found ISO-8 at {(row, col)} that meets requirements.")
                    if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_LOCK):
                        self.emulator.click_button(ui.ISO8_LOCK)
                        if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_LOCK_CONFIRM):
                            logger.info(f"ISO-8 at {(row, col)} has locked.")
                            self.emulator.click_button(ui.ISO8_LOCK_CONFIRM)
Example #12
0
    def _get_all_characters_info_for_normal_mode(self):
        """Gets all characters and their popularity from selector.

        :return: sorted indexes of characters by popularity and character's images.
        :rtype: tuple[list[float], list[numpy.ndarray]]
        """
        characters_popularity, characters_images = [], []
        for character_index in range(1, 7):
            character_ui = ui.get_by_name(
                f'DANGER_ROOM_CHARACTER_{character_index}')
            character_image = self.emulator.get_screen_image(
                rect=character_ui.button_rect)
            characters_images.append(character_image)
            character_popularity_text = self.emulator.get_screen_text(
                ui_element=character_ui)
            full_match = character_popularity_regexp.fullmatch(
                character_popularity_text)
            if not full_match:
                logger.warning(
                    f"Can't read character #{character_index} popularity, assuming it's 0."
                )
                character_popularity = 0
            else:
                character_popularity = full_match.group(1)
            characters_popularity.append(float(character_popularity))
        sorted_char_index = sorted(range(len(characters_popularity)),
                                   key=lambda k: characters_popularity[k])
        return sorted_char_index, characters_images
Example #13
0
 def _select_stage(self, stage):
     """Selects stage of the battle."""
     stage_ui = ui.get_by_name(stage)
     if wait_until(self.emulator.is_ui_element_on_screen,
                   ui_element=stage_ui):
         self.emulator.click_button(stage_ui)
         return True
     return False
Example #14
0
    def _select_story_stage(self, story_stage):
        """Selects stage of Story mission.

        :param str story_stage: UI element that represent mission stage.
        """
        while not self.emulator.is_ui_element_on_screen(
                ui.get_by_name(story_stage)):
            # TODO: plus sign for next missions
            self.emulator.click_button(ui.STORY_STAGE_MINUS)
Example #15
0
    def _start_squad_battle(self, battle_name):
        """Starts selected squad battle.

        :param str battle_name: number of the battle.
        """
        battle_ui = ui.get_by_name(battle_name)
        if self._select_squad_battle(squad_battle_ui=battle_ui):
            if not self.press_start_button():
                return self.end_missions()
            AutoBattleBot(self.game, self.battle_over_conditions).fight()
            self.close_squad_battle_after_battle_notifications()
Example #16
0
    def _select_types_for_upgrade(self, iso_to_use, stars_to_use):
        """Deselects all previous selected types by clicking at 'Select All` toggle and
        then selects types and ranks of ISO-8 for upgrading in Upgrade Menu.

        :param str | list[str] iso_to_use: list of ISO-8 types to use for upgrade. See `ISO8_TYPE_TO_USE` class.
        :param str | list[str] stars_to_use: list of ISO-8 ranks to use for upgrade. See `ISO8_STARS_TO_USE` class.
        """
        if isinstance(iso_to_use, str):
            iso_to_use = [iso_to_use]
        if isinstance(stars_to_use, str):
            stars_to_use = [stars_to_use]
        if wait_until(self.emulator.is_image_on_screen, ui_element=ui.ISO8_QUICK_UPGRADE_SELECT_ALL):
            logger.debug("Clearing selecting types by deselecting them all.")
            self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_SELECT_ALL)
        else:
            logger.debug("Clearing selecting types by selecting and deselecting them all.")
            self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_SELECT_ALL)
            self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_SELECT_ALL)
        for iso_type in iso_to_use:
            self.emulator.click_button(ui.get_by_name(iso_type))
        for star_type in stars_to_use:
            self.emulator.click_button(ui.get_by_name(star_type))
Example #17
0
    def _deploy_characters(self, apply_character_filter=False):
        """Tries to deploy characters.
        If room was cleared in previous season then selects characters from top of the list.
        If room wasn't cleared in previous season then selectes characters from bottom of the list.
        Stops selecting characters when gets `NO EMPTY SLOTS` notification.

        :param bool apply_character_filter: should character filter be applied or not.

        :return: (True or False) full team was selected or not.
        :rtype: bool
        """
        if self._cleared_previously:
            char_num_gen = (char_num for char_num in range(1, 4)
                            )  # Only first 3 character from previous clear
        else:
            char_num_gen = (char_num for char_num in range(12, 0, -1)
                            )  # 12 characters from the bottom to top
        if apply_character_filter:
            self._select_character_filter_by_mission()
        while not self.emulator.is_ui_element_on_screen(
                ui.SL_SELECT_CHARACTERS_NO_EMPTY_SLOTS):
            char_num = next(char_num_gen, None)
            if not char_num:  # If no more characters is available to deploy
                if self._cleared_previously:  # Use default strategy with 12 characters
                    char_num_gen = (char_num for char_num in range(12, 0, -1))
                    self._cleared_previously = False
                    continue
                else:
                    return False
            # If `cleared` characters is no more then use default strategy with 12 characters
            if char_num and self._cleared_previously and not self.emulator.is_ui_element_on_screen(
                    ui.get_by_name(f"SL_CHARACTER_CLEARED_{char_num}")):
                char_num_gen = (char_num for char_num in range(12, 0, -1))
                self._cleared_previously = False
                continue
            self.emulator.click_button(
                ui.get_by_name(f"SL_CHARACTER_{char_num}"))
        self.emulator.click_button(ui.SL_SELECT_CHARACTERS_NO_EMPTY_SLOTS)
        return True
Example #18
0
    def buy_materials(self, materials_list):
        """Buy materials from Support Shop.

        :param str | list[str] materials_list: list of names of UI Element of materials to buy.
        """
        if isinstance(materials_list, str):
            materials_list = [materials_list]

        self.open_support_shop()
        self._open_material_tab()
        for material in materials_list:
            self._buy_material(material_ui=ui.get_by_name(material))
        self.game.go_to_main_menu()
Example #19
0
    def _get_all_characters_info_for_extreme_mode(self):
        """Gets all available characters and their popularity from selector.

        :return: sorted indexes of non participated characters by popularity.
        :rtype: list[float]
        """
        characters_popularity = []
        for character_index in range(1, 13):
            character_ui = ui.get_by_name(
                f'DANGER_ROOM_EXTREME_CHARACTER_{character_index}')
            used_character_ur = ui.get_by_name(
                f'DANGER_ROOM_EXTREME_CHARACTER_USED_{character_index}')
            character_participation = self.emulator.is_color_similar(
                color=used_character_ur.image_color,
                rects=[used_character_ur.image_rect])
            if not character_participation:
                logger.debug(
                    f"Character #{character_index} already participated, skipping."
                )
                characters_popularity.append(0)
                continue
            character_popularity_text = self.emulator.get_screen_text(
                ui_element=character_ui)
            full_match = character_popularity_regexp.fullmatch(
                character_popularity_text)
            if not full_match:
                logger.warning(
                    f"Can't read character #{character_index} popularity, assuming it's 0."
                )
                character_popularity = 0
            else:
                character_popularity = full_match.group(1)
            characters_popularity.append(float(character_popularity))
        sorted_char_index = sorted(range(len(characters_popularity)),
                                   key=lambda k: characters_popularity[k])
        return sorted_char_index
Example #20
0
    def find_event_ui_by_name(self, name, similar_to_full_line=True):
        """Finds UI element of Event by it's name.

        :param str name: name of event.
        :param bool similar_to_full_line: take name of event as full line of text or part of any line.

        :rtype ui.UIElement
        """
        self._drag_event_list_to_the_bottom()
        for ui_index in range(1, 5):
            event_ui = ui.get_by_name(f"EVENT_BUTTON_1_{ui_index}")
            if self._is_event_ui_has_same_name(
                    name=name,
                    event_ui=event_ui,
                    similar_to_full_line=similar_to_full_line):
                return event_ui
        self._drag_event_list_to_the_top()
        for ui_index in range(1, 5):
            event_ui = ui.get_by_name(f"EVENT_BUTTON_2_{ui_index}")
            if self._is_event_ui_has_same_name(
                    name=name,
                    event_ui=event_ui,
                    similar_to_full_line=similar_to_full_line):
                return event_ui
Example #21
0
    def _open_story_mission(self, story_mission):
        """Opens given Story mission from Story lobby.

        :param str story_mission: UI element that represent Story Mission.

        :rtype: bool
        """
        story_mission_ui = ui.get_by_name(story_mission)
        if wait_until(self.emulator.is_ui_element_on_screen,
                      ui_element=story_mission_ui):
            logger.debug(f"Opening Story mission {story_mission_ui}")
            self.emulator.click_button(story_mission_ui)
            # TODO: normal start button
            return wait_until(self.emulator.is_ui_element_on_screen,
                              ui_element=ui.STORY_ULTIMATE_START_BUTTON)
        logger.error(f"Can't open Store mission {story_mission_ui}")
Example #22
0
 def acquire_all_weekly_rewards(self):
     """Acquired all available weekly rewards from Daily Challenges."""
     self.game.go_to_challenges()
     if wait_until(self.emulator.is_ui_element_on_screen,
                   ui_element=ui.DAILY_REWARDS_TAB):
         self.emulator.click_button(ui.DAILY_REWARDS_TAB)
         for reward_num in range(1, 6):
             reward_ui = ui.get_by_name(
                 f"DAILY_REWARDS_ACQUIRE_WEEKLY_{reward_num}")
             self.emulator.click_button(reward_ui)
             if wait_until(
                     self.emulator.is_ui_element_on_screen,
                     ui_element=ui.DAILY_REWARDS_ACQUIRE_WEEKLY_CLOSE):
                 logger.info(f"Weekly reward #{reward_num} acquired.")
                 self.emulator.click_button(
                     ui.DAILY_REWARDS_ACQUIRE_WEEKLY_CLOSE)
     self.game.go_to_main_menu()
Example #23
0
 def _deploy_allies(self):
     """Deploys 4 characters as allies to battle."""
     if self._sync_character_and_ally_teams:
         logger.debug(f"Selecting Ally Team #{self.stages}")
         self.emulator.click_button(
             ui.get_by_name(f'WB_SELECT_ALLY_TEAM_{self.stages}'))
     if self.emulator.is_image_on_screen(
             ui_element=ui.WB_NO_CHARACTER_ALLY_1):
         self.emulator.click_button(ui.WB_ALLY_CHARACTER_1)
     if self.emulator.is_image_on_screen(
             ui_element=ui.WB_NO_CHARACTER_ALLY_2):
         self.emulator.click_button(ui.WB_ALLY_CHARACTER_2)
     if self.emulator.is_image_on_screen(
             ui_element=ui.WB_NO_CHARACTER_ALLY_3):
         self.emulator.click_button(ui.WB_ALLY_CHARACTER_3)
     if self.emulator.is_image_on_screen(
             ui_element=ui.WB_NO_CHARACTER_ALLY_4):
         self.emulator.click_button(ui.WB_ALLY_CHARACTER_4)
Example #24
0
 def _select_stage(self, difficulty=6):
     """Selects stage in missions in Epic Quest."""
     difficulty_ui = ui.get_by_name(self._get_difficulty_ui(difficulty))
     if wait_until(self.emulator.is_ui_element_on_screen,
                   ui_element=self.stage_selector_ui):
         self.emulator.click_button(self.stage_selector_ui)
         if "_2_" in difficulty_ui.name:  # TODO: that's not good at all
             logger.debug(
                 "Difficulty is referring from the bottom of list. Trying to scroll."
             )
             self.emulator.drag(ui.DIFFICULTY_DRAG_FROM,
                                ui.DIFFICULTY_DRAG_TO)
             r_sleep(1)
         if wait_until(self.emulator.is_ui_element_on_screen,
                       ui_element=difficulty_ui):
             self.emulator.click_button(difficulty_ui)
     return wait_until(self.emulator.is_ui_element_on_screen,
                       ui_element=ui.START_BUTTON)
Example #25
0
    def _try_to_select_iso8_for_upgrade(self) -> bool:
        """Trying to select available ISO-8 for upgrade.
        Starting from bottom right clicks on every ISO-8 and looks for 'QUICK UPGRADE` button.
        Position doesn't matter because that ISO-8 would be already selected and on focus.

        :return: was available ISO-8 for upgrade found or not.
        :rtype: bool
        """
        for row in range(self.INVENTORY_ROW, 0, -1):
            for col in range(self.INVENTORY_COL, 0, -1):
                iso8_ui = ui.get_by_name(f"ISO8_ITEM_{row}_{col}")
                if self.emulator.is_image_on_screen(iso8_ui):  # Empty slot
                    continue
                self.emulator.click_button(iso8_ui)
                if self.emulator.is_ui_element_on_screen(ui.ISO8_QUICK_UPGRADE) or \
                        self.emulator.is_ui_element_on_screen(ui.ISO8_UPGRADE):
                    logger.debug(f"Found ISO-8 available for upgrade in inventory grid at ({row}, {col})")
                    return True
        return False
Example #26
0
 def _select_character_for_extreme_mode(self):
     """Selects best available character for EXTREME battle."""
     popular_character_indexes = self._get_all_characters_info_for_extreme_mode(
     )
     while not self.emulator.is_ui_element_on_screen(
             ui_element=ui.DANGER_ROOM_BATTLE_BEGINS_SOON_EXTREME):
         if self._check_game_canceled():
             return False
         best_character = None
         for character_index in popular_character_indexes:
             best_character = ui.get_by_name(
                 f'DANGER_ROOM_EXTREME_CHARACTER_{character_index + 1}')
         if not best_character:
             logger.error("Can't find best character for mode.")
             return False
         logger.debug(f"Selecting character {best_character}")
         self.emulator.click_button(best_character)
         r_sleep(2)
     logger.debug("Battle is ready to begin.")
     return True
Example #27
0
    def _select_and_combine_iso8(self, times):
        """Selects available for combine ISO-8 from inventory's grid and then combines it.

        :param int times: how many times to select new ISO-8 for combining.
        """
        counter = 0
        unable_to_combine = []
        while counter < times:
            iso_position = self._try_to_select_iso8_for_combine(skip_positions=unable_to_combine)
            if not iso_position:
                logger.info("No more ISO-8 to combine.")
                return
            self.emulator.click_button(ui.ISO8_COMBINE)
            if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_COMBINE_LABEL):
                if not wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_COMBINE_MATERIAL_SELECT_1):
                    logger.info("No more materials to combine.")
                    self.emulator.click_button(ui.ISO8_COMBINE_LABEL)
                    unable_to_combine.append(iso_position)
                    continue
                for material_num in range(1, 6):
                    material_ui = ui.get_by_name(f"ISO8_COMBINE_MATERIAL_SELECT_{material_num}")
                    self.emulator.click_button(material_ui)
                    if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_COMBINE_LOCKED):
                        logger.info(f"Item #{material_num} is locked, cannot combine, trying next one.")
                        self.emulator.click_button(ui.ISO8_COMBINE_LOCKED)
                        continue
                    self.emulator.click_button(ui.ISO8_COMBINE_CONFIRM)
                    if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_COMBINE_CONFIRM_NOTICE):
                        logger.debug("Combining ISO-8.")
                        self.emulator.click_button(ui.ISO8_COMBINE_CONFIRM_NOTICE)
                        if wait_until(self.emulator.is_ui_element_on_screen,
                                      ui_element=ui.ISO8_COMBINE_CONFIRM_NOTICE_CLOSE):
                            self.emulator.click_button(ui.ISO8_COMBINE_CONFIRM_NOTICE_CLOSE)
                            self.close_after_mission_notifications()
                            break
                else:
                    logger.info("All items are locked, cannot combine.")
                    self.emulator.click_button(ui.ISO8_COMBINE_LABEL)
                    unable_to_combine.append(iso_position)
                    continue
            counter += 1
Example #28
0
    def _try_to_select_iso8_for_combine(self, skip_positions=None):
        """Trying to select available ISO-8 for combine.
        Starting from bottom right clicks on every ISO-8 and looks for 'COMBINE` button.
        Can skip positions because each rank of ISO-8 could be combined with only the same rank
        so other available ISO-8 with lower ranks can be found later in the grid.

        :param skip_positions: list of position (row, col) which would be skipped for checking.

        :return: False when no available ISO-8 was found or position (row, col) in inventory's grid of found ISO-8.
        :rtype: bool | tuple[int, int]
        """
        for row in range(self.INVENTORY_ROW, 0, -1):
            for col in range(self.INVENTORY_COL, 0, -1):
                iso8_ui = ui.get_by_name(f"ISO8_ITEM_{row}_{col}")
                if self.emulator.is_image_on_screen(iso8_ui) or (skip_positions and (row, col) in skip_positions):
                    continue
                self.emulator.click_button(iso8_ui)
                if self.emulator.is_ui_element_on_screen(ui.ISO8_COMBINE):
                    logger.debug(f"Found ISO-8 available for combine in inventory grid at ({row}, {col})")
                    return row, col
        return False
Example #29
0
    def _auto_select_for_dismantle(self, artifact_stars):
        """Selects artifacts for dismantling using Auto Select menu.

        :param str | list[str] artifact_stars: artifact's stars to dismantle. See `ARTIFACT_STARS` for reference.

        :rtype: bool
        """
        if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ARTIFACT_DISMANTLE_AUTO_SELECT):
            logger.debug("Opening Auto Select menu.")
            self.emulator.click_button(ui.ARTIFACT_DISMANTLE_AUTO_SELECT)
            if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ARTIFACT_DISMANTLE_AUTO_SELECT_LABEL):
                for artifact_star in artifact_stars:
                    artifact_star_ui = ui.get_by_name(artifact_star)
                    logger.debug(f"Selecting {artifact_star_ui}.")
                    self.emulator.click_button(artifact_star_ui)
                self.emulator.click_button(ui.ARTIFACT_DISMANTLE_AUTO_SELECT_CONFIRM)
                if wait_until(self.emulator.is_ui_element_on_screen,
                              ui_element=ui.ARTIFACT_DISMANTLE_AUTO_SELECT_CANCEL):
                    logger.info("No artifacts to dismantle.")
                    self.emulator.click_button(ui.ARTIFACT_DISMANTLE_AUTO_SELECT_CANCEL)
                    return False
                return True
Example #30
0
    def _find_boss_for_fight(self):
        """Finds available boss fight and enter it.

        :return: was fight found and entered or not.
        :rtype: bool
        """
        weekly_boss_name = self.emulator.get_screen_text(
            ui_element=ui.INVASION_NAME)
        logger.debug(f"Weekly boss name: {weekly_boss_name}")
        for bosses in [
                'INVASION_TWILIGHT_BATTLE_', 'INVASION_BLACK_ORDER_BATTLE_'
        ]:
            for boss_index in range(1, 8):
                boss_ui = ui.get_by_name(f'{bosses}{boss_index}')
                boss_time = self.emulator.get_screen_text(ui_element=boss_ui)
                if boss_time:
                    logger.debug(
                        f"Found boss with UI: {boss_ui} with time {boss_time}, entering."
                    )
                    self.emulator.click_button(boss_ui)
                    if wait_until(self.emulator.is_ui_element_on_screen,
                                  ui_element=ui.INVASION_BOSS_FIGHT_ENTER):
                        self._boss_mission = self.emulator.get_screen_text(
                            ui.INVASION_BOSS_MISSION)
                        logger.debug(
                            f"Current boss mission: {self._boss_mission}")
                        self.emulator.click_button(
                            ui.INVASION_BOSS_FIGHT_ENTER)
                        return True
                    logger.error(
                        f"Something went wrong with found boss {boss_ui}")
                    if wait_until(self.emulator.is_ui_element_on_screen,
                                  ui_element=ui.INVASION_BOSS_FIGHT_CLOSE):
                        logger.warning(f"Closing {boss_ui}")
                        self.emulator.click_button(
                            ui.INVASION_BOSS_FIGHT_CLOSE)
        logger.error("Failed to found boss.")
        return False