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()
def _is_event_ui_has_same_name(self, name, event_ui, similar_to_full_line): """Checks if event UI element has same name as given event name. :param str name: event name. :param ui.UIElement event_ui: event UI Element :param bool similar_to_full_line: take name of event as full line of text or part of any line. """ event_text = self.emulator.get_screen_text(event_ui) logger.debug(f"Found text inside event list: {event_text}") if similar_to_full_line and is_strings_similar(event_text, name): return True if not similar_to_full_line: for line in event_text.split("\n"): if is_strings_similar(line, name): return True
def _reset_world_boss(self, target_world_boss, current_reset, max_resets): """Resets World Boss in reset menu. :param list[str] target_world_boss: name or list of the Bosses' names for reset. :param int current_reset: number of current reset to compare with maximum. :param int max_resets: number of maximum resets. """ if current_reset > max_resets: return logger.warning( f"Achieved max resets of {current_reset} for Today's World Boss." ) current_world_boss = self.emulator.get_screen_text( ui.WB_RESET_TODAYS_BOSS_NAME) logger.debug( f"Current boss of the day is {current_world_boss}; resetting for {target_world_boss}" ) target_world_boss_found = [ is_strings_similar(boss, current_world_boss) for boss in target_world_boss ] if any(target_world_boss_found): logger.debug("No need to reset World Boss. Exiting reset menu.") self.emulator.click_button(ui.WB_RESET_TODAYS_BOSS_MENU_CLOSE) return self.game.go_to_main_menu() else: logger.debug("Resetting World Boss of the day.") self.emulator.click_button(ui.WB_RESET_TODAYS_BOSS_BUTTON) r_sleep(1) # Wait for reset animation return self._reset_world_boss(target_world_boss=target_world_boss, current_reset=current_reset + 1, max_resets=max_resets)
def is_ui_element_on_screen(self, ui_element, screen=None): """Check if UI element is on screen. :param ui.UIElement ui_element: UI element. :param screen: screen image. :return: True or False. """ text_on_screen = self.get_screen_text(ui_element, screen) return is_strings_similar(ui_element.text, text_on_screen)
def is_ui_element_on_screen(self, ui_element, screen=None): """Checks if UI element is on screen. :param lib.game.ui.UIElement ui_element: UI element hat has all info for text recognition. :param numpy.ndarray screen: screen image. :rtype: bool """ text_on_screen = self.get_screen_text(ui_element, screen) return is_strings_similar(ui_element.text, text_on_screen)
def close_epic_quest_notification(self): """Closes Epic Quest notification. :return: was notification closed or not. :rtype: bool """ epic_quest = self.emulator.get_screen_text(ui.EQ_NOTIFICATION_OK) # Use overlap less 0.25 because sometimes 'EPIC QUEST' is similar to 'HEROIC QUEST' with default overlap if is_strings_similar(ui.EQ_NOTIFICATION_OK.text, epic_quest, overlap=0.15): self.emulator.click_button(ui.EQ_NOTIFICATION_OK) return True return False
def close_epic_quest_notification(self): """Close Epic Quest notification. :return: True or False: was notification closed. """ epic_quest = self.emulator.get_screen_text( self.ui['EQ_NOTIFICATION_OK']) # Use overlap less 0.25 because sometimes 'EPIC QUEST' is similar to 'HEROIC QUEST' with default overlap if is_strings_similar(self.ui['EQ_NOTIFICATION_OK'].text, epic_quest, overlap=0.15): self.emulator.click_button(self.ui['EQ_NOTIFICATION_OK'].button) return True return False
def get_mode_from_element(self, board_rect, element_rect): """Get information about game mode from single game mode element. :param board_rect: rectangle of Content Status Board. :param element_rect: rectangle of single game mode element inside board. :return: dictionary with information about game mode inside element_rect. """ # Getting global rects of elements element_ui = ui.UIElement('UI_BOARD_ELEMENT', text_rect=element_rect) element_ui.rect.parent = board_rect self.ui['CONTENT_STATUS_ELEMENT_LABEL'].rect.parent = element_ui.rect self.ui['CONTENT_STATUS_ELEMENT_STAGE'].rect.parent = element_ui.rect self.ui[ 'CONTENT_STATUS_ELEMENT_COMPLETE'].rect.parent = element_ui.rect self.ui['CONTENT_STATUS_ELEMENT_LABEL'].scale = 3 self.ui['CONTENT_STATUS_ELEMENT_STAGE'].scale = 3 # Getting board image and element image. Use it for stage recognize board_image = self.player.get_screen_image(board_rect.value) element_image = self.player.get_image_from_image( board_image, element_ui) stage_label_image = self.player.get_image_from_image( element_image, self.ui['CONTENT_STATUS_ELEMENT_LABEL']) stage_label = self.player.get_screen_text( self.ui['CONTENT_STATUS_ELEMENT_LABEL'], screen=stage_label_image) logger.debug(f"Stage found: {stage_label}") stage_completion_screen = self.player.get_image_from_image( element_image, self.ui['CONTENT_STATUS_ELEMENT_COMPLETE']) if self.player.is_ui_element_on_screen( self.ui['CONTENT_STATUS_ELEMENT_COMPLETE'], screen=stage_completion_screen): current_stages, max_stages = 0, 0 else: stage_counter_image = self.player.get_image_from_image( element_image, self.ui['CONTENT_STATUS_ELEMENT_STAGE']) stage_counter_text = self.player.get_screen_text( self.ui['CONTENT_STATUS_ELEMENT_STAGE'], screen=stage_counter_image) logger.debug(f"Stage: {stage_label}; stages: {stage_counter_text}") current_stages, max_stages = self.get_current_and_max_values_from_text( stage_counter_text) # Find mode and return info about stages and board for mode_name in self._mode_names: if is_strings_similar(mode_name, stage_label): game_mode = GameMode(name=mode_name, stages=current_stages, max_stages=max_stages, ui_button=element_ui.rect.global_rect, ui_board=board_rect.value) return game_mode
def solve_trivia(self): """Solve trivia question.""" question = self.player.get_screen_text(ui_element=self.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 answers: logger.debug(f"Found answers: {answers}, selecting.") for answer in answers: for i in range(1, 5): available_answer_ui = self.ui[f'DAILY_TRIVIA_ANSWER_{i}'] available_answer = self.player.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.name}, clicking.") self.player.click_button(available_answer_ui.button) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['DAILY_TRIVIA_CLOSE_ANSWER']): self.player.click_button(self.ui['DAILY_TRIVIA_CLOSE_ANSWER'].button) return True else: logger.error("Something went wrong after selecting correct answer.") logger.error(f"Can find answer for question: {question}") return False
def solve_trivia(self): """Solve trivia question.""" def close_notifications(): return self.game.close_complete_challenge_notification() or self.close_shield_lvl_up_notification() question = self.emulator.get_screen_text(ui_element=self.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 = self.ui[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.name}, clicking.") self.emulator.click_button(available_answer_ui.button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['DAILY_TRIVIA_CLOSE_ANSWER']): self.emulator.click_button(self.ui['DAILY_TRIVIA_CLOSE_ANSWER'].button) notification_closed = wait_until(close_notifications, timeout=3) logger.debug(f"Complete challenge notifications was closed: {notification_closed}") return True else: logger.error("Something went wrong after selecting correct answer.") else: logger.error("No available answers was found for trivia question.") random_answer = randint(1, 4) random_answer_ui = self.ui[f'DAILY_TRIVIA_ANSWER_{random_answer}'] logger.warning(f"Selecting random answer: {random_answer}.") self.emulator.click_button(random_answer_ui.button) return True
def close_heroic_quest_notification(self): """Closes Heroic Quest notification. :return: was notification closed or not. :rtype: bool """ heroic_quest = self.emulator.get_screen_text(ui.HQ_NOTIFICATION_OK) # Use overlap less 0.25 because sometimes 'EPIC QUEST' is similar to 'HEROIC QUEST' with default overlap if is_strings_similar(ui.HQ_NOTIFICATION_OK.text, heroic_quest, overlap=0.15): if self.game.ACQUIRE_HEROIC_QUEST_REWARDS: self.emulator.click_button(ui.HQ_NOTIFICATION_OPEN) HeroicQuests(self.game).acquire_reward_and_return_back() else: self.emulator.click_button(ui.HQ_NOTIFICATION_OK) return True return False
def get_mode_from_element(self, board_rect, element_rect): """Gets information about game mode from single game mode element. `element_rect` rectangle is made from coordinates that are local inside any Content Status Board rectangle. In order to obtain info about element, method creates temporary UI element and calculates `element_rect` local coordinates into global coordinates inside `board_rect`. :param ui.Rect board_rect: rectangle that represents current Content Status Board. See `ui.CONTENT_STATUS_BOARD_1` or `ui.CONTENT_STATUS_BOARD_2` for reference. :param ui.Rect element_rect: rectangle of single game mode element inside board. See `ui.CONTENT_STATUS_ELEMENT_1` for reference. :rtype: GameMode """ def create_global_copy(ui_element: ui.UIElement, parent_rect: ui.Rect): copy_ui = ui_element.copy() copy_ui.text_rect.parent = parent_rect copy_ui.text_rect = copy_ui.text_rect.global_rect return copy_ui # Getting global rects of elements element_ui = ui.UIElement(name='UI_BOARD_ELEMENT') element_ui.button_rect = element_rect element_ui.button_rect.parent = board_rect label_ui = create_global_copy( ui_element=ui.CONTENT_STATUS_ELEMENT_LABEL, parent_rect=element_ui.button_rect) stage_ui = create_global_copy( ui_element=ui.CONTENT_STATUS_ELEMENT_STAGE, parent_rect=element_ui.button_rect) stage_label = self.emulator.get_screen_text(label_ui) stage_counter_text = self.emulator.get_screen_text(stage_ui) logger.debug(f"Stage: {stage_label}; stages: {stage_counter_text}") current_stages, max_stages = self.get_current_and_max_values_from_text( stage_counter_text) # Find mode and return info about stages and board for mode_name in self._mode_names: if is_strings_similar(mode_name, stage_label): game_mode = GameMode(name=mode_name, stages=current_stages, max_stages=max_stages, ui_button=element_ui, ui_board=board_rect.value) return game_mode