AzurLaneAutoScript icon indicating copy to clipboard operation
AzurLaneAutoScript copied to clipboard

Fix: exiting combat status properly using MAP_GOTO_GLOBE_STORY

Open guoh064 opened this issue 1 year ago • 7 comments

guoh064 2024/11/6 13:00:26 7{R$%FOD2OEMN%~Y$PG9O51_tmb

求助,像这样EXP_INFO_S点了6次,CLICK_SAFE_AREA也点了6次的情况有没有什么办法可以从代码层面避免报错?从截图里面看不出来是不是60帧运行所以也不知道跟电脑性能有多大关系(交替出现story_option和GET_ITEMS也许是一个判断方法?)

吕明珠LmeSzinc 2024/11/6 19:11:09 把这个连击的问题解决一下

guoh064 avatar Nov 20 '24 02:11 guoh064

两次点击间隔50ms说明是在同一张截图上触发的重复点击,要去找出是什么触发了这些点击 防止重复触发

LmeSzinc avatar Nov 22 '24 15:11 LmeSzinc

分析结果

一句话概括:OSCombat._os_combat_expected_end()OSCombat.handle_get_items() 在未能离开的 Combat.combat_status() 内同一截图循环里面分别点击了 CLICK_SAFE_AREA

解决方案:正确地提前退出 Combat.combat_status(),方式有待讨论。

以下分析过程,太长不看。

首先注意到,这里的报错调用的是在 combat_status() 下的 handle_get_items() ,而不是 MapEventHandler 里面的 handle_map_get_items() ;这是由于战斗结束后未能及时退出 combat_status 结算导致的(大世界的物品获得结算并不像主线一样在 battle_status 之前,而是结束战斗回到海面之后获得,所以理论上应该在跳转时就离开 combat_status 了)

  • 为什么没有退出 combat_status() 呢? 我们这里调用的 combat_status() 传递的参数 expected_end 看似EnemySearchingHandler.is_in_map() (继承关系为 EnemySearchingHandlerMapEventHandlerCombatOSFleet

实际上这个参数传到 os_combat.combat_status() 的时候 expected 被强制改成了 OSCombat._os_combat_expected_end()

    def combat_status(self, drop=None, expected_end=None):
        self.__os_combat_drop = drop
        super().combat_status(drop=drop, expected_end=self._os_combat_expected_end)
        self.device.click_record_clear()

OSCombat._os_combat_expected_end() 内容如下:

    def _os_combat_expected_end(self):
        if self.handle_map_event(drop=self.__os_combat_drop):
            return False
        if self.combat_appear():
            raise ContinuousCombat

        return self.handle_os_in_map()

这里会最后运行到 self.handle_os_in_map() 函数,从而依旧为 EnemySearchingHandler.is_in_map();但是这里对话框挡住了 assets 使得 IN_MAPMAP_GOTO_GLOBE_FOG 均未能识别成功。

  • 为什么没有退出 combat_status() 就会导致双击呢?

继续看 OSCombat._os_combat_expected_end(),注意到这里调用了 MapEventHandler.handle_map_event(drop=self.__os_combat_drop)

这里由于图片里面有 GET_ITEMS_Xhandle_map_event 第一次调用了 MapEventHandler.handle_map_get_items(),并点击了 CLICK_SAFE_AREA

_os_combat_expected_end() 返回 False,从而 expected_end() 失败; 在当前截图下继续执行后续命令,执行到 if self.handle_get_items(drop=drop): 时,调用 OSCombat.handle_get_items()第二次点击了 CLICK_SAFE_AREA

guoh064 avatar Nov 27 '24 09:11 guoh064

@LmeSzinc 已修改

guoh064 avatar Nov 29 '24 08:11 guoh064

is_in_map() 是识别是否在海域地图中,而转场动画不属于,加到这里不合适

LmeSzinc avatar Dec 09 '24 10:12 LmeSzinc

@LmeSzinc 已修改,照搬了MAP_GOTO_GLOBE_FOG的思路。

guoh064 avatar Dec 11 '24 14:12 guoh064

不是,is_in_map 指的是这个海域,它没有出现或者受到遮挡都不能返回True,说了不要改 is_in_map 了 image

LmeSzinc avatar Dec 13 '24 02:12 LmeSzinc

行吧, 那你能给一个合适的解决方案吗 至少指点一下你希望的解决方式是什么

guoh064 avatar Dec 13 '24 02:12 guoh064