From 84c06a37d98cdc2808b486a60d8cf908a31bcac6 Mon Sep 17 00:00:00 2001 From: Compeador <00657113@email.ntou.edu.tw> Date: Fri, 7 Aug 2026 00:17:47 +0800 Subject: [PATCH] Fix: handle OS exploration containers (#5854) * fix: handle Operation Siren exploration containers * chore: update os container template --- assets/cn/os/TEMPLATE_ExplorationContainer.png | Bin 0 -> 311 bytes assets/en/os/TEMPLATE_ExplorationContainer.png | Bin 0 -> 311 bytes assets/jp/os/TEMPLATE_ExplorationContainer.png | Bin 0 -> 311 bytes assets/tw/os/TEMPLATE_ExplorationContainer.png | Bin 0 -> 311 bytes module/map_detection/os_grid.py | 8 ++++++++ module/os/assets.py | 1 + module/os/map.py | 16 ++++++++++++++++ module/os/tasks/explore.py | 7 +++++-- 8 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 assets/cn/os/TEMPLATE_ExplorationContainer.png create mode 100644 assets/en/os/TEMPLATE_ExplorationContainer.png create mode 100644 assets/jp/os/TEMPLATE_ExplorationContainer.png create mode 100644 assets/tw/os/TEMPLATE_ExplorationContainer.png diff --git a/assets/cn/os/TEMPLATE_ExplorationContainer.png b/assets/cn/os/TEMPLATE_ExplorationContainer.png new file mode 100644 index 0000000000000000000000000000000000000000..eba07ba5176f397bc5c0f819a8cad51dbb8c8337 GIT binary patch literal 311 zcmV-70m%M|P)X00000%Q7nv0002~NklyYqVpk`PcD8MzHIm*8&QgSi%&mSsVq^I>?OYcQyEc9O0>Esu4tfZ!Zm zW^Lu4>96R8_+!nU)dfT8tAaLR)}$24aVjv!j?$EMEFmJ|3bwl z065tCrh-8?i)YR3{A%W+0J?f8x6H+IaY_O}d$)Pg*oHWL{sSozXA+au`QQKm002ov JPDHLkV1nYIjCBA2 literal 0 HcmV?d00001 diff --git a/assets/en/os/TEMPLATE_ExplorationContainer.png b/assets/en/os/TEMPLATE_ExplorationContainer.png new file mode 100644 index 0000000000000000000000000000000000000000..eba07ba5176f397bc5c0f819a8cad51dbb8c8337 GIT binary patch literal 311 zcmV-70m%M|P)X00000%Q7nv0002~NklyYqVpk`PcD8MzHIm*8&QgSi%&mSsVq^I>?OYcQyEc9O0>Esu4tfZ!Zm zW^Lu4>96R8_+!nU)dfT8tAaLR)}$24aVjv!j?$EMEFmJ|3bwl z065tCrh-8?i)YR3{A%W+0J?f8x6H+IaY_O}d$)Pg*oHWL{sSozXA+au`QQKm002ov JPDHLkV1nYIjCBA2 literal 0 HcmV?d00001 diff --git a/assets/jp/os/TEMPLATE_ExplorationContainer.png b/assets/jp/os/TEMPLATE_ExplorationContainer.png new file mode 100644 index 0000000000000000000000000000000000000000..eba07ba5176f397bc5c0f819a8cad51dbb8c8337 GIT binary patch literal 311 zcmV-70m%M|P)X00000%Q7nv0002~NklyYqVpk`PcD8MzHIm*8&QgSi%&mSsVq^I>?OYcQyEc9O0>Esu4tfZ!Zm zW^Lu4>96R8_+!nU)dfT8tAaLR)}$24aVjv!j?$EMEFmJ|3bwl z065tCrh-8?i)YR3{A%W+0J?f8x6H+IaY_O}d$)Pg*oHWL{sSozXA+au`QQKm002ov JPDHLkV1nYIjCBA2 literal 0 HcmV?d00001 diff --git a/assets/tw/os/TEMPLATE_ExplorationContainer.png b/assets/tw/os/TEMPLATE_ExplorationContainer.png new file mode 100644 index 0000000000000000000000000000000000000000..eba07ba5176f397bc5c0f819a8cad51dbb8c8337 GIT binary patch literal 311 zcmV-70m%M|P)X00000%Q7nv0002~NklyYqVpk`PcD8MzHIm*8&QgSi%&mSsVq^I>?OYcQyEc9O0>Esu4tfZ!Zm zW^Lu4>96R8_+!nU)dfT8tAaLR)}$24aVjv!j?$EMEFmJ|3bwl z065tCrh-8?i)YR3{A%W+0J?f8x6H+IaY_O}d$)Pg*oHWL{sSozXA+au`QQKm002ov JPDHLkV1nYIjCBA2 literal 0 HcmV?d00001 diff --git a/module/map_detection/os_grid.py b/module/map_detection/os_grid.py index 494b17cae..5f1a6112f 100644 --- a/module/map_detection/os_grid.py +++ b/module/map_detection/os_grid.py @@ -19,6 +19,7 @@ class OSGridInfo(GridInfo): is_scanning_device = False is_logging_tower = False is_exploration_reward = False + is_exploration_container = False is_fleet_mechanism = False is_fleet = False @@ -37,6 +38,7 @@ class OSGridInfo(GridInfo): 'SD': 'is_scanning_device', 'LT': 'is_logging_tower', 'ER': 'is_exploration_reward', + 'EC': 'is_exploration_container', 'FM': 'is_fleet_mechanism', } for key, value in dic.items(): @@ -93,6 +95,9 @@ class OSGridInfo(GridInfo): if info.is_exploration_reward: self.is_exploration_reward = True return True + if info.is_exploration_container: + self.is_exploration_container = True + return True if info.is_fleet_mechanism: self.is_fleet_mechanism = True return True @@ -137,6 +142,7 @@ class OSGridInfo(GridInfo): self.is_scanning_device = False self.is_logging_tower = False self.is_exploration_reward = False + self.is_exploration_container = False self.is_fleet_mechanism = False def reset(self): @@ -161,6 +167,7 @@ class OSGridPredictor(GridPredictor): self.is_scanning_device = self.enemy_genre == 'ScanningDevice' self.is_logging_tower = self.enemy_genre == 'LoggingTower' self.is_exploration_reward = self.enemy_genre == 'ExplorationReward' + self.is_exploration_container = self.enemy_genre == 'ExplorationContainer' self.is_current_fleet = self.predict_current_fleet() self.is_fleet = self.is_current_fleet self.is_fleet_mechanism = self.predict_fleet_mechanism() @@ -210,6 +217,7 @@ class OSGridPredictor(GridPredictor): 'ScanningDevice': TEMPLATE_ScanningDevice, 'LoggingTower': TEMPLATE_LoggingTower, 'ExplorationReward': TEMPLATE_ExplorationReward, + 'ExplorationContainer': TEMPLATE_ExplorationContainer, } _os_template_enemy_upper = { 'ScanningDevice': TEMPLATE_ScanningDeviceUpper, diff --git a/module/os/assets.py b/module/os/assets.py index 550dd2522..c5bf7cbec 100644 --- a/module/os/assets.py +++ b/module/os/assets.py @@ -26,6 +26,7 @@ SELECT_SAFE = Button(area={'cn': (89, 251, 167, 269), 'en': (92, 253, 164, 268), SELECT_STRONGHOLD = Button(area={'cn': (89, 251, 166, 269), 'en': (81, 252, 175, 272), 'jp': (89, 251, 167, 269), 'tw': (88, 250, 167, 270)}, color={'cn': (113, 114, 118), 'en': (81, 83, 87), 'jp': (115, 116, 119), 'tw': (103, 105, 108)}, button={'cn': (89, 251, 166, 269), 'en': (81, 252, 175, 272), 'jp': (89, 251, 167, 269), 'tw': (88, 250, 167, 270)}, file={'cn': './assets/cn/os/SELECT_STRONGHOLD.png', 'en': './assets/en/os/SELECT_STRONGHOLD.png', 'jp': './assets/jp/os/SELECT_STRONGHOLD.png', 'tw': './assets/tw/os/SELECT_STRONGHOLD.png'}) STRONGHOLD_PERCENTAGE = Button(area={'cn': (293, 125, 340, 143), 'en': (293, 125, 340, 143), 'jp': (293, 125, 340, 143), 'tw': (293, 125, 340, 143)}, color={'cn': (132, 135, 146), 'en': (132, 135, 146), 'jp': (132, 135, 146), 'tw': (132, 135, 146)}, button={'cn': (293, 125, 340, 143), 'en': (293, 125, 340, 143), 'jp': (293, 125, 340, 143), 'tw': (293, 125, 340, 143)}, file={'cn': './assets/cn/os/STRONGHOLD_PERCENTAGE.png', 'en': './assets/en/os/STRONGHOLD_PERCENTAGE.png', 'jp': './assets/jp/os/STRONGHOLD_PERCENTAGE.png', 'tw': './assets/tw/os/STRONGHOLD_PERCENTAGE.png'}) TEMPLATE_EMPTY_HP = Template(file={'cn': './assets/cn/os/TEMPLATE_EMPTY_HP.png', 'en': './assets/en/os/TEMPLATE_EMPTY_HP.png', 'jp': './assets/jp/os/TEMPLATE_EMPTY_HP.png', 'tw': './assets/tw/os/TEMPLATE_EMPTY_HP.png'}) +TEMPLATE_ExplorationContainer = Template(file={'cn': './assets/cn/os/TEMPLATE_ExplorationContainer.png', 'en': './assets/en/os/TEMPLATE_ExplorationContainer.png', 'jp': './assets/jp/os/TEMPLATE_ExplorationContainer.png', 'tw': './assets/tw/os/TEMPLATE_ExplorationContainer.png'}) TEMPLATE_ExplorationReward = Template(file={'cn': './assets/cn/os/TEMPLATE_ExplorationReward.png', 'en': './assets/en/os/TEMPLATE_ExplorationReward.png', 'jp': './assets/jp/os/TEMPLATE_ExplorationReward.png', 'tw': './assets/tw/os/TEMPLATE_ExplorationReward.png'}) TEMPLATE_FleetMechanism = Template(file={'cn': './assets/cn/os/TEMPLATE_FleetMechanism.png', 'en': './assets/en/os/TEMPLATE_FleetMechanism.png', 'jp': './assets/jp/os/TEMPLATE_FleetMechanism.png', 'tw': './assets/tw/os/TEMPLATE_FleetMechanism.png'}) TEMPLATE_LoggingTower = Template(file={'cn': './assets/cn/os/TEMPLATE_LoggingTower.png', 'en': './assets/en/os/TEMPLATE_LoggingTower.png', 'jp': './assets/jp/os/TEMPLATE_LoggingTower.png', 'tw': './assets/tw/os/TEMPLATE_LoggingTower.png'}) diff --git a/module/os/map.py b/module/os/map.py index 55934a079..9a900aa3c 100644 --- a/module/os/map.py +++ b/module/os/map.py @@ -785,10 +785,26 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler): Returns: bool: If solved a map random event """ + grids = self.view.select(is_exploration_container=True) + if 'is_exploration_container' not in self._solved_map_event \ + and grids and grids[0].is_exploration_container: + grid = grids[0] + logger.info(f'Found exploration container on {grid}') + self.device.click(grid) + with self.config.temporary(STORY_ALLOW_SKIP=False, STORY_OPTION=1): + result = self.wait_until_walk_stable( + drop=drop, walk_out_of_step=False, confirm_timer=Timer(1.5, count=4)) + if 'event' in result: + self._solved_map_event.add('is_exploration_container') + return True + else: + return False + grids = self.view.select(is_exploration_reward=True) if 'is_exploration_reward' not in self._solved_map_event and grids and grids[0].is_exploration_reward: grid = grids[0] logger.info(f'Found exploration reward on {grid}') + self.device.click(grid) result = self.wait_until_walk_stable(drop=drop, walk_out_of_step=False, confirm_timer=Timer(1.5, count=4)) if 'event' in result: self._solved_map_event.add('is_exploration_reward') diff --git a/module/os/tasks/explore.py b/module/os/tasks/explore.py index acfc952d9..9c4466bcd 100644 --- a/module/os/tasks/explore.py +++ b/module/os/tasks/explore.py @@ -91,8 +91,11 @@ class OpsiExplore(OSMap): self.config.OpsiExplore_LastZone = zone logger.info(f'Zone cleared: {self.name_to_zone(zone)}') if finished_combat == 0: - logger.warning('Zone cleared but did not finish any combat') - self._os_explore_failed_zone.append(zone) + if 'is_exploration_container' in self._solved_map_event: + logger.info('Zone cleared by exploration container') + else: + logger.warning('Zone cleared but did not finish any combat') + self._os_explore_failed_zone.append(zone) self.handle_after_auto_search() self.config.check_task_switch()