def resupply_groups(self, check_fatigue): """Method for resupplying the LBAS groups. If check_fatigue is set to True, this method will also resolve the LBAS fatigue, set their LBAS mode to 'rest' to speed up morale recovery, and delay the sortie if necessary. Args: check_fatigue (bool): whether or not LBAS fatigue should be handled Returns: bool: True if LBAS groups are ready to be sortied, False otherwise int: number of minutes to delay the sortie by """ # reset temporary fatigue tracker fatigue = {'high': False, 'medium': False} Util.log_msg("Begin resupplying LBAS groups.") if self.config.combat['map'][0] == 'E': resupply_menu_button = 'lbas_resupply_menu_button_event.png' resupply_menu_button_faded = ( 'lbas_resupply_menu_button_faded_event.png') resupply_menu_button_region = self.regions['lower_left'] else: resupply_menu_button = 'lbas_resupply_menu_button.png' resupply_menu_button_faded = ( 'lbas_resupply_menu_button_faded.png') resupply_menu_button_region = self.regions['top_submenu'] Util.wait_and_click_and_wait( resupply_menu_button_region, resupply_menu_button, resupply_menu_button_region, Pattern(resupply_menu_button_faded).exact()) Util.kc_sleep(3) for group in self.config.combat['lbas_groups']: Util.log_msg("Checking LBAS group #{} state.".format(group)) if group != 1: self.regions['right'].click('lbas_group_tab_{}.png'.format( str(group))) Util.kc_sleep() if Util.check_and_click(self.regions['right'], 'lbas_resupply.png'): Util.log_msg("Resupplying LBAS group #{}.".format(group)) self.regions['right'].waitVanish('lbas_resupply.png', 10) if check_fatigue: fatigue = self._check_and_manage_lbas_fatigue(fatigue, group) Util.kc_sleep(1) Util.kc_sleep(1) Util.wait_and_click_and_wait(resupply_menu_button_region, resupply_menu_button_faded, resupply_menu_button_region, Pattern(resupply_menu_button).exact()) Util.kc_sleep(1) if fatigue['high']: return False, 18 if fatigue['medium']: return False, 12 return True, 0
def goto_fleetcomp_presets(self): """Method to navigate to the fleet preset recall submenu of the fleet composition menu. """ Nav.goto(self.regions, 'fleetcomp') self.regions['upper'].wait('shiplist_button.png', 10) Util.wait_and_click_and_wait( self.regions['lower_left'], Pattern('fleetswitch_submenu.png').exact(), self.regions['lower_left'], Pattern('fleetswitch_submenu_active.png').exact())
def _switch_fleet_pre_sortie(self, fleet): """Method that switches the fleet in the pre-sortie fleet selection screen to the specified fleet. Args: fleet (int): id of fleet to switch to """ Util.wait_and_click_and_wait( self.regions['top_submenu'], Pattern('fleet_{}.png'.format(fleet)).exact(), self.regions['top_submenu'], Pattern('fleet_{}_active.png'.format(fleet)).exact())
def check_hold(): p = Pattern("C:\Users\ly\Pictures\\holding.png") click(p) time.sleep(1) p = Pattern("C:\Users\ly\Pictures\\holding2.png") click(p) time.sleep(1) if exists("C:\Users\ly\Pictures\\holding3.png"): return 1 else: return 0
def switch(region, fleet): """Method that switches to the specified fleet by pressing the fleet icon in the specified region. Args: region (Region): sikuli Region in which to search for the fleet icons fleet (int): id of fleet to switch to """ Util.wait_and_click_and_wait( region, Pattern('fleet_{}.png'.format(fleet)).exact(), region, Pattern('fleet_{}_active.png'.format(fleet)).exact()) Util.kc_sleep()
def _check_ship_availability(self, criteria): """Checks the chosen ship's returns its availability for switching. Args: criteria (list): dictionary containing shipswitch criteria Returns: bool or str: True if the ship is available; False if it does not meet the criteria; 'conflict' if it meets the criteria but a ship of the same type is already in the fleet """ # wait until the panel is ready before speeding through checks self.regions['lower_right'].wait( Pattern('shiplist_shipswitch_button.png').similar(0.75), 5) # temp region for speed matching temp_region = Region(self.regions['upper_right']) temp_region.setAutoWaitTimeout(0) # check damage state; repair and heavy checked by default valid_damages = list(self.fleets[1].get_damages_at_threshold( self.config.combat['repair_limit'])) valid_damages.extend(['repair', 'heavy']) for damage in set(valid_damages): if temp_region.exists( Pattern('ship_state_dmg_{}.png'.format(damage)).similar( Globals.DAMAGE_SIMILARITY)): Util.log_warning("Candidate ship is damaged.") return False # check fatigue states if it is a criteria if 'fatigue' in criteria: for fatigue in ('medium', 'high'): if temp_region.exists( Pattern('ship_state_fatigue_{}.png'.format( fatigue)).similar(Globals.FATIGUE_SIMILARITY)): Util.log_warning("Candidate ship is fatigued.") return False # check sparkle if it is a criteria if 'sparkle' in criteria: if temp_region.exists( Pattern('sparkle_indicator_shiplist.png').similar(0.9), 2): Util.log_warning("Candidate ship is sparkled.") return False # passed criteria; check if there is a conflicting ship in fleet if Util.check_and_click(self.regions['lower_right'], 'shiplist_shipswitch_button.png'): Util.log_msg("Candidate ship successfully switched in.") return True else: Util.log_warning("Candidate ship has conflict with fleet.") return 'conflict'
def _switch_shiplist_tab(self, targets): """Method that checks and changes the shiplist tab if necessary. Args: targets (list): target tabs to switch to; should be values in VALID_TABS Raises: ValueError: invalid tab specified Returns: bool: always returns True after switching to the specified tabs """ for target in targets: if target not in self.VALID_TABS: raise ValueError( "Invalid shiplist tab ({}) specified.".format(target)) targets.sort() if self.current_shiplist_tabs == targets: # already at target tabs return True if 'all' in targets: # if target is all tabs, click the quick tab arrow once if not # already at all tabs; if arrow is clicked, reset page to 1 Util.log_msg("Enabling all shiplist tabs.") if not self.regions['top_submenu'].exists( Pattern('shiplist_quick_tab_all.png').exact()): Util.check_and_click(self.regions['top_submenu'], 'shiplist_quick_tab_none.png') self.current_shiplist_page = 1 self.current_shiplist_tabs = targets return True # if target is specific tabs, click the quick tab arrow until the # shiplist is empty, then click the tabs; afterwards, reset page to 1 Util.log_msg("Enabling shiplist tabs {}.".format(', '.join(targets))) while not self.regions['right'].exists('shiplist_empty_indicator.png'): Util.check_and_click(self.regions['top_submenu'], 'shiplist_quick_tab_none.png') for target in targets: Util.check_and_click( self.regions['top_submenu'], Pattern('shiplist_tab_{}.png'.format(target)).similar( Globals.SHIP_LIST_TAB_SIMILARITY)) self.current_shiplist_page = 1 self.current_shiplist_tabs = targets return True
def navigate_to_expedition(self, fleet): """Clicks the world icon and navigates the prev and next list scrolling to navigate and choose the desired expedition for the specified fleet. Args: fleet (ExpeditionFleet): expedition fleet instance """ expedition_line = Pattern('expedition_{}.png'.format( fleet.expedition)).similar(0.7) while not self.kc_region.exists(expedition_line): # if the expedition does not already exist on-screen, try selecting # the world first Util.kc_sleep() Util.check_and_click( self.regions['lower'], 'e_world_{}.png'.format(fleet.expedition_area)) Util.kc_sleep(1) if not self.kc_region.exists(expedition_line): # if the expedition still does not show on-screen, check the # specified expedition and scroll up or down the list if type(fleet.expedition) == int: while self.regions['upper_left'].exists('scroll_prev.png'): Util.check_and_click(self.regions['upper_left'], 'scroll_prev.png') Util.kc_sleep() elif type(fleet.expedition) == str: while self.regions['lower_left'].exists('scroll_next.png'): Util.check_and_click(self.regions['lower_left'], 'scroll_next.png', Globals.EXPAND['scroll_next']) Util.kc_sleep() # select the expedition Util.check_and_click(self.kc_region, expedition_line) Util.kc_sleep(0.5)
def find(window, target, similarity): """Method for finding all matches of an image in the specified window with at least the specified similarity once. Args: window (str): name of window to search in target (str): name of image to find in the window similarity (float, optional): minimum similarity threshold for the match """ target_window = App(window) target_region = target_window.focus().focusedWindow() print("\n") print( "+ Sikuli match object for '{}' in window '{}'".format( target, window)) print("+ with minimum similarity of {}:".format(similarity)) debug_matches = Util.findAll_wrapper( target_region, Pattern(target).similar(similarity)) for img_match in debug_matches: img_match.highlight() print(img_match) target_region.mouseMove(img_match) if isinstance(debug_matches, list) and len(debug_matches) == 0: print("No matches!") print("\n")
def navigate_to(self, regions, target): """Method that interacts with the game to transition from the current node to the destination via the pre-defined connections. Args: regions (dict): dict of pre-defined kcauto regions target (str): name of destination node Returns: NavNode: NavNode instance of the destination """ if target in self.connections: c = self.connections[target] Util.rejigger_mouse(regions, 'top') if c['click_target'] == 'QUEST_MENU': Util.click_preset_region(regions, 'quest_menu') else: Util.wait_and_click(regions[c['click_target_region']], c['click_target']) Util.rejigger_mouse(regions, 'top') regions[c['wait_target_region']].wait( Pattern(c['wait_target']).exact(), 60) return c['target'] else: Util.log_error( "Not possible to navigate to '{}' from {} screen.".format( target, self.name))
def _switch_lbas_mode(self, lbas_group_mode_name_target): """Switches the lbas group mode to the specified final mode. Args: lbas_group_mode_name_target (str): the mode to switch the LBAS group to """ Util.rejigger_mouse(self.regions, 'top') # Must be relevant to http://kancolle.wikia.com/wiki/Land_Base_Aerial_Support#Options if sum([ lbas_group_mode_name_target == i for i in self._lbas_group_modes_tuple ]) != 1: raise ValueError("No such LBAS mode: \"{}\".".format( lbas_group_mode_name_target)) while not self.module_regions['lbas_mode_switcher'].exists( 'lbas_group_mode_{}.png'.format(lbas_group_mode_name_target), 1 + Globals.SLEEP_MODIFIER): for lbas_group_mode_name_current in self._lbas_group_modes_tuple: lbas_group_mode_pattern = Pattern( 'lbas_group_mode_{}.png'.format( lbas_group_mode_name_current)).similar( Globals.DEFAULT_SIMILARITY) Util.rejigger_mouse(self.regions, 'top') if self.module_regions['lbas_mode_switcher'].exists( lbas_group_mode_pattern, 1 + Globals.SLEEP_MODIFIER): print("Current LBAS group mode is \"{}\".".format( lbas_group_mode_name_current)) if lbas_group_mode_name_current == lbas_group_mode_name_target: break Util.check_and_click( self.module_regions['lbas_mode_switcher'], lbas_group_mode_pattern) Util.log_msg("LBAS group switched to {} mode.".format( lbas_group_mode_name_target))
def _choose_and_check_availability_of_ship(self, position, criteria): """Select a ship in the ship list based on the specified position, and see if it available for switching in. Args: position (int): 0-based position in ship list criteria (dict): dictionary of criteria Returns: bool or str: result of _check_ship_availability() call """ fleet_indicator_area = Region(self.kc_region.x + 550, self.kc_region.y + 225 + (43 * position), 35, 35) if fleet_indicator_area.exists( Pattern('fleet_indicator_shiplist.png').similar( Globals.SHIP_LIST_FLEET_ICON_SIMILARITY)): # if the ship is already in a fleet, skip it return False self._choose_ship_by_position(position) availability = self._check_ship_availability(criteria) if availability is True: return True # not an actual navigation, but a click to get rid of a side panel Util.check_and_click(self.regions['lower_right'], 'page_first.png') return availability
def continuously_find(window, target, similarity=0.8): """Method for finding all mathes of an image in the specified window with at least the specified similarity continuously. The user must manually exit out the script to halt the matching. Args: window (str): name of window to search in target (str): name of image to find in the window similarity (float, optional): minimum similarity threshold for the match """ target_window = App(window) target_region = target_window.focus().focusedWindow() while True: print("+ {}:".format(strftime("%H:%M:%S"))) print( "+ Sikuli match object for '{}' in window '{}'".format( target, window)) print("+ with minimum similarity of {}:".format(similarity)) debug_matches = Util.findAll_wrapper( target_region, Pattern(target).similar(similarity)) for img_match in debug_matches: print(img_match) target_region.mouseMove(img_match) if isinstance(debug_matches, list) and len(debug_matches) == 0: print("No matches!") print("")
def run_pvp_logic(self): """Primary PvP logic Returns: boolean: True if PvP was run, False otherwise """ if not Util.check_and_click( self.kc_region, Pattern('pvp_row.png').similar(Globals.TEXT_SIMILARITY)): Util.log_warning("No PvP opponents available.") self._reset_next_pvp_time() return False self.stats.increment_pvp_attempted() Util.rejigger_mouse(self.regions, 'top') self.regions['lower_left'].wait('pvp_start_1.png', 30) # wait for ship portraits to load to accurately ascertain sub counts Util.kc_sleep(2) opponent_counts = self._count_ships() formation, night_battle = self._pvp_planner(opponent_counts) Util.log_msg("PvPing against {:d} ships ({:d} subs).".format( opponent_counts['ship'], opponent_counts['ss'] + opponent_counts['ssv'])) Util.log_msg("Selecting {} and {!s} on night battle.".format( formation.replace('_', ' '), night_battle)) # start pvp Util.wait_and_click(self.regions['lower_left'], 'pvp_start_1.png', 30) Util.wait_and_click(self.regions['lower'], 'pvp_start_2.png', 30) Util.log_msg("Beginning PvP sortie.") Util.rejigger_mouse(self.regions, 'top') Util.wait_and_click(self.regions[formation], formation) Util.rejigger_mouse(self.regions, 'top') self._start_crash_observer(start_delay=10) while not self.regions['lower_right_corner'].exists('next.png', 1): if self.kc_region.exists('combat_nb_fight.png', 1): if night_battle: Util.check_and_click(self.kc_region, 'combat_nb_fight.png') else: Util.check_and_click(self.kc_region, 'combat_nb_retreat.png') Util.rejigger_mouse(self.regions, 'top') self._check_and_recovery_crash() while not self.regions['home_menu'].exists('home_menu_sortie.png', 1): if Util.check_and_click(self.regions['lower_right_corner'], 'next.png', Globals.EXPAND['shipgirl_off_next']): Util.rejigger_mouse(self.regions, 'top') self._check_and_recovery_crash() self._stop_crash_observer() self.stats.increment_pvp_done() Util.log_msg("Finished PvP sortie.") self.fleet.needs_resupply = True return True
def _start_fleet_observer(self): """Method that starts the observeRegion/observeInBackground methods that tracks the fleet position icon in real-time in the live engine mode. """ self.observeRegion.onAppear( Pattern(self.fleet_icon).similar(Globals.FLEET_ICON_SIMILARITY), self._update_fleet_position) self.observeRegion.observeInBackground(FOREVER)
def _check_fatigue_func(self, mode): """Child multithreaded method for fatigue states. Args: mode (str): which fatigue state to check for """ self.fatigue[mode] = (True if ( self.module_regions['check_lbas_fatigue'].exists( Pattern('ship_state_fatigue_{}.png'.format(mode)).similar( Globals.FATIGUE_SIMILARITY))) else False)
def _check_fatigue_func(self, mode, region): """Child multithreaded method for checking fatigue states. Args: type (str): which fatigue state to check for region (Region): Region in which to search for the fatigue state """ self.fatigue[mode] = (True if (region.exists( Pattern('ship_state_fatigue_{}.png'.format(mode)).similar( Globals.FATIGUE_SIMILARITY))) else False)
def _filter_quests(self, filter): """Method to filter the quests based on the specified filter (active, daily, weekly, monthly, or other/quarterly) Args: filter (str): the filter to filter on """ Util.wait_and_click_and_wait( self.regions['left'], 'filter_tab_{}.png'.format(filter), self.regions['left'], Pattern('filter_tab_{}_active.png'.format(filter)).exact())
def _pick_fleet_ship(self): """Method to click a fleet ship based on the fleet icons displayed next to the ship in the ship list. Returns: boolean: True if a fleet ship was chosen and clicked, False otherwise """ Util.log_msg("Picking damaged ship from combat fleet(s) to repair.") # generate markers for fleets to repair fleet_markers = [] if self.config.combat['fleet_mode'] == 'striking': fleet_markers = ['repairlist_fleet_3.png'] else: fleet_markers = [ 'repairlist_fleet_1_flag.png', 'repairlist_fleet_1.png' ] if self.config.combat['combined_fleet']: fleet_markers.append('repairlist_fleet_2.png') # get damages to repair valid_damages = CombatFleet.get_damages_at_threshold( self.config.combat['repair_limit']) for fleet_marker in fleet_markers: fleet_id = int(fleet_marker[17]) # infer from filename fleet_instance = self.fleets[fleet_id] if fleet_instance.get_damage_counts_at_threshold( self.config.combat['repair_limit']) == 0: # if this fleet has no longer has ships that need repair, # don't search for its marker continue ship_matches = Util.findAll_wrapper( self.regions['repair_shiplist_fleet_markers'], Pattern(fleet_marker).similar(0.9)) for ship_match in ship_matches: target_region = ship_match.offset(Location(342, 0)).nearby(5) for damage in valid_damages: if fleet_instance.damage_counts[damage] == 0: # if no ships in this fleet are at this damage state, # don't search for it continue damage_icon = 'repairlist_dmg_{}.png'.format(damage) if Util.check_and_click(target_region, damage_icon, Globals.EXPAND['repair_list']): fleet_instance.damage_counts[damage] -= 1 fleet_instance.damage_counts['repair'] += 1 return True return False
def check_damage_flagship(self, regions): """Method that checks whether or not the flagship of the fleet is damaged in the post-combat results screen. Important for ascertaining whether or not the flagship of the escort fleet is the ship with heavy damage as it is not sinkable. Args: regions (dict): dict of pre-defined kcauto-kai regions """ if (regions['check_damage_flagship'].exists( Pattern('ship_state_dmg_heavy.png').similar( Globals.FATIGUE_SIMILARITY))): self.flagship_damaged = True
def _check_need_to_switch_ship(self, slot, criteria): """Method that checks whether or not the ship in the specified slot needs to be switched out based on the criteria. Args: slot (int): slot ID (0-base) criteria (list): dictionary of criteria for the slot Returns: bool: True if the ship meets the criteria to be swapped out; False otherwise """ Util.log_msg("Checking ship in slot {}.".format(slot + 1)) panel_regions = self.module_regions['panels'] if 'damage' in criteria: valid_damages = list(self.fleets[1].get_damages_at_threshold( self.config.combat['repair_limit'])) valid_damages.append('repair') for damage in valid_damages: if panel_regions[slot].exists( Pattern( 'ship_state_dmg_{}.png'.format(damage)).similar( Globals.DAMAGE_SIMILARITY)): Util.log_msg("Ship is damaged: attempting switch.") return True if 'fatigue' in criteria: for fatigue in ('medium', 'high'): if panel_regions[slot].exists( Pattern('ship_state_fatigue_{}.png'.format( fatigue)).similar(Globals.FATIGUE_SIMILARITY)): Util.log_msg("Ship is fatigued: attempting switch.") return True if 'sparkle' in criteria: if (panel_regions[slot].exists('sparkle_indicator.png', 2) and self.sparkling_cache[slot] <= self.stats.combat_done): Util.log_msg("Ship is sparkled: attempting switch.") return True return False
def _check_damages_func(self, type, region, reset): """Child multithreaded method for checking damage states. Args: type (str): which damage state to check for region (Region): Region in which to search for the damage state """ if reset: self.damage_counts[type] = 0 dmg_img = 'ship_state_dmg_{}.png'.format(type) count = Util.findAll_wrapper( region, Pattern(dmg_img).similar(Globals.DAMAGE_SIMILARITY)) for i in count: self.damage_counts[type] += 1
def _match_shiplist_ships_func(self, asset, ship_config): """Child multithreaded method for finding matching classes and ships. Args: asset (str): asset to match on ship_config (dict): dictionary of ship criteria """ matched_ships = Util.findAll_wrapper( self.module_regions['shiplist_class_col'], Pattern('shiplist_list_{}.png'.format(asset)).similar( Globals.SHIP_LIST_SIMILARITY)) ship_positions = self._filter_ships(matched_ships, ship_config) if ship_positions: self.temp_asset_position_dict[asset] = ship_positions self.temp_ship_config_dict[asset] = ship_config
def navigate_to_expedition(self, fleet): """Clicks the world icon and navigates the prev and next list scrolling to navigate and choose the desired expedition for the specified fleet. Args: fleet (ExpeditionFleet): expedition fleet instance """ Util.kc_sleep() Util.check_and_click(self.regions['lower'], 'e_world_{}.png'.format(fleet.expedition_area)) Util.kc_sleep(2) if type(fleet.expedition) == int: self._scroll_expedition_list_up() elif type(fleet.expedition) == str: self._scroll_expedition_list_down() rank_symbol = 'expedition_rank_{}.png'.format( fleet.expedition_rank.lower()) matched_ranks = Util.findAll_wrapper( self.module_regions['expedition_ranks'], Pattern(rank_symbol).exact()) expedition_display_name = str(fleet.expedition).zfill(2) for matched in matched_ranks: expedition_name_area = matched.left(38) expedition_name = Util.read_ocr_text(expedition_name_area) expedition_name = expedition_name.replace('O', '0') # disambiguate 'S' and '5' in proper locations if expedition_name[0] == '5': expedition_name = 'S' + expedition_name[1] if expedition_name[1] == 'S': expedition_name = expedition_name[0] + '5' if expedition_name == expedition_display_name: click_region = expedition_name_area.right(530) x = -self.kc_region.x + Util.random_coord( click_region.x, click_region.x + click_region.w) y = -self.kc_region.y + Util.random_coord( click_region.y, click_region.y + click_region.h) Util.click_coords(self.kc_region, x, y) Util.kc_sleep(0.5) return True # if the script reaches this point, an expedition was not selected Util.log_error( "Could not find desired expedition ({}). Please make sure it is " "unlocked.".format(fleet.expedition)) sys.exit(1)
def sell(code): try: #p = Pattern(pathprefix+'sellselection.png') p = Pattern(pathprefix + 'jiaoyiweituo.png') doubleClick(p) time.sleep(1) p = Pattern(pathprefix + 'maichu.png') doubleClick(p) time.sleep(2) p = Pattern(pathprefix + 'daima.png') click(p) click(p) click(p) paste(code) p = Pattern(pathprefix + 'putongweituo.png') click(p) p = Pattern(pathprefix + 'shijiacangwei.png') click(p) time.sleep(3) p = Pattern(pathprefix + 'all.png') click(p) p = Pattern(pathprefix + 'xiadan.png') click(p) time.sleep(3) if exists(pathprefix + 'daimanotbeempty.png'): p = Pattern(pathprefix + 'confirm.png') click(p) raise p = Pattern(pathprefix + 'confirm.png') click(p) return True except: print sys.exc_info()[0], sys.exc_info()[1] return False
def _match_shiplist_ships_func(self, mode, name, ship_config): """Child multithreaded method for finding matching classes and ships. Args: mode (str): specifies whether or not the search is for 'ship's or 'class'es name (str): name of class or ship ship_config (dict): dictionary of ship criteria """ img = ('shiplist_ship_{}.png'.format(name) if mode == 'ship' else 'shiplist_class_{}.png'.format(name)) matched_ships = Util.findAll_wrapper( self.module_regions['shiplist_class_col'], Pattern(img).similar(Globals.SHIP_LIST_SIMILARITY)) ship_positions = self._filter_ships(matched_ships, ship_config) if ship_positions: self.temp_ship_position_dict[name] = ship_positions self.temp_ship_config_dict[name] = ship_config
def ship_switch_logic(self): """Primary logic loop which goes through the 6 ship slots and switches ships as necessary. Only avilable for Fleet 1. """ self._set_shiplist_counts() # loop through slots and switch ships as necessary for slot in range(0, 6): if slot not in self.config.ship_switcher: continue slot_config = self.config.ship_switcher[slot] if self._check_need_to_switch_ship(slot, slot_config['criteria']): Util.wait_and_click_and_wait( self.module_regions['panels'][slot], 'shiplist_button.png', self.regions['top_submenu'], Pattern('shiplist_tab_aux.png').similar( Globals.SHIP_LIST_TAB_SIMILARITY)) Util.rejigger_mouse(self.regions, 'top') if self._resolve_replacement_ship(slot_config): self.stats.increment_ships_switched() if 'sparkle' in slot_config['criteria']: # if this is a sparkle slot, update the sparkle cache self._set_sparkle_cache(slot) else: Util.check_and_click(self.regions['top_submenu'], 'fleet_1_active.png') self.module_regions['panels'][0].wait('shiplist_button.png', 2) # check new fleet status # TODO: only checks on damage and repair states only, not fatigue! Util.kc_sleep(2) fleet = self.fleets[1] damage_counts = fleet.check_damages(self.kc_region) if (fleet.get_damage_counts_at_threshold( self.config.combat['repair_limit']) == 0 and damage_counts['repair'] == 0): # all ships in fleet pass checks: continue sortie fleet.needs_resupply = True # force resupply attempt Util.log_msg( "Fleet is ready to sortie. Updating next sortie time.") self.combat.set_next_combat_time() else: fleet.print_damage_counts(repair=True) Util.log_msg("Fleet is still not ready to sortie.")
def generate_pattern(cls, region, target, expand=[], prematched=False): """Method to generate a pattern with a custom targetOffset (click point) based on the randint_gauss() method. Args: region (Region): Region to conduct the search in target (str, Pattern): the filename of the asset or Pattern to search for expand (list, optional): area expansion for the targetOffset prematched (bool, optional): specifies whether or not the target was matched in the region immediately prior to the generate_pattern() call. This allows for the use of getLastMatch() to generate the match, instead of re-searching. Returns: Pattern: new Pattern object with the custom targetOffset """ if len(expand) == 0: if not prematched: region.find(target) matched_region = region.getLastMatch() if matched_region: x_width = matched_region.w / 2 y_height = matched_region.h / 2 expand = [-x_width, x_width, -y_height, y_height] if isinstance(target, str): created_pattern = Pattern(target).targetOffset( int(round(cls.randint_gauss(expand[0], expand[1]))), int(round(cls.randint_gauss(expand[2], expand[3])))) elif isinstance(target, Pattern) or isinstance(target, JPattern): created_pattern = target.targetOffset( int(round(cls.randint_gauss(expand[0], expand[1]))), int(round(cls.randint_gauss(expand[2], expand[3])))) return created_pattern
def _update_fleet_position_once(self): """Method that can be called to find and update the fleet's position on-demand. """ fleet_match = self.kc_region.find( Pattern(self.fleet_icon).similar(Globals.FLEET_ICON_SIMILARITY)) # lastMatch is based off of screen positions, so subtract game region # x and y to get in-game positions self.current_position = [ fleet_match.x + (fleet_match.w / 2) - self.kc_region.x, fleet_match.y + fleet_match.h - self.kc_region.y ] # debug console print for the method's found position of the fleet """ print( "{}, {} ({})".format( self.current_position[0], self.current_position[1], fleet_match)) """ matched_node = self.map.find_node_by_pos(*self.current_position) self.current_node = (matched_node if matched_node is not None else self.current_node) Util.log_msg("Fleet at node {}.".format(self.current_node))
def run_pvp_logic(self): """Primary PvP logic Returns: boolean: True if PvP was run, False otherwise """ if not Util.check_and_click(self.kc_region, Pattern('pvp_row.png').similar(0.8)): Util.log_warning("No PvP opponents available.") self._reset_next_pvp_time() return False self.stats.increment_pvp_attempted() Util.rejigger_mouse(self.regions, 'top') self.regions['lower_left'].wait('pvp_start_1.png', 30) # wait for ship portraits to load to accurately ascertain sub counts Util.kc_sleep(2) opponent_counts = self._count_ships() formation, night_battle = self._pvp_planner(opponent_counts) Util.log_msg("PvPing against {:d} ships ({:d} subs).".format( opponent_counts['ship'], opponent_counts['ss'] + opponent_counts['ssv'])) Util.log_msg("Selecting {} and {!s} on night battle.".format( formation.replace('_', ' '), night_battle)) # start pvp Util.wait_and_click(self.regions['lower_left'], 'pvp_start_1.png', 30) Util.wait_and_click(self.regions['lower'], 'pvp_start_2.png', 30) Util.log_msg("Beginning PvP sortie.") Util.rejigger_mouse(self.regions, 'top') Util.wait_and_click(self.regions[formation], formation) while not (self.regions['lower_right_corner'].exists('next.png') or self.kc_region.exists('combat_nb_fight.png')): # wait through combat pass # resolve night battle if self.kc_region.exists('combat_nb_fight.png'): if (night_battle): Util.check_and_click(self.kc_region, 'combat_nb_fight.png') else: Util.check_and_click(self.kc_region, 'combat_nb_retreat.png') while not self.regions['lower_right_corner'].exists('next.png'): # wait through night battle combat, if applicable pass Util.click_preset_region(self.regions, 'center') while not self.regions['home_menu'].exists('home_menu_sortie.png'): # click through post-combat screens until main menu Util.click_preset_region(self.regions, 'center') Util.kc_sleep(2) self.stats.increment_pvp_done() Util.log_msg("Finished PvP sortie.") self.fleet.needs_resupply = True return True