From 81f9b61ea575d562860e525c0aef3a8d9e891daa Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Fri, 5 Jun 2020 03:51:54 +0800 Subject: [PATCH] Add: Logic fleet_2_rescue, Logic for chapter 3 - Fix camera outside map caused by info bar - Fix mis-detection of is_caught_by_siren - Fix grid attribute is_caught_by_siren will be kept to next attack - Fix find_current_fleet when ammo icon of another fleet is covered by the green arrow of current fleet - Fix fleet_boss_index - Fix can not predict when boss appear on fleet's face --- .../cn/template/TEMPLATE_CAUGHT_BY_SIREN.png | Bin 6356 -> 5016 bytes .../en/template/TEMPLATE_CAUGHT_BY_SIREN.png | Bin 6356 -> 5016 bytes campaign/campaign_main/campaign_3_1.py | 14 ++++- campaign/campaign_main/campaign_3_2.py | 12 +++- campaign/campaign_main/campaign_3_3.py | 9 ++- campaign/campaign_main/campaign_3_4.py | 13 +++-- module/map/camera.py | 10 +++- module/map/fleet.py | 17 +++++- module/map/grid_info.py | 11 +++- module/map/grid_predictor.py | 1 - module/map/map.py | 29 +++++++++- module/map/map_base.py | 52 +++++++++++------- 12 files changed, 123 insertions(+), 45 deletions(-) diff --git a/assets/cn/template/TEMPLATE_CAUGHT_BY_SIREN.png b/assets/cn/template/TEMPLATE_CAUGHT_BY_SIREN.png index 25542f881504a45e43d78772fca46579c798ea1c..4bb61ddb41e5302bb091a21b623fe33408397ac0 100644 GIT binary patch delta 2327 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 diff --git a/assets/en/template/TEMPLATE_CAUGHT_BY_SIREN.png b/assets/en/template/TEMPLATE_CAUGHT_BY_SIREN.png index 25542f881504a45e43d78772fca46579c798ea1c..4bb61ddb41e5302bb091a21b623fe33408397ac0 100644 GIT binary patch delta 2327 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 diff --git a/campaign/campaign_main/campaign_3_1.py b/campaign/campaign_main/campaign_3_1.py index 29980b8b1..b87a7025d 100644 --- a/campaign/campaign_main/campaign_3_1.py +++ b/campaign/campaign_main/campaign_3_1.py @@ -14,9 +14,9 @@ MAP.map_data = ''' ''' MAP.weight_data = ''' 30 30 30 20 10 10 10 - 30 30 30 20 10 10 10 - 40 40 40 20 10 10 10 + 30 30 30 20 10 09 10 40 40 40 20 10 10 10 + 40 40 40 20 20 10 10 ''' MAP.spawn_data = [ {'battle': 0, 'enemy': 2, 'mystery': 1}, @@ -36,6 +36,9 @@ class Config: FLEET_BOSS = 1 MAP_MYSTERY_HAS_CARRIER = True + + INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 + EDGE_LINES_HOUGHLINES_THRESHOLD = 40 INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { 'height': (120, 255 - 40), 'width': (1.5, 10), @@ -54,6 +57,11 @@ class Campaign(CampaignBase): MAP = MAP def battle_0(self): + self.fleet_2_push_forward() + + if self.fleet_2_rescue(G2): + return True + self.clear_all_mystery() return self.battle_default() @@ -64,4 +72,4 @@ class Campaign(CampaignBase): if not self.check_accessibility(G2, fleet='boss'): return self.fleet_boss.battle_default() - return self.clear_boss() + return self.fleet_boss.clear_boss() diff --git a/campaign/campaign_main/campaign_3_2.py b/campaign/campaign_main/campaign_3_2.py index 7d35d6e33..e0e833019 100644 --- a/campaign/campaign_main/campaign_3_2.py +++ b/campaign/campaign_main/campaign_3_2.py @@ -15,10 +15,10 @@ MAP.map_data = ''' SP ME -- -- ME MM -- ++ ''' MAP.weight_data = ''' - 50 50 50 30 30 20 10 10 + 50 50 50 30 30 20 10 09 50 50 40 40 30 20 10 10 - 50 50 50 40 40 20 20 20 - 50 50 50 50 35 30 30 30 + 50 50 50 40 40 50 20 20 + 50 50 50 50 35 50 50 50 ''' MAP.spawn_data = [ {'battle': 0, 'enemy': 2, 'mystery': 1}, @@ -38,11 +38,17 @@ class Campaign(CampaignBase): MAP = MAP def battle_0(self): + self.fleet_2_push_forward() + + if self.fleet_2_rescue(H1): + return True + self.clear_all_mystery() return self.battle_default() def battle_3(self): + # print(H1.__dict__) self.clear_all_mystery() if not self.check_accessibility(H1, fleet='boss'): diff --git a/campaign/campaign_main/campaign_3_3.py b/campaign/campaign_main/campaign_3_3.py index dbddd0c7f..6f068df4c 100644 --- a/campaign/campaign_main/campaign_3_3.py +++ b/campaign/campaign_main/campaign_3_3.py @@ -18,8 +18,8 @@ MAP.weight_data = ''' 50 50 30 30 50 50 50 50 30 30 50 50 50 50 20 30 50 50 - 10 10 10 20 50 50 - 10 10 10 50 50 50 + 09 10 11 20 50 50 + 10 10 11 50 50 50 ''' MAP.spawn_data = [ {'battle': 0, 'enemy': 2, 'mystery': 1}, @@ -40,6 +40,11 @@ class Campaign(CampaignBase): MAP = MAP def battle_0(self): + self.fleet_2_push_forward() + + if self.fleet_2_rescue(A4): + return True + self.clear_all_mystery() return self.battle_default() diff --git a/campaign/campaign_main/campaign_3_4.py b/campaign/campaign_main/campaign_3_4.py index d1348f4a9..bd20900d9 100644 --- a/campaign/campaign_main/campaign_3_4.py +++ b/campaign/campaign_main/campaign_3_4.py @@ -18,8 +18,8 @@ MAP.map_data = ''' MAP.weight_data = ''' 40 40 40 40 40 40 40 40 40 40 40 30 30 30 30 30 - 40 40 30 30 20 10 10 10 - 40 40 30 20 20 10 10 10 + 40 40 30 30 20 10 10 09 + 40 40 30 20 20 10 10 09 ''' MAP.spawn_data = [ {'battle': 0, 'enemy': 2}, @@ -38,15 +38,16 @@ A4, B4, C4, D4, E4, F4, G4, H4, \ class Config(Config31): MAP_MYSTERY_HAS_CARRIER = False - # Map 3-4 is relatively small for the density of enemies. - INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 - EDGE_LINES_HOUGHLINES_THRESHOLD = 40 - class Campaign(CampaignBase): MAP = MAP def battle_0(self): + self.fleet_2_push_forward() + + if self.fleet_2_rescue(H3): + return True + return self.battle_default() def battle_3(self): diff --git a/module/map/camera.py b/module/map/camera.py index 1b2038ff2..4900257fe 100644 --- a/module/map/camera.py +++ b/module/map/camera.py @@ -111,7 +111,15 @@ class Camera(InfoHandler): self.grids.update(image=self.device.image) return True - self.grids = Grids(self.device.image, config=self.config) + try: + self.grids = Grids(self.device.image, config=self.config) + except PerspectiveError as e: + if self.info_bar_count(): + logger.info('Perspective error cause by info bar. Waiting.') + self.handle_info_bar() + return self.update(camera=camera) + else: + raise e # Catch perspective error known_exception = self.info_bar_count() diff --git a/module/map/fleet.py b/module/map/fleet.py index 421cca48b..34179a78a 100644 --- a/module/map/fleet.py +++ b/module/map/fleet.py @@ -1,5 +1,6 @@ import itertools + from module.base.timer import Timer from module.exception import MapWalkError from module.handler.ambush import AmbushHandler @@ -58,7 +59,7 @@ class Fleet(Camera, MapOperation, AmbushHandler): @property def fleet_boss_index(self): if self.config.FLEET_BOSS == 2 or self.config.FLEET_2: - return 1 + return 2 else: return 1 @@ -265,7 +266,12 @@ class Fleet(Camera, MapOperation, AmbushHandler): for loca in [self.fleet_1_location, self.fleet_2_location]: if len(loca) and loca in self.map: - self.map[loca].wipe_out() + grid = self.map[loca] + if grid.may_boss and grid.is_caught_by_siren: + # Only boss appears on fleet's face + pass + else: + self.map[loca].wipe_out() def find_all_fleets(self): logger.hr('Find all fleets') @@ -306,7 +312,12 @@ class Fleet(Camera, MapOperation, AmbushHandler): self.fleet_1 = another.location self.fleet_2 = fleets[0].location else: - self.find_all_fleets() + cover = self.map.grid_covered(fleets[0], location=[(0, -1)]) + if fleets[0].is_current_fleet and len(cover) and cover[0].is_spawn_point: + self.fleet_1 = fleets[0].location + self.fleet_2 = cover[0].location + else: + self.find_all_fleets() elif count == 2: current = self.map.select(is_current_fleet=True) if current.count == 1: diff --git a/module/map/grid_info.py b/module/map/grid_info.py index 31a0c88d0..ec6987fbf 100644 --- a/module/map/grid_info.py +++ b/module/map/grid_info.py @@ -139,11 +139,17 @@ class GridInfo: ignore_may (bool): Ignore map_data, force update. ignore_cleared (bool): Ignore is_cleared property. """ + if info.is_caught_by_siren: + self.is_caught_by_siren = True + for item in ['boss', 'siren']: if info.enemy_scale or self.enemy_scale: break if info.__getattribute__('is_' + item): - flag = not info.is_fleet and not self.is_fleet + if item == 'boss': + flag = not info.is_fleet + else: + flag = not info.is_fleet and not self.is_fleet if not ignore_may: flag &= self.__getattribute__('may_' + item) if not ignore_cleared: @@ -186,8 +192,6 @@ class GridInfo: self.is_fleet = info.is_fleet if info.is_current_fleet: self.is_current_fleet = True - if info.is_caught_by_siren: - self.is_caught_by_siren = True return False def wipe_out(self): @@ -201,6 +205,7 @@ class GridInfo: self.is_boss = False self.is_ammo = False self.is_siren = False + self.is_caught_by_siren = False def reset(self): """ diff --git a/module/map/grid_predictor.py b/module/map/grid_predictor.py index c685f0e8d..005c1b4c0 100644 --- a/module/map/grid_predictor.py +++ b/module/map/grid_predictor.py @@ -267,4 +267,3 @@ class GridPredictor: return name return None - diff --git a/module/map/map.py b/module/map/map.py index 9b812c76f..de99d18a0 100644 --- a/module/map/map.py +++ b/module/map/map.py @@ -237,7 +237,8 @@ class Map(Fleet): bool: """ grids = self.map.select(is_boss=True, is_accessible=True) - logger.info('Is boss: %s' % self.map.select(is_boss=True)) + grids = grids.add(self.map.select(may_boss=True, is_caught_by_siren=True)) + logger.info('Is boss: %s' % grids) if not grids.count: grids = grids.add(self.map.select(may_boss=True, is_enemy=True, is_accessible=True)) logger.warning('Boss not detected, using may_boss grids.') @@ -277,6 +278,7 @@ class Map(Fleet): def brute_clear_boss(self): """ Method to clear boss, using brute-force to find roadblocks. + Note: This method will use 2 fleets. """ boss = self.map.select(is_boss=True) if boss: @@ -296,7 +298,7 @@ class Map(Fleet): 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]) + return 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() @@ -442,3 +444,26 @@ class Map(Fleet): self.fleet_2.goto(grids[0]) self.fleet_1.switch_to() return True + + def fleet_2_rescue(self, grid): + """Use mob fleet to rescue boss fleet. + + Args: + grid (GridInfo): Destination. Usually to be boss spawn grid. + + Returns: + bool: If clear an enemy. + """ + if not self.config.FLEET_2: + return False + + grids = self.brute_find_roadblocks(grid, fleet=2) + if not grids: + return False + logger.info('Fleet_2 rescue') + grids = self.select_grids(grids) + if not grids: + return False + + self.clear_chosen_enemy(grids[0]) + return True diff --git a/module/map/map_base.py b/module/map/map_base.py index bb303b49f..5b8829040 100644 --- a/module/map/map_base.py +++ b/module/map/map_base.py @@ -392,6 +392,22 @@ class CampaignMap: return path + def grid_covered(self, grid, location=None): + """ + Args: + grid (GridInfo) + location (list[tuple[int]]): Relative coordinate of the covered grid. + + Returns: + list[GridInfo]: + """ + if location is None: + covered = [tuple(np.array(grid.location) + upper) for upper in grid.covered_grid()] + else: + covered = [tuple(np.array(grid.location) + upper) for upper in location] + covered = [self[upper] for upper in covered if upper in self] + return covered + def missing_get(self, battle_count, mystery_count=0, siren_count=0, carrier_count=0): try: missing = self.spawn_data[battle_count].copy() @@ -408,15 +424,12 @@ class CampaignMap: missing[attr] -= 1 for grid in self: - for upper in grid.covered_grid(): - upper = tuple(np.array(grid.location) + upper) - if upper in self: - upper = self[upper] - for attr in ['enemy', 'mystery', 'siren', 'boss']: - if upper.__getattribute__('may_' + attr) and not upper.__getattribute__('is_' + attr): - may[attr] += 1 - if upper.may_carrier: - may['carrier'] += 1 + for upper in self.grid_covered(grid): + for attr in ['enemy', 'mystery', 'siren', 'boss']: + if upper.__getattribute__('may_' + attr) and not upper.__getattribute__('is_' + attr): + may[attr] += 1 + if upper.may_carrier: + may['carrier'] += 1 logger.attr('enemy_missing', ', '.join([f'{k[:2].upper()}:{str(v).rjust(2)}' for k, v in missing.items() if k != 'battle'])) @@ -444,18 +457,15 @@ class CampaignMap: # predict for grid in self: - for upper in grid.covered_grid(): - upper = tuple(np.array(grid.location) + upper) - if upper in self: - upper = self[upper] - for attr in ['enemy', 'mystery', 'siren', 'boss']: - if upper.__getattribute__('may_' + attr) and missing[attr] > 0 and missing[attr] == may[attr]: - logger.info('Predict %s to be %s' % (location2node(upper.location), attr)) - upper.__setattr__('is_' + attr, True) - if carrier_count: - if upper.may_carrier and missing['carrier'] > 0 and missing['carrier'] == may['carrier']: - logger.info('Predict %s to be enemy' % location2node(upper.location)) - upper.__setattr__('is_enemy', True) + for upper in self.grid_covered(grid): + for attr in ['enemy', 'mystery', 'siren', 'boss']: + if upper.__getattribute__('may_' + attr) and missing[attr] > 0 and missing[attr] == may[attr]: + logger.info('Predict %s to be %s' % (location2node(upper.location), attr)) + upper.__setattr__('is_' + attr, True) + if carrier_count: + if upper.may_carrier and missing['carrier'] > 0 and missing['carrier'] == may['carrier']: + logger.info('Predict %s to be enemy' % location2node(upper.location)) + upper.__setattr__('is_enemy', True) def select(self, **kwargs): """