def acquire_free_artifact_chest(self): """Acquires available Free Artifact Chest.""" if not self.open_artifact_store(): return logger.error("Can't open Artifact Store.") self.emulator.click_button(ui.STORE_ARTIFACT_FREE_CHEST) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.STORE_ARTIFACT_FREE_CHEST_BUTTON_ACQUIRE): logger.debug("Acquiring Free Artifact Chest.") self.emulator.click_button(ui.STORE_ARTIFACT_FREE_CHEST_BUTTON_ACQUIRE) 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) r_sleep(1) # Wait for animation logger.info("Free Artifact Chest acquired.") self.emulator.click_button(ui.MENU_BACK) r_sleep(1) # Wait for animation else: logger.info("No available Free Artifact Chest, exiting.") self.emulator.click_button(ui.MENU_BACK) r_sleep(1) # Wait for animation self.game.go_to_main_menu()
def _buy_material(self, material_ui, max_items=True): """Buys material from Support Shop. :param ui.UIElement material_ui: UI Element of material to buy. :param bool max_items: buy all items or not. """ logger.debug(f"Buying material with UI: {material_ui}") self.emulator.click_button(material_ui) if not wait_until( self.emulator.is_ui_element_on_screen, ui_element=ui.SUPPORT_SHOP_BUY_MATERIAL_EXCHANGE_BUTTON): return logger.warning( "Cannot get into Exchange menu, probably material has been already bought." ) if max_items and self.emulator.is_ui_element_on_screen( ui.SUPPORT_SHOP_BUY_MATERIAL_MAX_BUTTON): logger.debug("Clicking MAX button.") self.emulator.click_button(ui.SUPPORT_SHOP_BUY_MATERIAL_MAX_BUTTON) self.emulator.click_button( ui.SUPPORT_SHOP_BUY_MATERIAL_EXCHANGE_BUTTON) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.SUPPORT_SHOP_BUY_MATERIAL_CLOSE_PURCHASE): logger.info("Material acquired.") r_sleep(1) # Wait for animation self.emulator.click_button( ui.SUPPORT_SHOP_BUY_MATERIAL_CLOSE_PURCHASE)
def fight(self): """Starts battle and waits until the end.""" def wait_battle(): self.skip_cutscene() return self.is_battle() if confirm_condition_by_time(confirm_condition=self.is_battle_over): return logger.warning("Battle is already over") if not wait_until(wait_battle, timeout=60, period=1): return logger.error("Can't find MELEE button on screen after starting a battle.") logger.info("Battle is started") if not wait_until(self.emulator.is_image_on_screen, timeout=2, ui_element=ui.AUTOPLAY_TOGGLE): logger.debug("Found AUTO PLAY toggle inactive. Clicking it.") self.emulator.click_button(ui.AUTOPLAY_TOGGLE) while not self.is_battle_over(): if not self.is_battle(): self.skip_cutscene() r_sleep(self._30_FPS) r_sleep(1) # Wait for end of the battle animations if self._disconnected: return logger.debug("Disconnect condition was triggered.") # Check for possible notifications after end of the battle if not wait_until(confirm_condition_by_time, confirm_condition=self.is_battle_over, timeout=10): return self.fight() logger.info("Battle is over")
def go_to_content_status_board(self): """Goes to Content Status Board screen.""" self.go_to_main_menu() if wait_until(self.is_main_menu): self.emulator.click_button(ui.CONTENT_STATUS_BOARD_BUTTON) return wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.CONTENT_STATUS_BOARD_LABEL)
def press_start_button(self, start_button_ui=ui.INVASION_BOSS_FIGHT_START, ignore_coop_mission=False): """Presses start button of the mission. :return: was button clicked successfully or not. :rtype: bool """ logger.debug( f"Pressing START button with UI Element: {start_button_ui}.") if wait_until(self.emulator.is_ui_element_on_screen, ui_element=start_button_ui): self._deploy_characters(ignore_coop_mission=ignore_coop_mission) self.emulator.click_button(start_button_ui) if wait_until(self._check_notifications_before_fight, timeout=10): return True if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.INVASION_NO_CHEST_SLOTS): logger.warning("No slots for chests. Exiting.") self.emulator.click_button(ui.INVASION_NO_CHEST_SLOTS) return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.DISCONNECT_NEW_OPPONENT): logger.debug( "Found disconnect notification. Trying to start again.") self.emulator.click_button(ui.DISCONNECT_NEW_OPPONENT) return True logger.error(f"Unable to press {start_button_ui} button.") return False
def press_start_button(self, start_button_ui='INVASION_BOSS_FIGHT_START'): """Press start button of the mission. :return: was button clicked successfully. """ logger.debug( f"Pressing START button with UI Element: {start_button_ui}.") if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui[start_button_ui]): self._deploy_characters() self.emulator.click_button(self.ui[start_button_ui].button) if wait_until(self._check_notifications_before_fight, timeout=10): return True if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['INVASION_NO_CHEST_SLOTS']): logger.warning("No slots for chests. Exiting.") self.emulator.click_button( self.ui['INVASION_NO_CHEST_SLOTS'].button) return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=self.ui['DISCONNECT_NEW_OPPONENT']): logger.debug( "Found disconnect notification. Trying to start again.") self.emulator.click_button( self.ui['DISCONNECT_NEW_OPPONENT'].button) return True logger.warning("Unable to press START button.") return False
def _select_legendary_battle_from_bottom(self, title, battle, mode): """Select Legendary Battle from bottom of the list. :param UIElement title: title of legendary battle. :param UIElement battle: legendary battle. :param mode: difficulty of legendary battle. """ if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=title): logger.debug( f"Found selected {title.text}, entering with {mode} mode.") return self._select_battle_mode(mode=mode) else: logger.debug(f"{title.text} isn't selected, trying to found it.") self.emulator.drag(self.ui['LB_DRAG_FROM'].button, self.ui['LB_DRAG_TO'].button) r_sleep(1) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=battle): logger.debug(f"Found {title.text} battle. Selecting.") self.emulator.click_button(battle.button) return self._select_legendary_battle_from_bottom(title=title, battle=battle, mode=mode) return False
def press_start_button(self, start_button_ui='START_BUTTON'): """Press start button of the mission. :return: was button clicked. """ if self.emulator.is_ui_element_on_screen(self.ui[start_button_ui]): self.select_team() self.emulator.click_button(self.ui[start_button_ui].button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=self.ui['NOT_ENOUGH_ENERGY']): self.emulator.click_button(self.ui['NOT_ENOUGH_ENERGY'].button) logger.warning( f"Not enough energy for starting mission, current energy: {self.game.energy}" ) return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=self.ui['INVENTORY_FULL']): self.emulator.click_button(self.ui['INVENTORY_FULL'].button) logger.warning("Your inventory is full, cannot start mission.") return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=self.ui['ITEM_MAX_LIMIT_NOTIFICATION']): self.emulator.click_button( self.ui['ITEM_MAX_LIMIT_NOTIFICATION'].button) return True logger.warning("Unable to press START button.") return False
def press_start_button(self, deploy_characters=True): """Press start button of the mission. :return: was button clicked successfully. """ logger.debug( f"Pressing START button with character deployment: {deploy_characters}" ) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['INVASION_BOSS_FIGHT_START']): if deploy_characters: self.player.click_button( self.ui['INVASION_CHARACTER_1'].button) self.player.click_button( self.ui['INVASION_CHARACTER_2'].button) self.player.click_button( self.ui['INVASION_CHARACTER_3'].button) self.player.click_button( self.ui['INVASION_BOSS_FIGHT_START'].button) if wait_until(self.check_fight_notifications, timeout=10): return True if wait_until(self.player.is_ui_element_on_screen, timeout=2, ui_element=self.ui['DISCONNECT_NEW_OPPONENT']): logger.debug( "Found disconnect notification. Trying to start again.") self.player.click_button(self.ui['DISCONNECT_NEW_OPPONENT'].button) return True logger.warning("Unable to press START button.") return False
def press_start_button(self, start_button_ui=ui.DM_START_BUTTON, use_hidden_tickets=False): """Presses start button of the mission.""" if self.emulator.is_ui_element_on_screen(start_button_ui): self.select_team() self.emulator.click_button(start_button_ui) if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.NOT_ENOUGH_ENERGY): self.emulator.click_button(ui.NOT_ENOUGH_ENERGY) logger.warning(f"Not enough energy for starting mission, current energy: {self.game.energy}") return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.INVENTORY_FULL): self.emulator.click_button(ui.INVENTORY_FULL) logger.warning("Your inventory is full, cannot start mission.") return False if use_hidden_tickets and wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.DM_TICKET_NOTIFICATION_USE): logger.debug("Clicked USE hidden tickets.") self.emulator.click_button(ui.DM_TICKET_NOTIFICATION_USE) if not use_hidden_tickets and wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.DM_TICKET_NOTIFICATION_DONT_USE): logger.debug("Clicked DON'T USE hidden tickets.") self.emulator.click_button(ui.DM_TICKET_NOTIFICATION_DONT_USE) if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.ITEM_MAX_LIMIT_NOTIFICATION): self.emulator.click_button(ui.ITEM_MAX_LIMIT_NOTIFICATION) return True logger.error(f"Unable to press START button with UI element: {start_button_ui}.") return False
def repeat_mission(self, times): """Repeat missions. :param times: how many times to repeat. """ for _ in range(times): if not self.press_start_button(): logger.error( "Cannot start missions while repeating them, exiting.") return AutoBattleBot(self.game, self.battle_over_conditions).fight() self.close_mission_notifications() repeat_button_ui = None if wait_until( self.emulator.is_image_on_screen, timeout=2, ui_element=self.ui['REPEAT_BUTTON_IMAGE_POSITION_2']): repeat_button_ui = 'REPEAT_BUTTON_IMAGE_POSITION_2' else: if wait_until( self.emulator.is_image_on_screen, timeout=2, ui_element=self.ui['REPEAT_BUTTON_IMAGE_POSITION_1']): repeat_button_ui = 'REPEAT_BUTTON_IMAGE_POSITION_1' if repeat_button_ui: self.press_repeat_button(repeat_button_ui)
def go_to_stages_list(self): """Go to Legendary Battle stages list screen.""" self.game.select_mode(self.mode_name) legendary_home = wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['LB_MENU_LABEL']) difficulty_on_screen = wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['LB_DIFFICULTY_NORMAL']) return legendary_home and difficulty_on_screen
def start_stage(self, stage_button, stage_num, farm_shifter_bios=False): """Starts Epic Quests stage. :param ui.UIElement stage_button: rect of button to start stage. :param int stage_num: available stages count. :param bool farm_shifter_bios: should game be restarted if shifter isn't appeared. """ if not wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.START_BUTTON): self.emulator.click_button(stage_button) wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.START_BUTTON) if not self.press_start_button(): logger.error( f"Cannot start Epic Quest stage {self.mode_name}, exiting.") return 0 auto_battle_bot = AutoBattleBot(self.game, self.battle_over_conditions) ally_appeared = auto_battle_bot.wait_until_shifter_appeared( ) if farm_shifter_bios else True if farm_shifter_bios and not ally_appeared: logger.info("No shifter, restarting.") if self.game.restart_game(repeat_while=auto_battle_bot.is_battle): self.game.select_mode(self.mode_name) return stage_num auto_battle_bot.fight() stage_num -= 1 logger.debug(f"{stage_num} stages left to complete.") self.close_mission_notifications() if stage_num > 0: self.press_repeat_button() else: self.press_home_button() return stage_num
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()
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
def manual_bot_start(self): """Start manual bot for the fight.""" ManualBattleBot(self.game, self.battle_over_conditions, self.disconnect_conditions).fight() if self.player.is_ui_element_on_screen( ui_element=self.ui['INVASION_SLOT_CHEST']): self.player.click_button(self.ui['INVASION_SLOT_CHEST'].button) self._chests += 1 if wait_until(self.player.is_image_on_screen, timeout=2, ui_element=self.ui['INVASION_HOME_BUTTON']): if self._chests < self._max_chests: self.press_repeat_button( repeat_button_ui='INVASION_REPEAT_BUTTON', start_button_ui='INVASION_BOSS_FIGHT_START') else: self.press_home_button(home_button='INVASION_HOME_BUTTON') return # In case we got back from fight by disconnect or something else logger.debug("Any chest after boss fight wasn't acquired.") if wait_until(self.player.is_ui_element_on_screen, timeout=20, ui_element=self.ui['INVASION_BOSS_FIGHT_START']): if self.press_start_button(deploy_characters=False): self.wait_for_players()
def _acquire_chest(self, chest_index): """Acquire chest by chest index. :param chest_index: chest index (from 1 to max chests + 1) :return: True or False: was chest acquired. """ logger.debug(f"Trying to acquire chest #{chest_index}") chest_ui = self.ui[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.button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['INVASION_SKIP_CHEST']): while self.emulator.is_ui_element_on_screen( ui_element=self.ui['INVASION_SKIP_CHEST']): logger.debug("Skipping chests items.") self.emulator.click_button( self.ui['INVASION_SKIP_CHEST'].button, min_duration=0.5, max_duration=0.8) while not self.emulator.is_ui_element_on_screen( ui_element=self.ui['INVASION_CHESTS_MENU_LABEL']): self.emulator.click_button( self.ui['INVASION_SKIP_CHEST'].button, 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
def go_to_alliance(self): """Go to Alliance screen.""" self.go_to_main_menu() self.emulator.click_button(self.ui['MAIN_MENU'].button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['MAIN_MENU']): if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['MAIN_MENU_ALLIANCE']): self.emulator.click_button( self.ui['MAIN_MENU_ALLIANCE'].button) if wait_until( self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ALLIANCE_LEVEL_UP_NOTIFICATION']): logger.debug("Closing Alliance level up notification.") self.emulator.click_button( self.ui['ALLIANCE_LEVEL_UP_NOTIFICATION'].button) return wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ALLIANCE_LABEL']) logger.warning("Can't find Alliance button in Main menu, exiting") self.emulator.click_button(self.ui['MAIN_MENU'].button) return False
def _wait_for_players_and_start_fight(self): """Wait for players before start of the fight.""" if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['WAITING_FOR_OTHER_PLAYERS']): logger.debug("Waiting for other players before battle.") if wait_until(self.emulator.is_ui_element_on_screen, timeout=60, condition=False, period=0.5, ui_element=self.ui['WAITING_FOR_OTHER_PLAYERS']): if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=self.ui['DISCONNECT_NEW_OPPONENT']): logger.debug( "Found disconnect notification. Trying to start again." ) self.emulator.click_button( self.ui['DISCONNECT_NEW_OPPONENT'].button) self._wait_for_players_and_start_fight() return logger.debug("Battle is loading. Starting manual bot.") self._manual_bot_start() return logger.error("Waiting other emulator very long, trying to reset.") self.emulator.click_button( self.ui['WAITING_FOR_OTHER_PLAYERS'].button)
def _select_and_upgrade_iso8(self, times, iso_to_use, stars_to_use): """Selects available for upgrade ISO-8 from inventory's grid and then upgrades it. :param int times: how many times to select new ISO-8 for upgrading. :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. """ for _ in range(times): if not self._try_to_select_iso8_for_upgrade(): return logger.info("No available ISO-8 for upgrades on first page in the inventory grid.") if not self.toggle_quick_upgrade(): return logger.error(f"ISO-8: can't find {ui.ISO8_QUICK_UPGRADE} button, cannot upgrade.") self.emulator.click_button(ui.ISO8_QUICK_UPGRADE) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_QUICK_UPGRADE_MENU): self._select_types_for_upgrade(iso_to_use=iso_to_use, stars_to_use=stars_to_use) logger.debug("ISO-8: confirming upgrading.") self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_CONFIRM) self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_CONFIRM) # To skip animation if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ISO8_QUICK_UPGRADE_RESULTS): self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_RESULTS) else: if self.emulator.is_ui_element_on_screen(ui.ISO8_QUICK_UPGRADE_MENU): logger.info("Not enough ISO-8 types/stars to perform upgrade.") self.emulator.click_button(ui.ISO8_QUICK_UPGRADE_MENU) return self.close_after_mission_notifications()
def press_start_button(self, start_button_ui=ui.START_BUTTON): """Presses start button of the mission.""" if self.emulator.is_ui_element_on_screen(start_button_ui): self.select_team() self.emulator.click_button(start_button_ui) if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.NOT_ENOUGH_ENERGY): self.emulator.click_button(ui.NOT_ENOUGH_ENERGY) logger.warning( f"Not enough energy for starting mission, current energy: {self.game.energy}" ) return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.INVENTORY_FULL): self.emulator.click_button(ui.INVENTORY_FULL) logger.warning("Your inventory is full, cannot start mission.") return False if wait_until(self.emulator.is_ui_element_on_screen, timeout=2, ui_element=ui.ITEM_MAX_LIMIT_NOTIFICATION): self.emulator.click_button(ui.ITEM_MAX_LIMIT_NOTIFICATION) return True logger.error(f"Unable to press {start_button_ui} button.") return False
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)
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
def dismantle_artifacts(self, artifact_stars): """Dismantles artifacts. :param str | list[str] artifact_stars: artifact's stars to dismantle. See `ARTIFACT_STARS` for reference. """ if not artifact_stars: logger.warning("Nothing to dismantle.") return self.game.go_to_main_menu() if not self.open_artifact_tab(): logger.error("Can't get to Artifact tab in the inventory.") return self.game.go_to_main_menu() if not self._open_dismantle_menu(): logger.error("Can't open Dismantle menu.") return self.game.go_to_main_menu() if not self._auto_select_for_dismantle(artifact_stars=artifact_stars): return self.game.go_to_main_menu() if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ARTIFACT_DISMANTLE_CONFIRM): logger.debug("Dismantling artifacts.") self.emulator.click_button(ui.ARTIFACT_DISMANTLE_CONFIRM) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ARTIFACT_DISMANTLE_CONFIRM_OK): self.emulator.click_button(ui.ARTIFACT_DISMANTLE_CONFIRM_OK) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ARTIFACT_DISMANTLE_CONFIRM_CLOSE, timeout=10): logger.info("Artifacts were dismantled.") self.emulator.click_button(ui.ARTIFACT_DISMANTLE_CONFIRM_CLOSE) self.game.go_to_main_menu()
def press_start_button(self, check_inventory=True): """Start Co-op mission stage.""" self.player.click_button(self.ui['COOP_START_BUTTON'].button) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['WAITING_FOR_OTHER_PLAYERS']): logger.debug("Waiting for other players.") if wait_until(self.player.is_ui_element_on_screen, timeout=60, condition=False, ui_element=self.ui['WAITING_FOR_OTHER_PLAYERS']): if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['DISCONNECT_NEW_OPPONENT']): logger.debug("Got disconnected. Finding new opponent.") self.player.click_button( self.ui['DISCONNECT_NEW_OPPONENT'].button) return self.press_start_button(check_inventory=False) AutoBattleBot(self.game, self.battle_over_conditions, self.disconnect_conditions).fight() r_sleep(2) # wait progress bar animation if self.stages > 0: self.press_repeat_button() else: self.press_home_button() return if check_inventory and wait_until( self.player.is_ui_element_on_screen, timeout=2, ui_element=self.ui['INVENTORY_FULL']): self.player.click_button(self.ui['INVENTORY_FULL'].button) self.stages *= 0 return logger.warning("Something went wrong while waiting for other players.") self.player.click_button(self.ui['WAITING_FOR_OTHER_PLAYERS'].button)
def collect_energy_from_challenges(self, collect_daily=True, collect_weekly=True): """Collects energy from Alliance Challenges. :param bool collect_daily: collect daily rewards or not. :param bool collect_weekly: collect weekly rewards or not. """ if not collect_daily and not collect_weekly: logger.info("Nothing to collect.") return self.game.go_to_main_menu() self.game.go_to_alliance() if not wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_CHALLENGES_TAB): logger.error(f"Can't find {ui.ALLIANCE_CHALLENGES_TAB} tab, exiting.") return self.game.go_to_main_menu() self.emulator.click_button(ui.ALLIANCE_CHALLENGES_TAB) if collect_daily and wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_CHALLENGES_DAILY_ENERGY): logger.info("Collecting daily energy from challenge.") self.emulator.click_button(ui.ALLIANCE_CHALLENGES_DAILY_ENERGY) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_CHALLENGES_REWARD_CLOSE): self.emulator.click_button(ui.ALLIANCE_CHALLENGES_REWARD_CLOSE) if collect_weekly and wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_CHALLENGES_WEEKLY_ENERGY): logger.info("Collecting weekly energy from challenge.") self.emulator.click_button(ui.ALLIANCE_CHALLENGES_WEEKLY_ENERGY) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_CHALLENGES_REWARD_CLOSE): self.emulator.click_button(ui.ALLIANCE_CHALLENGES_REWARD_CLOSE) self.game.go_to_main_menu()
def start_missions(self): """Start available missions.""" logger.info(f"{self.stages} stages available.") if self.stages > 0: self.open_coop_play() self.check_rewards() if wait_until(self.emulator.is_image_on_screen, timeout=1, ui_element=self.ui['COOP_REPEAT_TOGGLE']): logger.debug("Found REPEAT toggle active. Clicking it.") self.emulator.click_button( self.ui['COOP_REPEAT_TOGGLE'].button) if not wait_until(self.emulator.is_image_on_screen, timeout=1, ui_element=self.ui['COOP_QUICK_MATCH_TOGGLE']): logger.debug("Found QUICK MATCH toggle inactive. Clicking it.") self.emulator.click_button( self.ui['COOP_QUICK_MATCH_TOGGLE'].button) while self.stages > 0: if not self._deploy_character(): logger.warning( "Can't deploy character. Probably you run out of available. Exiting" ) self.stages *= 0 break self.press_start_button() self.check_rewards() logger.info("No more stages.")
def donate_resources(self, donate_gold=True, donate_memento=True): """Donates resources to Alliance :param bool donate_gold: True or False. :param bool donate_memento: True or False. """ if not donate_gold and not donate_memento: logger.info("Nothing to donate.") return self.game.go_to_main_menu() self.game.go_to_alliance() if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_DONATE): self.emulator.click_button(ui.ALLIANCE_DONATE) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_DONATION_MENU): if donate_gold: logger.debug("Maxing GOLD for donation.") self.emulator.click_button(ui.ALLIANCE_DONATION_MAX_GOLD) if donate_memento: logger.debug("Maxing ALLIANCE MEMENTO for donation.") self.emulator.click_button(ui.ALLIANCE_DONATION_MAX_MEMENTO) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_DONATION_CONFIRM): logger.info("Donating resources for Alliance.") self.emulator.click_button(ui.ALLIANCE_DONATION_CONFIRM) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ALLIANCE_DONATION_REWARD_CLOSE): logger.info("Resources were donated, exiting.") self.emulator.click_button(ui.ALLIANCE_DONATION_REWARD_CLOSE) else: logger.warning("Can't donate resource for Alliance. Probably already donated, exiting.") self.emulator.click_button(ui.ALLIANCE_DONATION_CANCEL) self.game.go_to_main_menu()
def go_to_timeline_battle(self): """Go to TimeLine battle screen and select battle.""" self.game.select_mode(self.mode_name) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['TL_LEAGUE_NOTIFICATION']): self.player.click_button(self.ui['TL_LEAGUE_NOTIFICATION'].button) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['TL_GET_READY_BUTTON']): self.player.click_button(self.ui['TL_GET_READY_BUTTON'].button) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['TL_RESTRICTED_NOTIFICATION']): self.player.click_button( self.ui['TL_RESTRICTED_NOTIFICATION'].button) if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['TL_SEARCH_BUTTON']): if wait_until(self.player.is_image_on_screen, timeout=1, ui_element=self.ui['TL_REPEAT_TOGGLE']): logger.debug("Found REPEAT toggle active. Clicking it.") self.player.click_button( self.ui['TL_REPEAT_TOGGLE'].button) self.select_team() self.player.click_button(self.ui['TL_SEARCH_BUTTON'].button)
def acquire_free_hero_chest(self): """Acquires available Free Hero Chest.""" self.open_character_store() if self._open_hero_chest_tab(): if not wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.STORE_CHARACTER_FREE_HERO_CHEST_BUTTON): logger.info("No available Free Hero Chest, exiting.") return self.game.go_to_main_menu() logger.info("Free Hero Chest is available.") self.emulator.click_button(ui.STORE_CHARACTER_FREE_HERO_CHEST_BUTTON) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.STORE_CHARACTER_FREE_HERO_CHEST_BUTTON_ACQUIRE): self.emulator.click_button(ui.STORE_CHARACTER_FREE_HERO_CHEST_BUTTON_ACQUIRE) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.STORE_CHARACTER_FREE_HERO_CHEST_PURCHASE): self.emulator.click_button(ui.STORE_CHARACTER_FREE_HERO_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_CHARACTER_FREE_HERO_CHEST_PURCHASE_CLOSE): self.emulator.click_button(ui.STORE_CHARACTER_FREE_HERO_CHEST_PURCHASE_CLOSE) r_sleep(1) # Wait for animation logger.info("Free Hero Chest acquired.") self.emulator.click_button(ui.MENU_BACK) r_sleep(1) # Wait for animation self.game.go_to_main_menu()