Add: Do event story, not added to GUI yet

run with `python -m module.eventstory.eventstory`
This commit is contained in:
LmeSzinc 2025-01-02 00:38:16 +08:00
parent 72142c698b
commit f434784c6e
8 changed files with 150 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,11 @@
from module.base.button import Button
from module.base.template import Template
# This file was automatically generated by dev_tools/button_extract.py.
# Don't modify it manually.
BATTLE_MIDDLE = Button(area={'cn': (499, 346, 530, 375), 'en': (499, 346, 530, 375), 'jp': (499, 346, 530, 375), 'tw': (499, 346, 530, 375)}, color={'cn': (160, 160, 166), 'en': (160, 160, 166), 'jp': (160, 160, 166), 'tw': (160, 160, 166)}, button={'cn': (499, 346, 530, 375), 'en': (499, 346, 530, 375), 'jp': (499, 346, 530, 375), 'tw': (499, 346, 530, 375)}, file={'cn': './assets/cn/eventstory/BATTLE_MIDDLE.png', 'en': './assets/cn/eventstory/BATTLE_MIDDLE.png', 'jp': './assets/cn/eventstory/BATTLE_MIDDLE.png', 'tw': './assets/cn/eventstory/BATTLE_MIDDLE.png'})
STORY_FINISHED = Button(area={'cn': (913, 347, 940, 373), 'en': (913, 347, 940, 373), 'jp': (913, 347, 940, 373), 'tw': (913, 347, 940, 373)}, color={'cn': (204, 180, 83), 'en': (204, 180, 83), 'jp': (204, 180, 83), 'tw': (204, 180, 83)}, button={'cn': (913, 347, 940, 373), 'en': (913, 347, 940, 373), 'jp': (913, 347, 940, 373), 'tw': (913, 347, 940, 373)}, file={'cn': './assets/cn/eventstory/STORY_FINISHED.png', 'en': './assets/cn/eventstory/STORY_FINISHED.png', 'jp': './assets/cn/eventstory/STORY_FINISHED.png', 'tw': './assets/cn/eventstory/STORY_FINISHED.png'})
STORY_FIRST = Button(area={'cn': (89, 346, 116, 373), 'en': (89, 346, 116, 373), 'jp': (89, 346, 116, 373), 'tw': (89, 346, 116, 373)}, color={'cn': (199, 199, 203), 'en': (199, 199, 203), 'jp': (199, 199, 203), 'tw': (199, 199, 203)}, button={'cn': (89, 346, 116, 373), 'en': (89, 346, 116, 373), 'jp': (89, 346, 116, 373), 'tw': (89, 346, 116, 373)}, file={'cn': './assets/cn/eventstory/STORY_FIRST.png', 'en': './assets/cn/eventstory/STORY_FIRST.png', 'jp': './assets/cn/eventstory/STORY_FIRST.png', 'tw': './assets/cn/eventstory/STORY_FIRST.png'})
STORY_LAST = Button(area={'cn': (913, 347, 940, 374), 'en': (913, 347, 940, 374), 'jp': (913, 347, 940, 374), 'tw': (913, 347, 940, 374)}, color={'cn': (204, 204, 207), 'en': (204, 204, 207), 'jp': (204, 204, 207), 'tw': (204, 204, 207)}, button={'cn': (913, 347, 940, 374), 'en': (913, 347, 940, 374), 'jp': (913, 347, 940, 374), 'tw': (913, 347, 940, 374)}, file={'cn': './assets/cn/eventstory/STORY_LAST.png', 'en': './assets/cn/eventstory/STORY_LAST.png', 'jp': './assets/cn/eventstory/STORY_LAST.png', 'tw': './assets/cn/eventstory/STORY_LAST.png'})
STORY_MIDDLE = Button(area={'cn': (501, 346, 528, 373), 'en': (501, 346, 528, 373), 'jp': (501, 346, 528, 373), 'tw': (501, 346, 528, 373)}, color={'cn': (199, 199, 203), 'en': (199, 199, 203), 'jp': (199, 199, 203), 'tw': (199, 199, 203)}, button={'cn': (501, 346, 528, 373), 'en': (501, 346, 528, 373), 'jp': (501, 346, 528, 373), 'tw': (501, 346, 528, 373)}, file={'cn': './assets/cn/eventstory/STORY_MIDDLE.png', 'en': './assets/cn/eventstory/STORY_MIDDLE.png', 'jp': './assets/cn/eventstory/STORY_MIDDLE.png', 'tw': './assets/cn/eventstory/STORY_MIDDLE.png'})

View File

@ -0,0 +1,135 @@
from module.campaign.campaign_ui import CampaignUI
from module.combat.combat import Combat
from module.eventstory.assets import *
from module.handler.login import LoginHandler
from module.logger import logger
from module.ui.page import page_event
class EventStory(CampaignUI, Combat, LoginHandler):
def ui_goto_event_story(self):
"""
Returns:
str: 'finish', 'story', 'unknown'
"""
self.ui_ensure(page_event)
self.campaign_ensure_mode_20241219('story')
state = 'unknown'
for _ in range(3):
state = self.get_event_story_state()
logger.attr('EventStoryState', state)
if state == 'unknown':
# Story page get swiped, can't find story entrance
# Reset mode to reset swipe
self.campaign_ensure_mode_20241219('combat')
self.campaign_ensure_mode_20241219('story')
continue
else:
break
return state
def event_story(self, skip_first_screenshot=True):
"""
Args:
skip_first_screenshot:
Returns:
str: 'battle' or 'finish'
"""
logger.hr('Event story', level=1)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
if self.is_combat_executing() or self.is_combat_loading():
logger.info('run_story end at battle')
return 'battle'
if self.match_template_color(STORY_FINISHED, offset=(20, 20), interval=3):
logger.info('run_story end at STORY_FINISHED')
return 'finish'
# Story skip
if self.handle_story_skip():
self.interval_clear([STORY_MIDDLE, BATTLE_MIDDLE])
continue
if self.handle_get_items():
continue
# Clicks
if self.appear_then_click(STORY_FIRST, offset=(20, 20), interval=3):
self.story_skip_interval_clear()
self.popup_interval_clear()
self.device.click_record_clear()
continue
if self.match_template_color(STORY_LAST, offset=(20, 20), interval=3):
self.device.click(STORY_LAST)
self.story_skip_interval_clear()
self.popup_interval_clear()
self.device.click_record_clear()
continue
if self.appear_then_click(STORY_MIDDLE, offset=(20, 200), interval=3):
self.story_skip_interval_clear()
self.popup_interval_clear()
self.device.click_record_clear()
continue
if self.appear_then_click(BATTLE_MIDDLE, offset=(20, 200), interval=3):
self.story_skip_interval_clear()
self.popup_interval_clear()
self.device.click_record_clear()
continue
def run_event_story(self):
"""
Loop until event story finished
Handle story battles
"""
while 1:
state = self.ui_goto_event_story()
if state == 'finish':
break
result = self.event_story()
if result == 'battle':
# Kill game is considered cleared battles
# It's much faster than waiting event battles
logger.hr('Event Story Battle', level=2)
self.config.override(Error_HandleError=True)
self.app_stop()
self.app_start()
continue
if result == 'finish':
break
def get_event_story_state(self):
"""
Returns:
str: 'finish', 'story', 'unknown'
"""
if self.match_template_color(STORY_FINISHED, offset=(20, 20), interval=3):
return 'finish'
if self.appear_then_click(STORY_FIRST, offset=(20, 20), interval=3):
return 'story'
if self.match_template_color(STORY_LAST, offset=(20, 20), interval=3):
return 'story'
if self.appear_then_click(STORY_MIDDLE, offset=(20, 200), interval=3):
return 'story'
if self.appear_then_click(BATTLE_MIDDLE, offset=(20, 200), interval=3):
return 'story'
return 'unknown'
def run(self):
self.run_event_story()
# Scheduler
pass
if __name__ == '__main__':
self = EventStory('alas')
self.run()

View File

@ -447,6 +447,10 @@ class InfoHandler(ModuleBase):
return False
def story_skip_interval_clear(self):
self.interval_clear(STORY_SKIP_3)
self.interval_clear(STORY_LETTERS_ONLY)
def handle_story_skip(self, drop=None):
# Rerun events in clear mode but still have stories.
# No stories in clear mode