diff --git a/campaign/campaign_main/campaign_7_1.py b/campaign/campaign_main/campaign_7_1.py index a2ed136c6..9f46e1556 100644 --- a/campaign/campaign_main/campaign_7_1.py +++ b/campaign/campaign_main/campaign_7_1.py @@ -6,19 +6,33 @@ from module.logger import logger MAP = CampaignMap() MAP.map_data = ''' - -- -- -- -- -- -- ++ ++ - -- -- ++ ++ -- -- ++ ++ - -- -- ++ ++ -- -- -- -- + -- ME ME MM ME -- ++ ++ + SP ME ++ ++ ME ME ++ ++ + SP -- ++ ++ -- ME ME MB ''' -MAP.camera_data = ['D2', 'E2'] +MAP.camera_data = ['C1', 'E1'] +MAP.weight_data = ''' + 40 30 21 20 17 15 50 50 + 40 40 50 50 16 13 50 50 + 40 40 50 50 14 12 11 10 +''' +MAP.spawn_data = [ + {'battle': 0, 'enemy': 3}, + {'battle': 1, 'enemy': 2}, + {'battle': 2, 'enemy': 2}, + {'battle': 3, 'enemy': 1, 'mystery': 1}, + {'battle': 4}, + {'battle': 5, 'boss': 1}, +] class Config: SUBMARINE = 0 - POOR_MAP_DATA = True + FLEET_BOSS = 2 - INTERNAL_LINES_HOUGHLINES_THRESHOLD = 30 - EDGE_LINES_HOUGHLINES_THRESHOLD = 30 + INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 + EDGE_LINES_HOUGHLINES_THRESHOLD = 40 + COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 MID_DIFF_RANGE_H = (140 - 3, 140 + 3) MID_DIFF_RANGE_V = (143 - 3, 143 + 3) @@ -39,3 +53,22 @@ class Config: class Campaign(CampaignBase): MAP = MAP + MAP_AMBUSH_OVERLAY_TRANSPARENCY_THRESHOLD = 0.45 + MAP_AIR_RAID_OVERLAY_TRANSPARENCY_THRESHOLD = 0.45 + + def battle_0(self): + self.clear_all_mystery() + self.fleet_2_push_forward() + + return self.battle_default() + + def battle_5(self): + self.clear_all_mystery() + + return self.fleet_2.brute_clear_boss() + + def handle_boss_appear_refocus(self): + for data in self.map.spawn_data: + if data.get('battle') == self.battle_count and data.get('boss', 0): + self.map_swipe((-3, -2)) + return super().handle_boss_appear_refocus() diff --git a/module/map/fleet.py b/module/map/fleet.py index 408db9088..d380d587a 100644 --- a/module/map/fleet.py +++ b/module/map/fleet.py @@ -219,12 +219,20 @@ class Fleet(Camera, MapOperation, AmbushHandler): else: self._goto(location, expected=expected) - def find_path_initial(self): + def find_path_initial(self, grid=None): + """ + Args: + grid (tuple, GridInfo): Current fleet grid + """ + if grid is None: + grid = self.fleet_current + else: + grid = location_ensure(grid) if self.fleet_1_location: self.map[self.fleet_1_location].is_fleet = True if self.fleet_2_location: self.map[self.fleet_2_location].is_fleet = True - self.map.find_path_initial(self.fleet_current, has_ambush=self.config.MAP_HAS_AMBUSH) + self.map.find_path_initial(grid, has_ambush=self.config.MAP_HAS_AMBUSH) def show_fleet(self): fleets = [] @@ -280,6 +288,15 @@ class Fleet(Camera, MapOperation, AmbushHandler): logger.info('Fleet_2 not detected.') if self.config.POOR_MAP_DATA and not self.map.select(is_spawn_point=True): self.fleet_1 = fleets[0].location + elif self.map.select(is_spawn_point=True).count == 2: + logger.info('Predict fleet to be spawn point') + another = self.map.select(is_spawn_point=True).delete(SelectedGrids([fleets[0]]))[0] + if fleets[0].is_current_fleet: + self.fleet_1 = fleets[0].location + self.fleet_2 = another.location + else: + self.fleet_1 = another.location + self.fleet_2 = fleets[0].location else: self.find_all_fleets() elif count == 2: diff --git a/module/map/grid_info.py b/module/map/grid_info.py index f3959f73e..76c917296 100644 --- a/module/map/grid_info.py +++ b/module/map/grid_info.py @@ -6,8 +6,8 @@ class GridInfo: """ Class that gather basic information of a grid in map_v1. - Visit 碧蓝航线WIKI(Chinese Simplified) http://wiki.joyme.com/blhx, to get basic info of a map_v1. For example, - visit http://wiki.joyme.com/blhx/7-2, to know more about campaign 7-2, which includes boss point, enemy spawn point. + Visit 碧蓝航线WIKI(Chinese Simplified) http://wiki.biligame.com/blhx, to get basic info of a map_v1. For example, + visit http://wiki.biligame.com/blhx/7-2, to know more about campaign 7-2, which includes boss point, enemy spawn point. A grid contains these unchangeable properties which can known from WIKI. | print_name | property_name | description | diff --git a/module/map/grid_predictor.py b/module/map/grid_predictor.py index cef8f72ef..c685f0e8d 100644 --- a/module/map/grid_predictor.py +++ b/module/map/grid_predictor.py @@ -68,8 +68,7 @@ class GridPredictor: if not self.is_enemy and not self.is_mystery: if self.predict_dynamic_red_border(): self.enemy_genre = 'Siren_unknown' - if self.config.MAP_HAS_MOVABLE_ENEMY: - self.is_caught_by_siren = self.predict_siren_caught() + self.is_caught_by_siren = self.predict_siren_caught() if self.enemy_genre: self.is_enemy = True diff --git a/module/map/map.py b/module/map/map.py index ce984e6a9..9b812c76f 100644 --- a/module/map/map.py +++ b/module/map/map.py @@ -230,7 +230,8 @@ class Map(Fleet): return False def clear_boss(self): - """Clear BOSS. + """This method is deprecated, although it works well in simple map. + In a complex map, brute_clear_boss is recommended. Returns: bool: @@ -292,6 +293,10 @@ class Map(Fleet): return True else: return self.fleet_boss.clear_boss() + elif self.map.select(may_boss=True, is_caught_by_siren=True): + logger.info('BOSS appear on fleet grid') + self.fleet_2.switch_to() + self.clear_chosen_enemy(self.map.select(may_boss=True, is_caught_by_siren=True)[0]) else: logger.warning('BOSS not detected, trying all boss spawn point.') return self.clear_potential_boss() @@ -356,6 +361,8 @@ class Map(Fleet): Returns: bool: if clear an enemy. """ + if not self.config.FLEET_2: + return False for grid in grids: if self.fleet_at(grid=grid, fleet=2): return False @@ -376,6 +383,8 @@ class Map(Fleet): return True def fleet_2_break_siren_caught(self): + if not self.config.FLEET_2: + return False if not self.config.MAP_HAS_SIREN or not self.config.MAP_HAS_MOVABLE_ENEMY: return False if not self.map.select(is_caught_by_siren=True): @@ -395,3 +404,41 @@ class Map(Fleet): for grid in self.map: grid.is_caught_by_siren = False return True + + def fleet_2_push_forward(self): + """Move fleet 2 to the grid with lower grid.weight + This will reduce the possibility of Boss fleet get stuck by enemies, especially for those one-way-road map + from chapter 7 to chapter 9. + + Know more (in Chinese simplified): + 9章道中战最小化路线规划 (Route Planning for battle minimization in chapter 9) + https://wiki.biligame.com/blhx/9%E7%AB%A0%E9%81%93%E4%B8%AD%E6%88%98%E6%9C%80%E5%B0%8F%E5%8C%96%E8%B7%AF%E7%BA%BF%E8%A7%84%E5%88%92 + + Returns: + bool: If pushed forward. + """ + if not self.config.FLEET_2: + return False + + logger.info('Fleet_2 push forward') + grids = self.map.select(is_land=False).sort(cost=True, weight=True) + if self.map[self.fleet_2_location].weight <= grids[0].weight: + logger.info('Fleet_2 pushed to destination') + return False + + self.find_path_initial(self.fleet_2_location) + fleets = SelectedGrids([self.map[self.fleet_1_location], self.map[self.fleet_2_location]]) + grids = grids.select(is_accessible=True, is_sea=True).delete(fleets) + self.find_path_initial() + if not grids: + logger.info('Fleet_2 has no where to push') + return False + if self.map[self.fleet_2_location].weight <= grids[0].weight: + logger.info('Fleet_2 pushed to closest grid') + return False + + logger.info(f'Grids: {grids}') + logger.info(f'Push forward: {grids[0]}') + self.fleet_2.goto(grids[0]) + self.fleet_1.switch_to() + return True