diff --git a/campaign/campaign_war_archives/campaign_base.py b/campaign/campaign_war_archives/campaign_base.py index 6c70ad3fa..89d571303 100644 --- a/campaign/campaign_war_archives/campaign_base.py +++ b/campaign/campaign_war_archives/campaign_base.py @@ -180,29 +180,13 @@ class CampaignBase(CampaignBase_): self._prev_oil = oil return checked - def auto_search_watch_oil(self, checked=False): + def _check_oil(self, oil): """ - Watch oil. - This will set auto_search_oil_limit_triggered. + Override to check oil threshold of one battle before normal oil handling. """ - if not checked: - oil = self.get_oil() - if oil == 0: - logger.warning('Oil not found') - else: - if self.check_oil_threshold(oil): - self._interrupt = True - if oil < max(500, self.config.StopCondition_OilLimit): - logger.info('Reach oil limit') - self.auto_search_oil_limit_triggered = True - else: - if self.auto_search_oil_limit_triggered: - logger.warning('auto_search_oil_limit_triggered but oil recovered, ' - 'probably because of wrong OCR result before') - self.auto_search_oil_limit_triggered = False - checked = True - - return checked + if oil > 0 and self.check_oil_threshold(oil): + self._interrupt = True + super()._check_oil(oil) def auto_search_combat(self, emotion_reduce=None, fleet_index=1, battle=None): """ diff --git a/module/campaign/campaign_status.py b/module/campaign/campaign_status.py index 618aa99c3..fb5255778 100644 --- a/module/campaign/campaign_status.py +++ b/module/campaign/campaign_status.py @@ -62,35 +62,6 @@ class CampaignStatus(UI): self.config.update() return pt - def get_coin(self, skip_first_screenshot=True, update=False): - """ - Returns: - int: Coin amount - """ - _coin = {} - timeout = Timer(1, count=2).start() - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - if timeout.reached(): - logger.warning('Get coin timeout') - break - - _coin = { - 'Value': self._get_num(OCR_COIN, 'OCR_COIN', (239, 239, 239)), - 'Limit': self._get_num(OCR_COIN_LIMIT, 'OCR_COIN_LIMIT', (239, 239, 239)) - } - if _coin['Value'] >= 100: - break - LogRes(self.config).Coin = _coin - if update: - self.config.update() - - return _coin['Value'] - def _get_num(self, _button, name, letter): # Update offset _ = self.appear(OCR_OIL_CHECK) @@ -120,13 +91,33 @@ class CampaignStatus(UI): return ocr.ocr(self.device.image) + def _get_oil_limit(self): + if not hasattr(self, '_oil_limit_cache'): + limit = self._get_num(OCR_OIL_LIMIT, 'OCR_OIL_LIMIT', (247, 247, 247)) + if 1000 < limit <= 25000: + self._oil_limit_cache = limit + else: + logger.warning(f'Invalid oil limit: {limit}') + return 0 + return self._oil_limit_cache + + def _get_coin_limit(self): + if not hasattr(self, '_coin_limit_cache'): + limit = self._get_num(OCR_COIN_LIMIT, 'OCR_COIN_LIMIT', (239, 239, 239)) + if 10000 < limit <= 150000: + self._coin_limit_cache = limit + else: + logger.warning(f'Invalid coin limit: {limit}') + return 0 + return self._coin_limit_cache + def get_oil(self, skip_first_screenshot=True, update=False): """ Returns: int: Oil amount """ - _oil = {} - last = 0 + oil = 0 + last_oil = 0 timeout = Timer(1, count=2).start() while 1: if skip_first_screenshot: @@ -136,24 +127,40 @@ class CampaignStatus(UI): if not self.appear(OCR_OIL_CHECK, offset=(10, 2)): logger.info('No oil icon') - self.device.sleep(1) + continue if timeout.reached(): logger.warning('Get oil timeout') + oil = 0 break - _oil = { - 'Value': self._get_num(OCR_OIL, 'OCR_OIL', (247, 247, 247)), - 'Limit': self._get_num(OCR_OIL_LIMIT, 'OCR_OIL_LIMIT', (247, 247, 247)) - } - if last == _oil['Value'] and _oil['Value'] >= 100 and _oil['Limit'] <= 50000: + oil = self._get_num(OCR_OIL, 'OCR_OIL', (247, 247, 247)) + if last_oil == oil and oil >= 100: break - last = _oil['Value'] - LogRes(self.config).Oil = _oil + last_oil = oil + + if oil: + LogRes(self.config).Oil = {'Value': oil, 'Limit': self._get_oil_limit()} if update: self.config.update() - return _oil['Value'] + return oil + + def get_oil_and_coin(self, skip_first_screenshot=True, update=False): + """ + Read oil and coin sharing a single screenshot. + + Returns: + tuple[int, int]: (oil, coin) + """ + oil = self.get_oil(skip_first_screenshot=skip_first_screenshot, update=False) + coin = 0 + if oil: + coin = self._get_num(OCR_COIN, 'OCR_COIN', (239, 239, 239)) + LogRes(self.config).Coin = {'Value': coin, 'Limit': self._get_coin_limit()} + if update: + self.config.update() + return oil, coin def is_balancer_task(self): """ diff --git a/module/campaign/run.py b/module/campaign/run.py index bdfddcd44..c4b54e122 100644 --- a/module/campaign/run.py +++ b/module/campaign/run.py @@ -99,8 +99,7 @@ class CampaignRun(CampaignEvent, ShopStatus): # Oil limit if oil_check: self.status_get_gems() - self.get_coin() - _oil = self.get_oil() + _oil, _ = self.get_oil_and_coin() if _oil < max(500, self.config.StopCondition_OilLimit): logger.hr('Triggered stop condition: Oil limit') self.config.task_delay(minute=60) diff --git a/module/combat/auto_search_combat.py b/module/combat/auto_search_combat.py index 5e6689e51..bce061fac 100644 --- a/module/combat/auto_search_combat.py +++ b/module/combat/auto_search_combat.py @@ -121,52 +121,51 @@ class AutoSearchCombat(MapOperation, Combat, CampaignStatus): return checked - def auto_search_watch_oil(self, checked=False): + def _check_oil(self, oil): """ - Watch oil. - This will set auto_search_oil_limit_triggered. + Check oil threshold and set auto_search_oil_limit_triggered. + """ + if oil == 0: + logger.warning('Oil not found') + return + if oil < max(500, self.config.StopCondition_OilLimit): + logger.info('Reach oil limit') + self.auto_search_oil_limit_triggered = True + else: + if self.auto_search_oil_limit_triggered: + logger.warning('auto_search_oil_limit_triggered but oil recovered, ' + 'probably because of wrong OCR result before') + self.auto_search_oil_limit_triggered = False + + def _check_coin(self, coin): + """ + Check coin threshold and set auto_search_coin_limit_triggered. + """ + if coin == 0: + logger.warning('Coin not found') + return + limit = self.config.TaskBalancer_CoinLimit + if self.is_balancer_task(): + if coin < limit: + logger.info('Reach coin limit') + self.auto_search_coin_limit_triggered = True + else: + self.auto_search_coin_limit_triggered = False + else: + if self.auto_search_coin_limit_triggered: + logger.warning('auto_search_coin_limit_triggered but coin recovered, ' + 'probably because of wrong OCR result before') + self.auto_search_coin_limit_triggered = False + + def auto_search_watch_resources(self, checked=False): + """ + Watch oil and coin sharing a single screenshot. """ if not checked: - oil = self.get_oil() - if oil == 0: - logger.warning('Oil not found') - else: - if oil < max(500, self.config.StopCondition_OilLimit): - logger.info('Reach oil limit') - self.auto_search_oil_limit_triggered = True - else: - if self.auto_search_oil_limit_triggered: - logger.warning('auto_search_oil_limit_triggered but oil recovered, ' - 'probably because of wrong OCR result before') - self.auto_search_oil_limit_triggered = False - checked = True - - return checked - - def auto_search_watch_coin(self, checked=False): - """ - Watch coin. - This will set auto_search_coin_limit_triggered. - """ - if not checked: - limit = self.config.TaskBalancer_CoinLimit - coin = self.get_coin() - if coin == 0: - logger.warning('Coin not found') - else: - if self.is_balancer_task(): - if coin < limit: - logger.info('Reach coin limit') - self.auto_search_coin_limit_triggered = True - else: - # Enough coin - self.auto_search_coin_limit_triggered = False - else: - if self.auto_search_coin_limit_triggered: - logger.warning('auto_search_coin_limit_triggered but coin recovered, ' - 'probably because of wrong OCR result before') - self.auto_search_coin_limit_triggered = False - checked = True + oil, coin = self.get_oil_and_coin() + self._check_oil(oil) + self._check_coin(coin) + checked = True return checked @@ -198,15 +197,13 @@ class AutoSearchCombat(MapOperation, Combat, CampaignStatus): logger.info('Auto search moving') self.device.stuck_record_clear() checked_fleet = False - checked_oil = False - checked_coin = False + checked_resources = False for _ in self.loop(): if self.is_auto_search_running(): checked_fleet = self.auto_search_watch_fleet(checked_fleet) - if not checked_oil or not checked_coin: - checked_oil = self.auto_search_watch_oil(checked_oil) - checked_coin = self.auto_search_watch_coin(checked_coin) + if not checked_resources: + checked_resources = self.auto_search_watch_resources(checked_resources) if self.handle_retirement(): self.map_offensive_auto_search() # Map offensive ends at is_combat_loading