mirror of
https://github.com/0O0o0oOoO00/Alas.git
synced 2026-05-14 07:39:25 +08:00
Add: Cross zone scanning device reset(Part of story_skip handler)
This commit is contained in:
@@ -571,4 +571,74 @@ class InfoHandler(ModuleBase):
|
||||
if manjuu_timer.reached():
|
||||
break
|
||||
|
||||
return handled
|
||||
return handled
|
||||
|
||||
def story_skip_with_option(self, drop=None, option=0):
|
||||
"""
|
||||
2023.09.14 Story options changed with big white options in the middle,
|
||||
Check STORY_SKIP_3 but click the original STORY_SKIP.
|
||||
Returns:
|
||||
[skipped, story_choice_clicked]
|
||||
"""
|
||||
if self.story_popup_timeout.started() and not self.story_popup_timeout.reached():
|
||||
if self.handle_popup_confirm('STORY_SKIP'):
|
||||
self.story_popup_timeout = Timer(10)
|
||||
self.interval_reset(STORY_SKIP_3)
|
||||
self.interval_reset(STORY_LETTERS_ONLY)
|
||||
return [True , False]
|
||||
if self._is_story_black():
|
||||
if self.appear_then_click(STORY_LETTERS_ONLY, offset=(20, 20), interval=2):
|
||||
self.story_popup_timeout.reset()
|
||||
return [True , False]
|
||||
if self._story_option_timer.reached() and self.appear(STORY_SKIP_3, offset=(20, 20), interval=0):
|
||||
options = self._story_option_buttons_2()
|
||||
options_count = len(options)
|
||||
logger.attr('Story_options', options_count)
|
||||
if not options_count:
|
||||
self._story_option_record = 0
|
||||
self._story_option_confirm.reset()
|
||||
elif options_count == self._story_option_record:
|
||||
if self._story_option_confirm.reached():
|
||||
try:
|
||||
select = options[option]
|
||||
_op = option
|
||||
except IndexError:
|
||||
select = options[0]
|
||||
_op = option
|
||||
self.device.click(select)
|
||||
self._story_option_timer.reset()
|
||||
self.story_popup_timeout.reset()
|
||||
self.interval_reset(STORY_SKIP_3)
|
||||
self.interval_reset(STORY_LETTERS_ONLY)
|
||||
self._story_option_record = 0
|
||||
self._story_option_confirm.reset()
|
||||
return [True , _op]
|
||||
else:
|
||||
self._story_option_record = options_count
|
||||
self._story_option_confirm.reset()
|
||||
if self.appear(STORY_SKIP_3, offset=(20, 20), interval=2):
|
||||
# Confirm it's story
|
||||
# When story play speed is Very Fast, Alas clicked story skip but story disappeared
|
||||
# This click will interrupt auto search
|
||||
self.interval_reset([STORY_SKIP_3])
|
||||
if self._story_confirm.reached():
|
||||
if drop:
|
||||
drop.handle_add(self, before=2)
|
||||
if self.config.STORY_ALLOW_SKIP:
|
||||
logger.info(f'{STORY_SKIP_3} -> {STORY_SKIP}')
|
||||
self.device.click(STORY_SKIP)
|
||||
else:
|
||||
logger.info(f'{STORY_SKIP_3} -> {OS_CLICK_SAFE_AREA}')
|
||||
self.device.click(OS_CLICK_SAFE_AREA)
|
||||
self._story_confirm.reset()
|
||||
self.story_popup_timeout.reset()
|
||||
return [True , False]
|
||||
else:
|
||||
self.interval_clear(STORY_SKIP_3)
|
||||
else:
|
||||
self._story_confirm.reset()
|
||||
if self.appear_then_click(STORY_CLOSE, offset=(10, 10), interval=2):
|
||||
self.story_popup_timeout.reset()
|
||||
return [True , False]
|
||||
|
||||
return [False , False]
|
||||
|
||||
@@ -941,3 +941,166 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
|
||||
return False
|
||||
self.device.click(nearest)
|
||||
self._nearest_object_click_timer.reset()
|
||||
|
||||
def _story_for_cross_zone_reset(self, drop=None):
|
||||
"""
|
||||
Wait until homo_loca stabled.
|
||||
DETECTION_BACKEND must be 'homography'.
|
||||
|
||||
Args:
|
||||
drop (DropImage):
|
||||
|
||||
Returns:
|
||||
str: Things that fleet met on its way,
|
||||
'event', 'search', 'akashi', 'combat',
|
||||
or their combinations like 'event_akashi', 'event_combat',
|
||||
or an empty string '' if nothing met.
|
||||
|
||||
Raises:
|
||||
MapWalkError: If unable to goto such grid.
|
||||
"""
|
||||
logger.hr('Wait until walk stable')
|
||||
record = None
|
||||
enemy_searching_appear = False
|
||||
self.device.screenshot_interval_set(0.35)
|
||||
confirm_timer = Timer(1.5, count=4)
|
||||
result = set()
|
||||
# Record story history to clear click record
|
||||
clicked_story = False
|
||||
stuck_timer = Timer(20, count=5).start()
|
||||
clicked_middle = 0
|
||||
for _ in self.loop(skip_first=False):
|
||||
# Map event
|
||||
|
||||
# If clicked Middle for twice, means it's a scanning device, which need to quit to save it.
|
||||
if clicked_middle >1:
|
||||
option = -1
|
||||
result.add ("siren_scanning_device")
|
||||
else:
|
||||
option = -2
|
||||
|
||||
event = self.story_skip_with_option(drop=drop, option=option)
|
||||
if event[1] == -2:
|
||||
clicked_middle += 1
|
||||
event = event[0]
|
||||
if event:
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
result.add('event')
|
||||
if event == 'story_skip':
|
||||
clicked_story = True
|
||||
elif event == 'map_get_items':
|
||||
# story_skip -> map_get_items means abyssal progress reward is received
|
||||
if clicked_story:
|
||||
logger.info('Got items from story')
|
||||
self.device.click_record_clear()
|
||||
clicked_story = False
|
||||
else:
|
||||
# Handled other events, clear history
|
||||
clicked_story = False
|
||||
continue
|
||||
if self.handle_retirement():
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
if self.handle_popup_confirm('WALK_UNTIL_STABLE'):
|
||||
# Confirm to submit items, in siren scanning devices
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
|
||||
# Accident click
|
||||
if self.is_in_globe():
|
||||
self.os_globe_goto_map()
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
if self.is_in_storage():
|
||||
self.storage_quit()
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
if self.is_in_os_mission():
|
||||
self.os_mission_quit()
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
if self.handle_os_game_tips():
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
if self.is_in_map_order():
|
||||
self.order_quit()
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
|
||||
# Combat
|
||||
if self.combat_appear():
|
||||
# Use ui_back() for testing, because there are too few abyssal loggers every month.
|
||||
# self.ui_back(check_button=self.is_in_map)
|
||||
self.combat(expected_end=self.is_in_map, fleet_index=self.fleet_show_index, save_get_items=drop)
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
result.add('event')
|
||||
continue
|
||||
|
||||
# Akashi shop
|
||||
if self.appear(PORT_SUPPLY_CHECK, offset=(20, 20)):
|
||||
self.interval_clear(PORT_SUPPLY_CHECK)
|
||||
self.handle_akashi_supply_buy(CLICK_SAFE_AREA)
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
result.add('akashi')
|
||||
continue
|
||||
|
||||
# A game bug that AUTO_SEARCH_REWARD from the last cleared zone popups
|
||||
if self.appear_then_click(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3):
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
|
||||
# Enemy searching
|
||||
if not enemy_searching_appear and self.enemy_searching_appear():
|
||||
enemy_searching_appear = True
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
continue
|
||||
else:
|
||||
if enemy_searching_appear:
|
||||
self.handle_enemy_flashing()
|
||||
self.device.sleep(0.3)
|
||||
logger.info('Enemy searching appeared.')
|
||||
enemy_searching_appear = False
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
result.add('search')
|
||||
if self.is_in_map():
|
||||
self.enemy_searching_color_initial()
|
||||
|
||||
# Arrive
|
||||
# Check colors, because screen goes black when something is unlocking.
|
||||
# A direct use of IN_MAP, basically `self.is_in_map() and IN_MAP.match_template_color()`
|
||||
if self.match_template_color(IN_MAP, offset=(200, 5)):
|
||||
self.update_os()
|
||||
current = self.view.backend.homo_loca
|
||||
logger.attr('homo_loca', current)
|
||||
# Max known distance is 4.48px, homo_loca between ( 56, 60) and ( 52, 58)
|
||||
if record is None or (current is not None and np.linalg.norm(np.subtract(current, record)) < 5.5):
|
||||
if confirm_timer.reached():
|
||||
break
|
||||
else:
|
||||
if stuck_timer.reached():
|
||||
logger.warning(f"homo_loca stuck at current view, try reset.")
|
||||
if self.fleet_reset_view():
|
||||
stuck_timer.reset()
|
||||
confirm_timer.reset()
|
||||
record = current
|
||||
else:
|
||||
confirm_timer.reset()
|
||||
stuck_timer.reset()
|
||||
|
||||
result = '_'.join(result)
|
||||
logger.info(f'Walk stabled, result: {result}')
|
||||
self.device.screenshot_interval_set()
|
||||
return result
|
||||
@@ -4,6 +4,7 @@ from sys import maxsize
|
||||
import inflection
|
||||
|
||||
import scheduler_watcher
|
||||
from encodings.punycode import selective_find
|
||||
from module.base.timer import Timer
|
||||
from module.combat_ui.assets import PAUSE
|
||||
from module.config.utils import get_os_reset_remain
|
||||
@@ -767,7 +768,13 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
|
||||
self._solved_map_event = set()
|
||||
self._solved_fleet_mechanism = False
|
||||
if self.config.full_config.OpsiCrossZoneScanningDeviceReset_Scheduler_Enable:
|
||||
self.map_rescan()
|
||||
if self.zone.hazard_level>=5:
|
||||
self.clear_question_for_cross_zone_reset(drop=drop)
|
||||
else:
|
||||
self.clear_question(drop=drop)
|
||||
self.map_rescan(rescan_mode=rescan, drop=drop)
|
||||
self.config.task_call("OpsiCrossZoneScanningDeviceReset")
|
||||
self.config.task_stop()
|
||||
else:
|
||||
if question:
|
||||
self.clear_question(drop=drop)
|
||||
@@ -956,3 +963,50 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
|
||||
logger.warning('Too many trial on map rescan, stop')
|
||||
self.fleet_set(self.config.OpsiFleet_Fleet)
|
||||
return False
|
||||
|
||||
def clear_question_for_cross_zone_reset(self, drop):
|
||||
"""
|
||||
Clear nearly (and 3 grids from above) question marks on radar.
|
||||
Try 3 times at max to avoid loop tries on 2 adjacent fleet mechanism.
|
||||
|
||||
Args:
|
||||
drop:
|
||||
|
||||
Returns:
|
||||
bool: If cleared
|
||||
"""
|
||||
logger.hr('Clear question', level=2)
|
||||
for _ in range(3):
|
||||
grid = self.radar.predict_question(self.device.image, in_port=self.zone.is_port)
|
||||
if grid is None:
|
||||
logger.info('No question mark above current fleet on this radar')
|
||||
return False
|
||||
|
||||
logger.info(f'Found question mark on {grid}')
|
||||
self.handle_info_bar()
|
||||
|
||||
self.update_os()
|
||||
self.view.predict()
|
||||
self.view.show()
|
||||
|
||||
grid = self.convert_radar_to_local(grid)
|
||||
self.device.click(grid)
|
||||
with self.config.temporary(STORY_ALLOW_SKIP=False):
|
||||
result = self._story_for_cross_zone_reset(drop=drop)
|
||||
if 'akashi' in result:
|
||||
self._solved_map_event.add('is_akashi')
|
||||
return True
|
||||
elif 'event' in result and grid.is_logging_tower:
|
||||
self._solved_map_event.add('is_logging_tower')
|
||||
return True
|
||||
elif 'event' in result and (grid.is_scanning_device or "siren_scanning_device" in result):
|
||||
self._solved_map_event.add('is_scanning_device')
|
||||
self.os_auto_search_run_exit_combat(drop=drop)
|
||||
return "is_scanning_device"
|
||||
else:
|
||||
logger.warning(f'Arrive question with unexpected result: {result}, expected: {grid.str}')
|
||||
continue
|
||||
|
||||
logger.warning('Failed to goto question mark after 5 trail, '
|
||||
'this might be 2 adjacent fleet mechanism, stopped')
|
||||
return False
|
||||
|
||||
@@ -273,3 +273,29 @@ class MapEventHandler(EnemySearchingHandler):
|
||||
changed = fleet_lock.set(state, main=self)
|
||||
|
||||
return changed
|
||||
|
||||
def handle_map_event_for_cross_zone_reset(self, drop=None, option=0):
|
||||
"""
|
||||
Args:
|
||||
drop (DropImage):
|
||||
option (int):
|
||||
|
||||
Returns:
|
||||
str: Event that handled
|
||||
"""
|
||||
if self.handle_map_get_items(drop=drop):
|
||||
return 'map_get_items'
|
||||
if self.handle_os_game_tips():
|
||||
return 'os_game_tips'
|
||||
if self.handle_map_archives(drop=drop):
|
||||
return 'map_archives'
|
||||
if self.handle_guild_popup_cancel():
|
||||
return 'guild_popup_cancel'
|
||||
if self.handle_ash_popup():
|
||||
return 'ash_popup'
|
||||
if self.handle_urgent_commission(drop=drop):
|
||||
return 'urgent_commission'
|
||||
if self.story_skip_with_option(option=option):
|
||||
return 'story_skip'
|
||||
|
||||
return ''
|
||||
Reference in New Issue
Block a user