def start_missions(self, times=0, difficulty=15): """Start Dimension Missions. :param times: :param difficulty: name of UI element that contains info about difficulty of stage. """ logger.info(f"Starting Dimensions Missions for {times} times.") if not self.go_to_dm(): logger.warning("Dimension Mission: can't get in mission lobby.") return self.select_stage_level(level_num=difficulty) while times > 0: if self.get_ready(): r_sleep(1) if not self.is_stage_startable(): logger.error( "Cannot start Dimension Mission battle, not enough boost points." ) return if not self.press_start_button( start_button_ui='DM_START_BUTTON'): logger.error( "Cannot start Dimension Mission battle, exiting.") return AutoBattleBot(self.game, self.battle_over_conditions).fight() times -= 1 self.close_mission_notifications() if times > 0: self.press_repeat_button() else: self.press_home_button() self.close_after_mission_notifications() logger.info("No more stages for Dimension Missions.")
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
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()
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 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 start_missions(self, times=0, difficulty=15, use_hidden_tickets=False): """Start Dimension Missions. :param times: how many times to complete missions. :param difficulty: name of UI element that contains info about difficulty of stage. :param use_hidden_tickets: use Hidden Tickets or not. """ logger.info(f"Starting Dimensions Missions for {times} times.") if not self.open_dimension_mission(): logger.warning("Can't get in mission lobby.") return self._select_stage_level(level_num=difficulty) if self._get_ready_for_mission(): r_sleep(1) if not self.is_stage_startable(): logger.error( "Cannot start Dimension Mission battle, not enough boost points." ) return while times > 0: if not self.press_start_button( start_button_ui='DM_START_BUTTON', use_hidden_tickets=use_hidden_tickets): logger.error("Cannot start Dimension Mission battle, exiting.") return AutoBattleBot(self.game, self.battle_over_conditions).fight() times -= 1 self.close_mission_notifications() if times > 0: self.press_repeat_button() else: self.press_home_button() self.close_after_mission_notifications() logger.info("No more stages.")
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 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 find_mode_on_content_status_board(self, mode_name): """Finds game mode on Content Status Board. :param str mode_name: name of game mode. """ if not self.go_to_content_status_board(): return logger.error("Failed to open Content Status board.") mode = self.find_mode_on_board(mode_name=mode_name, board=ui.CONTENT_STATUS_BOARD_1, rows=3, cols=4) if mode: self.go_to_main_menu() return mode self.emulator.drag(ui.CONTENT_STATUS_DRAG_FROM, ui.CONTENT_STATUS_DRAG_TO, duration=0.2) r_sleep(1) self.emulator.drag(ui.CONTENT_STATUS_DRAG_FROM, ui.CONTENT_STATUS_DRAG_TO, duration=0.2) r_sleep(1) mode = self.find_mode_on_board(mode_name=mode_name, board=ui.CONTENT_STATUS_BOARD_2, rows=3, cols=4) if mode: self.go_to_main_menu() return mode
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 _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 find_mode_on_content_status_board(self, mode_name): """Find game mode on Content Status Board. :param mode_name: mode's name. :return: GameMode: class representation of found game mode. """ if not self.go_to_content_status_board(): logger.error("Failed to open Content Status board.") return mode_from_board_1 = self.find_mode_on_board( mode_name=mode_name, board=self.ui['CONTENT_STATUS_BOARD_1'], element=self.ui['CONTENT_STATUS_ELEMENT_1'], rows=3, cols=4) if mode_from_board_1: return mode_from_board_1 else: self.emulator.drag(self.ui['CONTENT_STATUS_DRAG_FROM'].button, self.ui['CONTENT_STATUS_DRAG_TO'].button, duration=0.2) r_sleep(1) return self.find_mode_on_board( mode_name=mode_name, board=self.ui['CONTENT_STATUS_BOARD_2'], element=self.ui['CONTENT_STATUS_ELEMENT_1'], rows=3, cols=4)
def acquire_all_chests(self): """Acquires all chests from Inbox.""" self.game.go_to_inbox() if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.INBOX_CHEST_TAB): r_sleep(2) # Wait for animation self.emulator.click_button(ui.INBOX_CHEST_TAB) self._acquire_chests() self.game.go_to_main_menu()
def close_game(self): """Close game. :return: True or False: was game closed. """ logger.debug("Closing game.") self.emulator.close_current_app() r_sleep(2)
def search_new_opponent(self): """Search new opponents to minimize lose points.""" if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['TL_SEARCH_NEW_OPPONENT']): for _ in range(3): self.player.click_button( self.ui['TL_SEARCH_NEW_OPPONENT'].button) r_sleep(1)
def _drag_to_the_right(self): """Drag Dispatch sector menu to the right side.""" logger.debug("Dragging to the right side.") self.emulator.drag(self.ui['DISPATCH_DRAG_RIGHT_POSITION'].button, self.ui['DISPATCH_DRAG_LEFT_POSITION'].button) r_sleep(1) self.emulator.drag(self.ui['DISPATCH_DRAG_RIGHT_POSITION'].button, self.ui['DISPATCH_DRAG_LEFT_POSITION'].button) r_sleep(1)
def _drag_to_the_left(self): """Drags Dispatch sector menu to the left side.""" logger.debug("Dragging to the left side.") self.emulator.drag(ui.DISPATCH_DRAG_LEFT_POSITION, ui.DISPATCH_DRAG_RIGHT_POSITION) r_sleep(1) self.emulator.drag(ui.DISPATCH_DRAG_LEFT_POSITION, ui.DISPATCH_DRAG_RIGHT_POSITION) r_sleep(1)
def go_to_mission_selection(self): """Goes to Missions screen.""" self.go_to_main_menu() if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.ENTER_MISSIONS): self.emulator.click_button(ui.ENTER_MISSIONS) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.SELECT_MISSION): r_sleep(1) return True
def go_to_epic_quests(self): """Goes to Epic Quests screen.""" if self.go_to_mission_selection(): if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.EPIC_QUEST_MISSIONS): self.emulator.click_button(ui.EPIC_QUEST_MISSIONS) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.EQ_LABEL): r_sleep(1) return True
def go_to_dispatch_mission(self): """Goes to Dispatch Mission screen.""" if self.go_to_mission_selection(): if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.DISPATCH_MISSION): self.emulator.click_button(ui.DISPATCH_MISSION) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.DISPATCH_MISSION_LABEL): r_sleep(1) return True
def collect_antimatter(self): """Collect all available antimatter in the lab.""" self.game.go_to_lab() r_sleep(1) # Wait for button's animation if self.emulator.is_ui_element_on_screen(ui_element=self.ui['LAB_ANTIMATTER_GENERATOR_COLLECT_1']): logger.debug("Found COLLECT button with max lvl generator, collecting.") self.emulator.click_button(self.ui['LAB_ANTIMATTER_GENERATOR_COLLECT_1'].button) if self.emulator.is_ui_element_on_screen(ui_element=self.ui['LAB_ANTIMATTER_GENERATOR_COLLECT_2']): logger.debug("Found COLLECT button with not max lvl generator, collecting.") self.emulator.click_button(self.ui['LAB_ANTIMATTER_GENERATOR_COLLECT_2'].button) self.game.go_to_main_menu()
def acquire_all_gifts(self, acquire_energy=False): """Acquires all gifts from Inbox. :param bool acquire_energy: acquire energy or not. """ self.game.go_to_inbox() if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.INBOX_GIFT_TAB): r_sleep(2) # Wait for animations self.emulator.click_button(ui.INBOX_GIFT_TAB) self._acquire_gifts(acquire_energy=acquire_energy) self.game.go_to_main_menu()
def go_to_mission_selection(self): """DEPRECATED. Go to Missions screen. """ self.go_to_main_menu() if wait_until(self.player.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ENTER_MISSIONS']): self.player.click_button(self.ui['ENTER_MISSIONS'].button) r_sleep(1)
def go_to_mission_selection(self): """Go to Missions screen.""" self.go_to_main_menu() if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ENTER_MISSIONS']): self.emulator.click_button(self.ui['ENTER_MISSIONS'].button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['SELECT_MISSION']): r_sleep(1) return True
def go_to_dispatch_mission(self): """Go to Dispatch Mission screen.""" if self.go_to_mission_selection(): if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['DISPATCH_MISSION']): self.emulator.click_button(self.ui['DISPATCH_MISSION'].button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['DISPATCH_MISSION_LABEL']): r_sleep(1) return True
def click_button(self, button_rect, min_duration=0.1, max_duration=0.25): """Click inside button rectangle. :param button_rect: rectangle of button. :param min_duration: minimum duration between clicking. :param max_duration: maximum duration between clicking. """ duration = random.uniform(min_duration, max_duration) r_sleep(duration) x, y = self.get_position_inside_screen_rectangle(button_rect) autoit.control_click_by_handle(self.parent_hwnd, self.hwnd, x=x, y=y) r_sleep(duration * 2)
def go_to_challenge_selection(self): """DEPRECATED. Go to Challenges screen. """ self.go_to_main_menu() if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ENTER_MISSIONS']): self.emulator.click_button(self.ui['ENTER_MISSIONS'].button) r_sleep(1) self.emulator.click_button(self.ui['CHALLENGE_MISSIONS'].button) r_sleep(1)
def go_to_arena(self): """DEPRECATED. Go to Arena screen. """ self.go_to_main_menu() if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['ENTER_MISSIONS']): self.emulator.click_button(self.ui['ENTER_MISSIONS'].button) r_sleep(1) self.emulator.click_button(self.ui['ARENA_MISSIONS'].button) r_sleep(1)
def go_to_epic_quests(self): """Go to Epic Quests screen.""" if self.go_to_mission_selection(): if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['EPIC_QUEST_MISSIONS']): self.emulator.click_button( self.ui['EPIC_QUEST_MISSIONS'].button) if wait_until(self.emulator.is_ui_element_on_screen, timeout=3, ui_element=self.ui['EQ_LABEL']): r_sleep(1) return True
def open_support_shop(self): """Opens Support Shop from Main Menu tab.""" self.game.go_to_main_menu() self.emulator.click_button(ui.MAIN_MENU) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.MAIN_MENU): if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.MAIN_MENU_SUPPORT_SHOP): self.emulator.click_button(ui.MAIN_MENU_SUPPORT_SHOP) if wait_until(self.emulator.is_ui_element_on_screen, ui_element=ui.SUPPORT_SHOP_LABEL): r_sleep(1) # Wait for animation return True