def handle_in_map_with_enemy_searching(self): if not self.is_in_map(): return False timeout = Timer(self.MAP_ENEMY_SEARCHING_TIMEOUT_SECOND) appeared = False while 1: if self.is_in_map(): timeout.start() else: timeout.reset() if self.handle_in_stage(): return True if self.handle_story_skip(): self.ensure_no_story() timeout.limit = 10 timeout.reset() # End if self.enemy_searching_appear(): appeared = True else: if appeared: self.handle_enemy_flashing() self.device.sleep(1) logger.info('Enemy searching appeared.') break self.enemy_searching_color_initial() if timeout.reached(): logger.info('Enemy searching timeout.') break self.device.screenshot() return True
def _reward_receive(self): """ Returns: bool: If rewarded. """ logger.hr('Reward receive') reward = False exit_timer = Timer(1, count=3) click_timer = Timer(1) exit_timer.start() btn = [] if self.config.ENABLE_REWARD: btn.append(REWARD_3) if self.config.ENABLE_COMMISSION_REWARD: btn.append(REWARD_1) if self.config.ENABLE_OIL_REWARD: btn.append(OIL) if self.config.ENABLE_COIN_REWARD: btn.append(COIN) while 1: self.device.screenshot() for button in [ EXP_INFO_S_REWARD, GET_ITEMS_1, GET_ITEMS_2, GET_SHIP ]: if self.appear(button, interval=1): REWARD_SAVE_CLICK.name = button.name self.device.click(REWARD_SAVE_CLICK) click_timer.reset() exit_timer.reset() reward = True continue if click_timer.reached() and ( (self.config.ENABLE_OIL_REWARD and self.appear_then_click(OIL, interval=60)) or (self.config.ENABLE_COIN_REWARD and self.appear_then_click(COIN, interval=60)) or (self.config.ENABLE_COMMISSION_REWARD and self.appear_then_click(REWARD_1, interval=1)) or (self.config.ENABLE_REWARD and self.appear_then_click(REWARD_3, interval=1))): exit_timer.reset() click_timer.reset() reward = True continue if not self.appear( page_reward.check_button) or self.info_bar_count(): exit_timer.reset() continue # End if exit_timer.reached(): break return reward
def ensure_no_info_bar(self, timeout=0.6): timeout = Timer(timeout) timeout.start() while 1: self.device.screenshot() self.handle_info_bar() if timeout.reached(): break
def _handle_air_raid(self): logger.info('Map air raid') disappear = Timer(self.MAP_AIR_RAID_CONFIRM_SECOND) disappear.start() while 1: self.device.screenshot() if self._air_raid_appear(): disappear.reset() else: if disappear.reached(): break
def _reward_mission(self): """ Returns: bool: If rewarded. """ logger.hr('Mission reward') if not self.appear(MISSION_NOTICE): logger.info('No mission reward') return False self.ui_goto(page_mission, skip_first_screenshot=True) reward = False exit_timer = Timer(2) click_timer = Timer(1) timeout = Timer(10) exit_timer.start() timeout.start() while 1: self.device.screenshot() for button in [GET_ITEMS_1, GET_ITEMS_2]: if self.appear_then_click(button, offset=(30, 30), interval=1): exit_timer.reset() timeout.reset() reward = True continue for button in [MISSION_MULTI, MISSION_SINGLE]: if not click_timer.reached(): continue if self.appear_then_click(button, interval=1): exit_timer.reset() click_timer.reset() timeout.reset() continue if not self.appear(MISSION_CHECK): if self.appear_then_click(GET_SHIP, interval=1): click_timer.reset() exit_timer.reset() timeout.reset() continue # End if reward and exit_timer.reached(): break if timeout.reached(): logger.warning('Wait get items timeout.') break self.ui_goto(page_main, skip_first_screenshot=True) return reward
def ensure_no_story(self, skip_first_screenshot=True): logger.info('Ensure no story') story_timer = Timer(5, count=4) story_timer.start() while 1: if skip_first_screenshot: skip_first_screenshot = False else: self.device.screenshot() if self.story_skip(): story_timer.reset() if story_timer.reached(): break
def combat_execute(self, auto='combat_auto', call_submarine_at_boss=False, save_get_items=False): """ Args: auto (str): Combat auto mode. call_submarine_at_boss (bool): save_get_items (bool) """ logger.info('Combat execute') self.submarine_call_reset() self.combat_auto_reset() self.combat_manual_reset() confirm_timer = Timer(10) confirm_timer.start() self.device.screenshot_interval_set( self.config.COMBAT_SCREENSHOT_INTERVAL) while 1: self.device.screenshot() if not confirm_timer.reached() and self.appear_then_click( AUTOMATION_CONFIRM, offset=True): continue if self.handle_story_skip(): continue if self.handle_combat_auto(auto): continue if self.handle_combat_manual(auto): continue if auto != 'combat_auto' and self.auto_mode_checked and self.is_combat_executing( ): if self.handle_combat_weapon_release(): continue if call_submarine_at_boss: pass else: if self.handle_submarine_call(): continue # End if self.handle_battle_status( save_get_items=save_get_items) or self.handle_get_items( save_get_items=save_get_items): self.device.screenshot_interval_set(0) break
def combat_execute(self, auto='combat_auto', submarine='do_not_use', drop=None): """ Args: auto (str): ['combat_auto', 'combat_manual', 'stand_still_in_the_middle', 'hide_in_bottom_left'] submarine (str): ['do_not_use', 'hunt_only', 'every_combat'] drop (DropImage): """ logger.info('Combat execute') self.submarine_call_reset() self.combat_auto_reset() self.combat_manual_reset() self.device.click_record_clear() confirm_timer = Timer(10) confirm_timer.start() while 1: self.device.screenshot() if not confirm_timer.reached() and self.appear_then_click( AUTOMATION_CONFIRM, offset=True): continue if self.handle_story_skip(): continue if self.handle_combat_auto(auto): continue if self.handle_combat_manual(auto): continue if auto != 'combat_auto' and self.auto_mode_checked and self.is_combat_executing( ): if self.handle_combat_weapon_release(): continue if self.handle_submarine_call(submarine): continue if self.handle_popup_confirm('COMBAT_EXECUTE'): continue # End if self.handle_battle_status(drop=drop) \ or self.handle_get_items(drop=drop): self.device.screenshot_interval_set() break
def handle_in_map_with_enemy_searching(self): if not self.is_in_map(): return False timeout = Timer(self.MAP_ENEMY_SEARCHING_TIMEOUT_SECOND) appeared = False while 1: self.device.screenshot() if self.is_event_animation(): continue if self.is_in_map(): timeout.start() else: timeout.reset() if self.handle_in_stage(): return True if self.handle_story_skip(): self.ensure_no_story() timeout.limit = 10 timeout.reset() if self.handle_guild_popup_cancel(): self.config.GUILD_POPUP_TRIGGERED = True timeout.limit = 10 timeout.reset() continue # End if self.enemy_searching_appear(): appeared = True else: if appeared: self.handle_enemy_flashing() self.device.sleep(1) logger.info('Enemy searching appeared.') break self.enemy_searching_color_initial() if timeout.reached(): logger.info('Enemy searching timeout.') break self.device.screenshot() return True
def handle_siren_platform(self): """ Handle siren platform notice after entering map Returns: bool: If handled """ if not self.handle_story_skip(): return False logger.info('Handle siren platform') timeout = Timer(self.MAP_ENEMY_SEARCHING_TIMEOUT_SECOND).start() appeared = False while 1: self.device.screenshot() if self.is_in_map(): timeout.start() else: timeout.reset() if self.handle_story_skip(): timeout.reset() continue # End if self.enemy_searching_appear(): appeared = True else: if appeared: self.handle_enemy_flashing() self.device.sleep(1) logger.info('Enemy searching appeared.') break self.enemy_searching_color_initial() if timeout.reached(): logger.info('Enemy searching timeout.') break return True
def _goto(self, location, expected=''): """Goto a grid directly and handle ambush, air raid, mystery picked up, combat. Args: location (tuple, str, GridInfo): Destination. """ location = location_ensure(location) siren_count = self.map.select(is_siren=True).count result_mystery = '' while 1: sight = self.map.camera_sight self.in_sight(location, sight=(sight[0], 0, sight[2], sight[3])) self.focus_to_grid_center() grid = self.convert_map_to_grid(location) self.ambush_color_initial() self.enemy_searching_color_initial() grid.__str__ = location result = 'nothing' self.device.click(grid) arrived = False # Wait to confirm fleet arrived. It does't appear immediately if fleet in combat . add = self.config.MAP_SIREN_MOVE_WAIT * min(self.config.MAP_SIREN_COUNT, siren_count) \ if self.config.MAP_HAS_MOVABLE_ENEMY and not self.config.ENABLE_FAST_FORWARD else 0 arrive_timer = Timer(0.3 + add) arrive_unexpected_timer = Timer(1.5 + add) # Wait after ambushed. ambushed_retry = Timer(0.5) # If nothing happens, click again. walk_timeout = Timer(20) walk_timeout.start() while 1: self.device.screenshot() grid.image = self.device.image # Ambush if self.handle_ambush(): ambushed_retry.start() # Mystery mystery = self.handle_mystery(button=grid) if mystery: self.mystery_count += 1 result = 'mystery' result_mystery = mystery # Combat if self.config.ENABLE_MAP_FLEET_LOCK and not self.is_in_map(): if self.handle_retirement(): self.map_offensive() walk_timeout.reset() if self.handle_combat_low_emotion(): walk_timeout.reset() if self.combat_appear(): self.combat( expected_end=self._expected_combat_end(expected), fleet_index=self.fleet_current_index) self.hp_get() if self.hp_withdraw_triggered(): self.withdraw() arrived = True if not self.config.MAP_HAS_MOVABLE_ENEMY else False result = 'combat' self.battle_count += 1 self.fleet_ammo -= 1 if 'siren' in expected: self.siren_count += 1 elif self.map[location].may_enemy: self.map[location].is_cleared = True self.handle_boss_appear_refocus() grid = self.convert_map_to_grid(location) walk_timeout.reset() # Cat attack animation if self.handle_map_cat_attack(): walk_timeout.reset() continue if self.handle_walk_out_of_step(): raise MapWalkError('walk_out_of_step') # Arrive if self.is_in_map() and \ (grid.predict_fleet() or (walk_timeout.reached() and grid.predict_current_fleet())): if not arrive_timer.started(): logger.info(f'Arrive {location2node(location)}') arrive_timer.start() arrive_unexpected_timer.start() if not arrive_timer.reached(): continue if expected and result not in expected: if arrive_unexpected_timer.reached(): logger.warning('Arrive with unexpected result') else: continue logger.info( f'Arrive {location2node(location)} confirm. Result: {result}. Expected: {expected}' ) arrived = True break # End if ambushed_retry.started() and ambushed_retry.reached(): break if walk_timeout.reached(): logger.warning('Walk timeout. Retrying.') self.ensure_edge_insight() break # End if arrived: # Ammo grid needs to click again, otherwise the next click doesn't work. if self.map[location].may_ammo: self.device.click(grid) break self.map[self.fleet_current].is_fleet = False self.map[location].wipe_out() self.map[location].is_fleet = True self.__setattr__('fleet_%s_location' % self.fleet_current_index, location) if result_mystery == 'get_carrier': prev_enemy = self.map.select(is_enemy=True) self.full_scan(is_carrier_scan=True) diff = self.map.select(is_enemy=True).delete(prev_enemy) logger.info(f'Carrier spawn: {diff}') self.find_path_initial()
def _goto(self, location, expected=''): """Goto a grid directly and handle ambush, air raid, mystery picked up, combat. Args: location (tuple, str, GridInfo): Destination. """ location = location_ensure(location) result_mystery = '' self.movable_before = self.map.select(is_siren=True) if self.hp_withdraw_triggered(): self.withdraw() is_portal = self.map[location].is_portal while 1: sight = self.map.camera_sight self.in_sight(location, sight=(sight[0], 0, sight[2], sight[3])) self.focus_to_grid_center() grid = self.convert_map_to_grid(location) self.ambush_color_initial() self.enemy_searching_color_initial() grid.__str__ = location result = 'nothing' self.device.click(grid) arrived = False # Wait to confirm fleet arrived. It does't appear immediately if fleet in combat . extra = 4.5 if self.config.SUBMARINE_MODE == 'hunt_only' else 0 arrive_timer = Timer(0.5 + self.round_wait + extra, count=2) arrive_unexpected_timer = Timer(1.5 + self.round_wait + extra, count=6) # Wait after ambushed. ambushed_retry = Timer(0.5) # If nothing happens, click again. walk_timeout = Timer(20) walk_timeout.start() while 1: self.device.screenshot() grid.image = np.array(self.device.image) if is_portal: self.update() grid = self.view[self.view.center_loca] # Combat if self.config.ENABLE_MAP_FLEET_LOCK and not self.is_in_map(): if self.handle_retirement(): self.map_offensive() walk_timeout.reset() if self.handle_combat_low_emotion(): walk_timeout.reset() if self.combat_appear(): self.combat( expected_end=self._expected_combat_end(expected), fleet_index=self.fleet_current_index) self.hp_get() arrived = True if not self.config.MAP_HAS_MOVABLE_ENEMY else False result = 'combat' self.battle_count += 1 self.fleet_ammo -= 1 if 'siren' in expected or ( self.config.MAP_HAS_MOVABLE_ENEMY and not expected): self.siren_count += 1 elif self.map[location].may_enemy: self.map[location].is_cleared = True self.handle_boss_appear_refocus() grid = self.convert_map_to_grid(location) walk_timeout.reset() # Ambush if self.handle_ambush(): self.hp_get() ambushed_retry.start() walk_timeout.reset() # Mystery mystery = self.handle_mystery(button=grid) if mystery: self.mystery_count += 1 result = 'mystery' result_mystery = mystery # Cat attack animation if self.handle_map_cat_attack(): walk_timeout.reset() continue if self.handle_walk_out_of_step(): raise MapWalkError('walk_out_of_step') # Arrive if self.is_in_map() and \ (grid.predict_fleet() or (walk_timeout.reached() and grid.predict_current_fleet())): if not arrive_timer.started(): logger.info(f'Arrive {location2node(location)}') arrive_timer.start() arrive_unexpected_timer.start() if not arrive_timer.reached(): continue if expected and result not in expected: if arrive_unexpected_timer.reached(): logger.warning('Arrive with unexpected result') else: continue if is_portal: location = self.map[location].portal_link self.camera = location logger.info( f'Arrive {location2node(location)} confirm. Result: {result}. Expected: {expected}' ) arrived = True break # Story if expected == 'story': if self.handle_story_skip(): result = 'story' continue # End if ambushed_retry.started() and ambushed_retry.reached(): break if walk_timeout.reached(): logger.warning('Walk timeout. Retrying.') self.ensure_edge_insight() break # End if arrived: # Ammo grid needs to click again, otherwise the next click doesn't work. if self.map[location].may_ammo: self.device.click(grid) break self.map[self.fleet_current].is_fleet = False self.map[location].wipe_out() self.map[location].is_fleet = True self.__setattr__('fleet_%s_location' % self.fleet_current_index, location) if result_mystery == 'get_carrier': self.full_scan_carrier() if result == 'combat': self.round_battle() self.round_next() if self.round_is_new: self.full_scan_movable(enemy_cleared=result == 'combat') self.find_path_initial() raise MapEnemyMoved self.find_path_initial()
def handle_in_map_with_enemy_searching(self, drop=None): """ Args: drop (DropImage): Returns: bool: If handled. """ if not self.is_in_map(): return False timeout = Timer(self.MAP_ENEMY_SEARCHING_TIMEOUT_SECOND) appeared = False while 1: self.device.screenshot() if self.is_event_animation(): continue if self.is_in_map(): timeout.start() else: timeout.reset() # Stage might ends, # although here expects an enemy searching animation. if self.handle_in_stage(): return True if self.handle_auto_search_exit(drop=drop): continue # Popups if self.handle_vote_popup(): timeout.limit = 10 timeout.reset() continue if self.handle_story_skip(): self.ensure_no_story() timeout.limit = 10 timeout.reset() if self.handle_guild_popup_cancel(): timeout.limit = 10 timeout.reset() continue if self.handle_urgent_commission(drop=drop): timeout.limit = 10 timeout.reset() continue # End if self.enemy_searching_appear(): appeared = True else: if appeared: self.handle_enemy_flashing() self.device.sleep(0.3) logger.info('Enemy searching appeared.') break self.enemy_searching_color_initial() if timeout.reached(): logger.info('Enemy searching timeout.') break self.device.screenshot() return True
class InfoHandler(ModuleBase): """ Class to handle all kinds of message. """ """ Info bar """ def info_bar_count(self): if self.appear(INFO_BAR_3): return 3 elif self.appear(INFO_BAR_2): return 2 elif self.appear(INFO_BAR_1): return 1 else: return 0 def handle_info_bar(self): if self.info_bar_count(): self.wait_until_disappear(INFO_BAR_1) return True else: return False def ensure_no_info_bar(self, timeout=0.6): timeout = Timer(timeout) timeout.start() while 1: self.device.screenshot() self.handle_info_bar() if timeout.reached(): break """ Popup info """ _popup_offset = (3, 30) def handle_popup_confirm(self, name=''): if self.appear(POPUP_CANCEL, offset=self._popup_offset) \ and self.appear(POPUP_CONFIRM, offset=self._popup_offset, interval=2): POPUP_CONFIRM.name = POPUP_CONFIRM.name + '_' + name self.device.click(POPUP_CONFIRM) POPUP_CONFIRM.name = POPUP_CONFIRM.name[:-len(name) - 1] return True else: return False def handle_popup_cancel(self, name=''): if self.appear(POPUP_CONFIRM, offset=self._popup_offset) \ and self.appear(POPUP_CANCEL, offset=self._popup_offset, interval=2): POPUP_CANCEL.name = POPUP_CANCEL.name + '_' + name self.device.click(POPUP_CANCEL) POPUP_CANCEL.name = POPUP_CANCEL.name[:-len(name) - 1] return True else: return False def handle_urgent_commission(self, save_get_items=None): """ Args: save_get_items (bool): Returns: bool: """ if save_get_items is None: save_get_items = self.config.ENABLE_SAVE_GET_ITEMS appear = self.appear(GET_MISSION, offset=True, interval=2) if appear: logger.info('Get urgent commission') if save_get_items: self.handle_info_bar() self.device.save_screenshot('get_mission') self.device.click(GET_MISSION) return appear def handle_combat_low_emotion(self): if not self.config.IGNORE_LOW_EMOTION_WARN: return False return self.handle_popup_confirm('IGNORE_LOW_EMOTION') """ Story """ story_popup_timout = Timer(10, count=20) def story_skip(self): if self.story_popup_timout.started( ) and not self.story_popup_timout.reached(): if self.handle_popup_confirm('STORY_SKIP'): self.story_popup_timout = Timer(10) return True if self.appear_then_click(STORY_SKIP, offset=True, interval=2): self.story_popup_timout.start() return True if self.appear(STORY_LETTER_BLACK) and self.appear_then_click( STORY_LETTERS_ONLY, offset=True, interval=2): self.story_popup_timout.start() return True if self.appear_then_click(STORY_CHOOSE, offset=True, interval=2): self.story_popup_timout.start() return True if self.appear_then_click(STORY_CHOOSE_2, offset=True, interval=2): self.story_popup_timout.start() return True return False def handle_story_skip(self): if not self.config.ENABLE_MAP_CLEAR_MODE: return False if self.config.ENABLE_FAST_FORWARD: return False return self.story_skip() def ensure_no_story(self, skip_first_screenshot=True): logger.info('Ensure no story') story_timer = Timer(5, count=10).start() while 1: if skip_first_screenshot: skip_first_screenshot = False else: self.device.screenshot() if self.story_skip(): story_timer.reset() if story_timer.reached(): break def handle_map_after_combat_story(self): if not self.config.MAP_HAS_MAP_STORY: return False self.ensure_no_story()
def _submarine_goto(self, location): """ Move submarine to given location. Args: location (tuple, str, GridInfo): Destination. Returns: bool: If submarine moved. Pages: in: SUBMARINE_MOVE_CONFIRM out: SUBMARINE_MOVE_CONFIRM """ location = location_ensure(location) moved = True while 1: self.in_sight(location, sight=self._walk_sight) self.focus_to_grid_center() grid = self.convert_global_to_local(location) grid.__str__ = location self.device.click(grid) arrived = False # Usually no need to wait arrive_timer = Timer(0.1, count=0) # If nothing happens, click again. walk_timeout = Timer(2, count=6).start() while 1: self.device.screenshot() self.view.update(image=self.device.image) # Arrive arrive_checker = grid.predict_submarine_move() if grid.predict_submarine() or (walk_timeout.reached() and grid.predict_fleet()): arrive_checker = True moved = False if arrive_checker: if not arrive_timer.started(): logger.info(f'Arrive {location2node(location)}') arrive_timer.start() if not arrive_timer.reached(): continue logger.info( f'Submarine arrive {location2node(location)} confirm.') if not moved: logger.info( f'Submarine already at {location2node(location)}') arrived = True break # End if walk_timeout.reached(): logger.warning('Walk timeout. Retrying.') self.predict() self.ensure_edge_insight(skip_first_update=False) break # End if arrived: break return moved
def _goto(self, location, expected=''): """Goto a grid directly and handle ambush, air raid, mystery picked up, combat. Args: location (tuple, str, GridInfo): Destination. expected (str): Expected result on destination grid, such as 'combat', 'combat_siren', 'mystery'. Will give a waring if arrive with unexpected result. """ location = location_ensure(location) result_mystery = '' self.movable_before = self.map.select(is_siren=True) self.movable_before_normal = self.map.select(is_enemy=True) if self.hp_retreat_triggered(): self.withdraw() is_portal = self.map[location].is_portal # The upper grid is submarine, may mess up predict_fleet() may_submarine_icon = self.map.grid_covered(self.map[location], location=[(0, -1)]) may_submarine_icon = may_submarine_icon and self.fleet_submarine_location == may_submarine_icon[ 0].location while 1: self.fleet_ensure(self.fleet_current_index) self.in_sight(location, sight=self._walk_sight) self.focus_to_grid_center() grid = self.convert_global_to_local(location) self.ambush_color_initial() self.enemy_searching_color_initial() grid.__str__ = location result = 'nothing' self.device.click(grid) arrived = False # Wait to confirm fleet arrived. It does't appear immediately if fleet in combat. extra = 0 if self.config.Submarine_Mode == 'hunt_only': extra += 4.5 if self.config.MAP_HAS_LAND_BASED and grid.is_mechanism_trigger: extra += grid.mechanism_wait arrive_timer = Timer(0.5 + self.round_wait + extra, count=2) arrive_unexpected_timer = Timer(1.5 + self.round_wait + extra, count=6) # Wait after ambushed. ambushed_retry = Timer(0.5) # If nothing happens, click again. walk_timeout = Timer(20) walk_timeout.start() while 1: self.device.screenshot() self.view.update(image=self.device.image) if is_portal: self.update(allow_error=True) grid = self.view[self.view.center_loca] # Combat if self.config.Campaign_UseFleetLock and not self.is_in_map(): if self.handle_retirement(): self.map_offensive() walk_timeout.reset() if self.handle_combat_low_emotion(): walk_timeout.reset() if self.combat_appear(): self.combat(expected_end=self._expected_end(expected), fleet_index=self.fleet_show_index, submarine_mode=self._submarine_mode(expected)) self.hp_get() self.lv_get(after_battle=True) arrived = True if not self.config.MAP_HAS_MOVABLE_ENEMY else False result = 'combat' self.battle_count += 1 self.fleet_ammo -= 1 if 'siren' in expected or ( self.config.MAP_HAS_MOVABLE_ENEMY and not expected): self.siren_count += 1 elif self.map[location].may_enemy: self.map[location].is_cleared = True if self.catch_camera_repositioning(self.map[location]): self.handle_boss_appear_refocus() if self.config.MAP_FOCUS_ENEMY_AFTER_BATTLE: self.camera = location self.update() grid = self.convert_global_to_local(location) arrive_timer = Timer(0.5 + extra, count=2) arrive_unexpected_timer = Timer(1.5 + extra, count=6) walk_timeout.reset() if not (grid.predict_fleet() and grid.predict_current_fleet()): ambushed_retry.start() # Ambush if self.handle_ambush(): self.hp_get() self.lv_get(after_battle=True) walk_timeout.reset() self.view.update(image=self.device.image) if not (grid.predict_fleet() and grid.predict_current_fleet()): ambushed_retry.start() # Mystery mystery = self.handle_mystery(button=grid) if mystery: self.mystery_count += 1 result = 'mystery' result_mystery = mystery # Cat attack animation if self.handle_map_cat_attack(): walk_timeout.reset() continue # Guild popup # Usually handled in combat_status, but sometimes delayed until after battle on slow PCs. if self.handle_guild_popup_cancel(): walk_timeout.reset() continue if self.handle_walk_out_of_step(): raise MapWalkError('walk_out_of_step') # Arrive arrive_predict = '' arrive_checker = False if self.is_in_map(): if not may_submarine_icon and grid.predict_fleet(): arrive_predict = '(is_fleet)' arrive_checker = True elif may_submarine_icon and grid.predict_current_fleet(): arrive_predict = '(may_submarine_icon, is_current_fleet)' arrive_checker = True elif self.config.MAP_WALK_USE_CURRENT_FLEET \ and expected != 'combat_boss' \ and not ('combat' in expected and grid.may_boss) \ and (grid.predict_fleet() or grid.predict_current_fleet()): arrive_predict = '(MAP_WALK_USE_CURRENT_FLEET, is_current_fleet)' arrive_checker = True elif walk_timeout.reached() and grid.predict_current_fleet( ): arrive_predict = '(walk_timeout, is_current_fleet)' arrive_checker = True if arrive_checker: if not arrive_timer.started(): logger.info( f'Arrive {location2node(location)} {arrive_predict}' .strip()) arrive_timer.start() arrive_unexpected_timer.start() if result == 'nothing' and not arrive_timer.reached(): continue if expected and result not in expected: if arrive_unexpected_timer.reached(): logger.warning('Arrive with unexpected result') else: continue if is_portal: location = self.map[location].portal_link self.camera = location logger.info( f'Arrive {location2node(location)} confirm. Result: {result}. Expected: {expected}' ) arrived = True break else: if arrive_timer.started(): arrive_timer.reset() if arrive_unexpected_timer.started(): arrive_unexpected_timer.reset() # Story if expected == 'story': if self.handle_story_skip(): result = 'story' continue # End if ambushed_retry.started() and ambushed_retry.reached(): break if walk_timeout.reached(): logger.warning('Walk timeout. Retrying.') self.predict() self.ensure_edge_insight(skip_first_update=False) break # End if arrived: # Ammo grid needs to click again, otherwise the next click doesn't work. if self.map[location].may_ammo: self.device.click(grid) break self.map[self.fleet_current].is_fleet = False self.map[location].wipe_out() self.map[location].is_fleet = True self.__setattr__('fleet_%s_location' % self.fleet_current_index, location) if result_mystery == 'get_carrier': self.full_scan_carrier() if result == 'combat': self.round_battle(after_battle=True) self.predict() self.round_next() if self.round_is_new: if result != 'combat': self.predict() self.full_scan_movable(enemy_cleared=result == 'combat') self.find_path_initial() raise MapEnemyMoved if self.round_maze_changed: self.find_path_initial() raise MapEnemyMoved self.find_path_initial() if self.config.MAP_HAS_DECOY_ENEMY: if result == 'nothing' and expected == 'combat': raise MapEnemyMoved
def _reward_mission_collect(self, interval=1): """ Streamline handling of mission rewards for both 'all' and 'weekly' pages Args: interval (int): Configure the interval for assets involved Returns: bool, if encountered at least 1 GET_ITEMS_* """ # Reset any existing interval for the following assets [ self.interval_clear(asset) for asset in [ GET_ITEMS_1, GET_ITEMS_2, MISSION_MULTI, MISSION_SINGLE, GET_SHIP ] ] # Basic timers for certain scenarios exit_timer = Timer(2) click_timer = Timer(1) timeout = Timer(10) exit_timer.start() timeout.start() reward = False while 1: self.device.screenshot() for button in [GET_ITEMS_1, GET_ITEMS_2]: if self.appear_then_click(button, offset=(30, 30), interval=interval): exit_timer.reset() timeout.reset() reward = True continue for button in [MISSION_MULTI, MISSION_SINGLE]: if not click_timer.reached(): continue if self.appear(button, offset=(0, 200), interval=interval) \ and button.match_appear_on(self.device.image): self.device.click(button) exit_timer.reset() click_timer.reset() timeout.reset() continue if not self.appear(MISSION_CHECK): if self.appear_then_click(GET_SHIP, interval=interval): exit_timer.reset() click_timer.reset() timeout.reset() continue if self.handle_mission_popup_ack(): exit_timer.reset() click_timer.reset() timeout.reset() continue # Story if self.handle_vote_popup(): exit_timer.reset() click_timer.reset() timeout.reset() continue if self.story_skip(): exit_timer.reset() click_timer.reset() timeout.reset() continue if self.handle_popup_confirm('MISSION_REWARD'): exit_timer.reset() click_timer.reset() timeout.reset() continue # End if reward and exit_timer.reached(): break if timeout.reached(): logger.warning('Wait get items timeout.') break return reward