def enhance_ship(self): """ Method that selects the first (leftmost of the first row) favorite ship and proceeds to enhance her. """ #selects ship Utils.touch_randomly(Region(209, 209, 80, 120)) Utils.script_sleep(1) while True: Utils.update_screen() if Utils.find("enhancement/menu_enhance"): Logger.log_debug("Filling with ships.") #taps the "fill" button Utils.touch_randomly(Region(1467, 917, 140, 38)) Utils.update_screen() if Utils.find("enhancement/alert_no_items", 0.85): Logger.log_warning("Not enough ships to enhance.") break if Utils.find("enhancement/menu_level", 0.8): self.handle_retirement() Logger.log_msg("Successfully finished enhancing.") break if Utils.find("enhancement/menu_details"): Logger.log_debug("Opening enhance menu.") if not Utils.find("enhancement/menu_retrofit", 0.9): Utils.touch_randomly(Region(31, 188, 91, 91)) else: Utils.touch_randomly(Region(31, 329, 91, 91)) continue Utils.touch_randomly(self.region['button_go_back']) Utils.script_sleep(1) return
def handle_retirement(self): """ Method that handles the disassembling of the ship materials used in the enhancement process. """ #tap the "enhance" button Utils.touch_randomly(Region(1705, 916, 167, 40)) Utils.update_screen() if not Utils.find("enhancement/alert_enhanced", 0.85): Logger.log_debug("Didn't find enhanced alert.") return else: Logger.log_debug("Successfully enhanced ship.") while True: Utils.update_screen() if Utils.find("menu/alert_info"): Utils.touch_randomly(Region(1320, 785, 232, 62)) Utils.script_sleep(1) continue if Utils.find("retirement/button_disassemble"): Utils.touch_randomly(Region(1099, 827, 225, 58)) Utils.script_sleep(1) continue if Utils.find("menu/item_found"): Utils.touch_randomly(Region(661, 840, 598, 203)) Utils.script_sleep(1) return
def handle_retirement(self): Utils.touch_randomly(Region(1510, 978, 216, 54)) items_found = 0 while True: Utils.update_screen() if Utils.find("retirement/alert_bonus"): Utils.touch_randomly(Region(1412, 938, 218, 61)) Utils.script_sleep(1) continue if Utils.find("menu/item_found"): Utils.touch_randomly(Region(661, 840, 598, 203)) Utils.script_sleep(1) items_found += 1 if items_found > 1: return continue if Utils.find("menu/alert_info"): Utils.touch_randomly(Region(1320, 785, 232, 62)) Utils.script_sleep(1) continue if Utils.find("retirement/button_disassemble"): Utils.touch_randomly(Region(1099, 827, 225, 58)) Utils.script_sleep(1) continue
def mission_logic_wrapper(self): while True: Utils.update_screen() if Utils.find("mission/alert_completed"): Logger.log_msg("Found mission completed alert.") Utils.touch_randomly(self.region["mission_menu"]) continue if Utils.find("menu/drop_ssr"): Logger.log_msg("Received SSR ship as reward.") Utils.touch_randomly(Region(1228, 103, 692, 735)) continue if Utils.find("menu/drop_elite"): Logger.log_msg("Received ELITE ship as reward.") Utils.touch_randomly(Region(1228, 103, 692, 735)) continue while Utils.find("menu/missions"): Utils.update_screen() if Utils.find("mission/button_collect"): Logger.log_msg("Collected all missions.") Utils.touch_randomly(self.region["collect"]) continue if Utils.find("mission/button_claim"): Logger.log_msg("Claimed mission.") Utils.touch_randomly(self.region["first_claim"]) continue if Utils.find("menu/item_found"): Utils.touch_randomly(Region(661, 840, 598, 203)) continue else: Logger.log_msg("No more missions to claim/collect.") Utils.touch_randomly(self.region["button_back"]) return True
def retreat_handler(self): Logger.log_msg("Retreating...") while True: Utils.update_screen() if Utils.find("combat/alert_morale_low"): Utils.touch_randomly(Region(613, 731, 241, 69)) self.exit = 2 continue if Utils.find("menu/button_sort"): Utils.touch_randomly(Region(1312, 263, 64, 56)) self.exit = 3 continue if Utils.find("combat/menu_formation"): Utils.touch_randomly(self.region["menu_nav_back"]) continue if Utils.find("combat/button_retreat"): Utils.touch_randomly(Region(1130, 985, 243, 60)) continue if Utils.find("commission/button_confirm"): Utils.touch_randomly(Region(1065, 732, 235, 68)) continue if Utils.find("menu/attack"): return
def combat_handler(self): Logger.log_msg("Starting combat.") Utils.touch_randomly(self.region['menu_combat_start']) Utils.script_sleep(4) while True: Utils.update_screen() if Utils.find("combat/combat_pause", 0.7): Logger.log_debug("In battle.") Utils.script_sleep(5) continue if Utils.find("combat/menu_touch2continue"): Utils.touch_randomly(Region(661, 840, 598, 203)) continue if Utils.find("menu/item_found"): Utils.touch_randomly(Region(661, 840, 598, 203)) Utils.script_sleep(1) continue if Utils.find("combat/button_confirm"): Logger.log_msg("Combat ended.") Utils.touch_randomly(Region(1520, 963, 216, 58)) Utils.script_sleep(1) return if Utils.find("combat/menu_combat_finished"): Utils.touch_randomly(Region(725, 965, 647, 76)) Utils.script_sleep(1) continue
def retire_ships(self): while True: Utils.update_screen() if Utils.find("retirement/selected_none") and self.sorted == False: Logger.log_debug("Opening sorting menu.") Utils.touch_randomly(Region(1655, 14, 130, 51)) continue if Utils.find("retirement/button_sort_all", 0.99): Logger.log_debug("Changing sorting options for retirement.") Utils.touch_randomly(Region(672, 724, 185, 41)) Utils.script_sleep(0.5) Utils.touch_randomly(Region(911, 724, 185, 41)) Utils.script_sleep(0.5) continue if Utils.find("retirement/button_sort_common") and Utils.find( "retirement/button_sort_rare"): Logger.log_msg("Sorting options for retirement are correct.") self.sorted = True Utils.touch_randomly(Region(1090, 969, 220, 60)) Utils.script_sleep(1) continue if Utils.find("retirement/empty"): Logger.log_msg("No ships left to retire.") Utils.touch_randomly(Region(54, 57, 67, 67)) return if Utils.find("retirement/selected_none"): self.select_ships() continue if Utils.find("retirement/bonus"): self.handle_retirement() continue
def retirement_logic_wrapper(self, forced=False): """Method that fires off the necessary child methods that encapsulates the entire action of filtering and retiring ships Args: forced: Forces retirement to start even if need_to_retire returns False. """ if self.need_to_retire or forced: self.last_retire = self.stats.combat_done Logger.log_msg("Opening build menu to retire ships.") while True: Utils.update_screen() if Utils.find("menu/button_sort"): # Tap menu retire button Utils.touch_randomly(Region(549, 735, 215, 64)) Utils.script_sleep(1) continue # In case function is called from menu if Utils.find("menu/button_battle"): Utils.touch_randomly(Region(1452, 1007, 198, 52)) Utils.script_sleep(1) continue if Utils.find("menu/build"): if Utils.find("event/build_limited"): Utils.touch_randomly(Region(30, 816, 94, 94)) else: Utils.touch_randomly(Region(20, 661, 115, 99)) Utils.script_sleep(1) continue if Utils.find("retirement/selected_none"): self.retire_ships() Utils.touch_randomly(Region(54, 57, 67, 67)) return
def retire_ships(self): """Clicks through the dialogs for retiring ships """ Utils.find_and_touch('retire_confirm', 0.8) Utils.wait_and_touch('retire_confirm', 0.8, 3) Utils.touch_randomly(Region(0, 0, 300, 300)) Utils.wait_and_touch('retire_confirm', 0.8, 3) Utils.wait_and_touch('retire_disassemble', 3) Utils.touch_randomly(Region(0, 0, 300, 300))
def deploy(self, start=True): Utils.touch_randomly(Region(950, 550, 0, 0)) Utils.wait_till_find("echelon_formation") Utils.touch_randomly(Region(1800, 1000, 0, 0)) Logger.log_msg("Echelon deployed") if start: Utils.touch_randomly(Region(1800, 1000, 0, 0)) Logger.log_msg("Comencing operation") Utils.script_sleep(2)
def set_filters(self): """Filters the ship list to only show rare and commmon ships """ Utils.touch_randomly(Region(1090, 15, 150, 40)) Utils.script_sleep(1) Utils.wait_for_exist('ship_filter_confirm', 3) Utils.touch_randomly(Region(300, 570, 100, 20)) Utils.find_and_touch('ship_filter_rarity_common') Utils.find_and_touch('ship_filter_rarity_rare') Utils.find_and_touch('ship_filter_confirm')
def select_ships(self): """Selects up to 10 ships for retirement """ Logger.log_msg('Selecting ships for retirement.') x, y = 90, 180 for i in range(0, 7): Utils.touch_randomly(Region(x + (i * 170), y, 30, 15)) y = 412 for i in range(0, 3): Utils.touch_randomly(Region(x + (i * 170), y, 30, 15))
def __init__(self, config, stats): """Initializes the Combat module. Args: config (Config): ALAuto Config instance. stats (Stats): ALAuto Stats instance. """ self.enabled = True self.config = config self.stats = stats self.exit = 0 self.l = [] self.blacklist = [] self.movement_event = {} self.chapter_map = self.config.combat['map'] self.region = { 'hide_strat_menu': Region(1617, 593, 4, 146), 'menu_button_battle': Region(1517, 442, 209, 206), 'map_summary_go': Region(1289, 743, 280, 79), 'fleet_menu_go': Region(1485, 872, 270, 74), 'combat_ambush_evade': Region(1493, 682, 208, 56), 'combat_com_confirm': Region(848, 740, 224, 56), 'combat_end_confirm': Region(1520, 963, 216, 58), 'menu_combat_start': Region(1578, 921, 270, 70), 'menu_nav_back': Region(54, 57, 67, 67) }
def clear_map(self): Logger.log_msg("Started map clear.") Utils.script_sleep(2.5) #hide strat menu Utils.touch_randomly(Region(1617, 593, 4, 146)) #swipe map to the left Utils.swipe(960, 540, 1300, 540, 100) target_info = self.get_closest_target(self.blacklist) while True: Utils.update_screen() if Utils.find("combat/alert_unable_battle"): Logger.log_warning("Failed to defeat enemy.") Utils.touch_randomly(Region(869, 741, 185, 48)) return False if self.exit is not 0: return True if Utils.find("enemy/fleet_boss", 0.9): Logger.log_msg("Boss fleet was found.") boss_region = Utils.find("enemy/fleet_boss", 0.9) #extrapolates boss_info(x,y,enemy_type) from the boss_region found boss_info = [boss_region.x + 50, boss_region.y + 25, "boss"] self.clear_boss(boss_info) continue if target_info == None: if Utils.find("combat/question_mark", 0.9): target_info = self.get_closest_target(self.blacklist, mystery_node=True) #if it is a mystery_node (question_mark), tap a bit lower if target_info[2] == "mystery_node": #coord_y += 140 target_info[1] += 140 else: target_info = self.get_closest_target(self.blacklist) continue if target_info: #tap at target's coordinates Utils.touch(target_info[0:2]) Utils.update_screen() if Utils.find("combat/alert_unable_reach", 0.8): Logger.log_warning("Unable to reach the target.") self.blacklist.append(target_info[0:2]) target_info = None continue else: movement_result = self.movement_handler(target_info) if movement_result == 1: self.battle_handler() target_info = None self.blacklist.clear() continue
def __init__(self, config): self.enabled = False self.config = config self.region = { "difficult_level": Region(842, 304, 102, 78), "start_explore": Region(1532, 768, 190, 83), } self.find_sec = False self.first_time = True self.is_boss = False self.swipe_right = True self.swipe_count = 0 self.retry_count = 0
def __init__(self, config, stats): """Initializes the Enhancement module. Args: config (Config): ALAuto Config instance stats (Stats): ALAuto stats instance """ self.config = config self.stats = stats self.last_enhance = 0 self.region = { 'button_favorite': Region(1014, 19, 170, 42), 'button_go_back': Region(54, 57, 67, 67) }
def __init__(self, config, stats): """Initializes the Combat module. Args: config (Config): ALAuto Config instance. stats (Stats): ALAuto Stats instance. """ self.enabled = True self.config = config self.stats = stats self.morale = {} self.next_combat_time = datetime.now() self.resume_previous_sortie = False self.kills_needed = 0 self.combat_auto_enabled = False self.hard_mode = self.config.combat['hard_mode'] self.sortie_map = self.config.combat['map'] self.event_map = self.sortie_map.split('-')[0] == 'E' self.need_to_refocus = True self.avoided_ambush = True self.region = { 'nav_back': Region(12, 8, 45, 30), 'home_menu_attack': Region(1000, 365, 180, 60), 'event_map': Region(1145, 140, 70, 40), 'map_go_1': Region(875, 465, 115, 35), 'map_go_2': Region(925, 485, 170, 45), 'battle_start': Region(1000, 610, 125, 50), 'toggle_autobattle': Region(150, 80, 65, 20), 'switch_fleet': Region(850, 650, 180, 40) }
def __init__(self, config, stats): """Initializes the Expedition module. Args: config (Config): kcauto Config instance """ self.enabled = True self.config = config self.stats = stats self.region = { 'mission_menu': Region(1206, 1001, 220, 64), 'collect': Region(1551, 0, 111, 58), 'first_claim': Region(1646, 174, 117, 102), 'button_back': Region(48, 43, 76, 76) }
def conduct_prebattle_check(self): """Method to check morale and check if auto-battle is enabled before a sortie. Enables autobattle if not already enabled. Returns: bool: True if it is ok to proceed with the battle """ ok = True fleet_morale = self.check_morale() if fleet_morale['sad']: self.set_next_combat_time({'hours': 2}) ok = False elif fleet_morale['neutral']: self.set_next_combat_time({'hours': 1}) ok = False else: if not self.combat_auto_enabled: Logger.log_msg('Checking if auto-battle is enabled.') if not Utils.exists('combat_auto_enabled'): Logger.log_msg('Enabling auto-battle') Utils.touch_randomly(self.region['toggle_autobattle']) Utils.script_sleep(0.5) Utils.touch_randomly(Region(600, 100, 150, 150)) Utils.script_sleep(2) self.combat_auto_enabled = True return ok
def enhance(): Utils.wait_till_find("factory") Utils.touch_randomly(regions["enhance"]) Utils.wait_till_find_touch("select_character") Utils.script_sleep(1) gun = None gun = Utils.find("enhance_1_l") if not gun: gun = Utils.find("enhance_1") if not gun: gun = Utils.find("enhance_2_l") if not gun: gun = Utils.find("enhance_2") if not gun: gun = Region(150, 400, 0, 0) Utils.touch_randomly(gun) Utils.wait_till_find_touch("select_character_2") Utils.wait_till_find_touch("smart_select") Utils.script_sleep(2) if not Utils.find("smart_select"): Utils.touch_randomly(regions["ok"]) Utils.script_sleep(1) Utils.touch_randomly(regions["ok"]) Utils.script_sleep(2) Utils.find_and_touch("ls_ok_restart") Utils.touch_randomly(regions["ok"]) Utils.script_sleep(1) Factory.enhance() else: Utils.touch_randomly(regions["return"]) Utils.touch_randomly(regions["return"]) Utils.wait_till_find("test")
def movement_handler(self, target_info): """ Method that handles the fleet movement until it reach its target (mystery node or enemy node). If the coordinates are wrong, they will be blacklisted and another set of coordinates to work on is obtained. If the target is a mystery node and what is found is ammo, then the method will fall in the blacklist case and search for another enemy: this is inefficient and should be improved, but it works. Args: target_info (list): coordinate_x, coordinate_y, type. Describes the selected target. Returns: (int): 1 if a fight is needed, otherwise 0. """ Logger.log_msg("Moving towards objective.") count = 0 location = [target_info[0], target_info[1]] Utils.script_sleep(1) while True: Utils.update_screen() event = self.check_movement_threads() if event["combat/button_evade"]: Logger.log_msg("Ambush was found, trying to evade.") Utils.touch_randomly(self.region["combat_ambush_evade"]) Utils.script_sleep(0.5) continue if event["combat/alert_failed_evade"]: Logger.log_warning("Failed to evade ambush.") Utils.touch_randomly(self.region["menu_combat_start"]) self.battle_handler() continue if event["menu/item_found"]: Logger.log_msg("Item found on node.") Utils.touch_randomly(Region(661, 840, 598, 203)) if Utils.find("combat/menu_emergency"): Utils.script_sleep(1) Utils.touch_randomly(self.region["hide_strat_menu"]) if target_info[2] == "mystery_node": Logger.log_msg("Target reached.") return 0 continue if event["menu/alert_info"]: Logger.log_debug("Found alert.") Utils.find_and_touch("menu/alert_close") continue if event["combat/menu_formation"] or event["combat/menu_loading"]: return 1 else: if count != 0 and count % 3 == 0: Utils.touch(location) if count > 21: Logger.log_msg( "Blacklisting location and searching for another enemy." ) self.blacklist.append(location) self.l.clear() location = self.get_closest_target(self.blacklist) count = 0 count += 1
def get_dorm_bar_color(self, percentage, corner_bar): if corner_bar: x_coord = 45 + int(780 * percentage) y_coord = 1025 else: x_coord = 630 + int(880 * percentage) y_coord = 400 return Utils.get_region_color_average(Region(x_coord, y_coord, 10, 10))
def mission_logic_wrapper(self): if (Utils.find_and_touch('mission_complete')): Logger.log_msg('Checking for completed missions.') self.stats.increment_missions_done() Utils.script_sleep(0.5) while Utils.find_and_touch('collect_mission'): Utils.touch_randomly() Utils.touch_randomly(Region(12, 8, 45, 30)) return True return False
def reach_map(self): """ Method to move to the world where the specified map is located. Only works with worlds added to assets (from 1 to 8). Also checks if hard mode is enabled. """ _map = 0 if Utils.find("menu/button_normal_mode"): Logger.log_debug("Disabling hard mode.") Utils.touch_randomly(Region(88, 990, 80, 40)) Utils.wait_update_screen(1) if not self.chapter_map[0].isdigit(): Utils.find_and_touch("menu/button_event") Utils.wait_update_screen(1) else: for x in range(1, 9): if Utils.find("maps/map_{}-1".format(x), 0.99): _map = x break if _map != 0: taps = int(self.chapter_map.split("-")[0]) - _map for x in range(0, abs(taps)): if taps >= 1: Utils.touch_randomly(Region(1831, 547, 26, 26)) Logger.log_debug("Swiping to the right") Utils.wait_update_screen() else: Utils.touch_randomly(Region(65, 547, 26, 26)) Logger.log_debug("Swiping to the left") Utils.wait_update_screen() if Utils.find('maps/map_{}'.format(self.chapter_map), 0.99): Logger.log_msg( "Successfully reached the world where map is located.") else: Logger.log_error( "Cannot find the specified map, please move to the world where it's located." ) while not Utils.find('maps/map_{}'.format(self.chapter_map), 0.99): Utils.wait_update_screen(1)
def __init__(self, config): self.enabled = False self.config = config self.region = { "home_team_up": Region(663, 907, 89, 108), "assist_challenge": Region(2170, 896, 163, 174), "combat_ready": Region(2064, 726, 221, 210), "combat_manual": Region(40, 949, 100, 92), "combat_finish": Region(1674, 612, 555, 419), "combat_cancel_invite": Region(864, 608, 258, 86), "auto_team_up": Region(1264, 898, 256, 84), }
def enhancement_logic_wrapper(self): """Method that fires off the necessary child methods that encapsulates the entire action of enhancing a ship """ if self.need_to_enhance: self.last_enhance = self.stats.combat_done Logger.log_msg("Opening dock to enhance ship.") while True: Utils.update_screen() if Utils.find("menu/button_battle"): Utils.touch_randomly(Region(297, 1015, 155, 40)) Utils.script_sleep(1) continue if Utils.find("enhancement/button_favorite", 0.99): self.enhance_ship() Utils.touch_randomly(self.region['button_favorite']) Utils.touch_randomly(Region(54, 57, 67, 67)) return if Utils.find("menu/dock"): Utils.touch_randomly(self.region['button_favorite']) continue
def battle_handler(self, boss=False): Logger.log_msg("Starting combat.") while not Utils.find("combat/menu_loading", 0.8): Utils.update_screen() if Utils.find("combat/alert_morale_low") or Utils.find( "menu/button_sort"): self.retreat_handler() return else: Utils.touch_randomly(self.region["menu_combat_start"]) Utils.script_sleep(1) Utils.script_sleep(4) while True: Utils.update_screen() if Utils.find("combat/alert_lock"): Logger.log_msg("Locking received ship.") Utils.touch_randomly(Region(1086, 739, 200, 55)) continue if Utils.find("combat/combat_pause", 0.7): Logger.log_debug("In battle.") Utils.script_sleep(5) continue if Utils.find("combat/menu_touch2continue"): Utils.touch_randomly(Region(661, 840, 598, 203)) continue if Utils.find("menu/item_found"): Utils.touch_randomly(Region(661, 840, 598, 203)) Utils.script_sleep(1) continue if Utils.find("menu/drop_ssr"): Logger.log_msg("Received SSR ship as drop.") Utils.touch_randomly(Region(1228, 103, 692, 735)) continue if Utils.find("menu/drop_elite"): Logger.log_msg("Received ELITE ship as drop.") Utils.touch_randomly(Region(1228, 103, 692, 735)) continue if Utils.find("combat/button_confirm"): Logger.log_msg("Combat ended.") Utils.touch_randomly(self.region["combat_end_confirm"]) Utils.script_sleep(1) if boss: return Utils.update_screen() if Utils.find("commission/button_confirm"): Logger.log_msg("Found commission info message.") Utils.touch_randomly(self.region["combat_com_confirm"]) continue if Utils.find("combat/button_retreat"): Utils.script_sleep(3) Utils.touch_randomly(Region(1617, 593, 4, 146)) return
def reach_map(self): """ Method to move to the world where the specified map is located. Only works with worlds added to assets (from 1 to 8) and some event maps. Also checks if hard mode is enabled. """ _map = 0 if not self.chapter_map[0].isdigit(): letter = self.chapter_map[2:3] event_maps = ['A', 'B', 'C', 'D'] Utils.find_and_touch("menu/button_event") Utils.wait_update_screen(1) if event_maps.index(letter) < 2 and Utils.find("menu/button_normal_mode") or \ event_maps.index(letter) > 1 and not Utils.find("menu/button_normal_mode"): Utils.touch_randomly(Region(88, 990, 80, 40)) Utils.wait_update_screen(1) else: for x in range(1, 11): if Utils.find("maps/map_{}-1".format(x), 0.99): _map = x break if _map != 0: taps = int(self.chapter_map.split("-")[0]) - _map for x in range(0, abs(taps)): if taps >= 1: Utils.touch_randomly(self.region['map_nav_right']) Logger.log_debug("Swiping to the right") Utils.wait_update_screen() else: Utils.touch_randomly(self.region['map_nav_left']) Logger.log_debug("Swiping to the left") Utils.wait_update_screen() if Utils.find('maps/map_{}'.format(self.chapter_map), 0.99): Logger.log_msg( "Successfully reached the world where map is located.") else: Logger.log_error( "Cannot find the specified map, please move to the world where it's located." ) while not Utils.find('maps/map_{}'.format(self.chapter_map), 0.99): Utils.wait_update_screen(1)
def __init__(self, config, stats): """Initializes the Research module. Args: config (Config): ALAuto Config instance """ self.enabled = True self.config = config self.stats = stats self.region = { 'lab_tab': Region(1004, 1013, 162, 39), 'exit_button': Region(51, 52, 71, 60), 'research_academy': Region(825, 415, 260, 265), 'project_click': Region(865, 155, 180, 100), 'right_arrow': Region(1855, 525, 30, 30), 'commence_tab': Region(650, 855, 215, 35), 'main_menu_button': Region(1821, 28, 44, 42), 'confirm_tab': Region(1095, 760, 190, 50) }
def __init__(self, config, stats): """Initializes the Enhancement module. Args: config (Config): ALAuto Config instance stats (Stats): ALAuto stats instance """ self.config = config self.stats = stats self.last_enhance = 0 self.levels = config.events['levels'].split(',') self.finished = False self.region = { 'menu_fleet_go': Region(1485, 872, 270, 74), 'menu_combat_start': Region(1578, 921, 270, 70), 'crosswave_ex': Region(1718, 246, 75, 75), 'crosswave_hard': Region(1650, 449, 75, 75), 'crosswave_normal': Region(1752, 612, 75, 75), 'crosswave_easy': Region(1683, 798, 75, 75), 'tap_to_continue': Region(661, 840, 598, 203), 'dismiss_combat_finished': Region(725, 965, 647, 76), 'combat_end_confirm': Region(1520, 963, 216, 58) }