Merge branch 'master' into dev
BIN
assets/cn/assignment/dispatch/ASSIGNMENT_START.2.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
assets/en/assignment/dispatch/ASSIGNMENT_START.2.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.2.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
@ -126,6 +126,7 @@ class GenerateAssignmentEventGroup(GenerateKeyword):
|
||||
|
||||
def iter_keywords(self) -> Iterable[dict]:
|
||||
yield dict(text_id=self.find_keyword('空间站特派', lang='cn')[0])
|
||||
yield dict(text_id=self.find_keyword('关于波提欧的一切…', lang='cn')[0])
|
||||
|
||||
|
||||
class GenerateAssignmentEventEntry(GenerateKeyword):
|
||||
|
@ -1113,7 +1113,7 @@
|
||||
"20": "20 Hours"
|
||||
},
|
||||
"Event": {
|
||||
"name": "Complete Event Assignments First",
|
||||
"name": "Complete Event Assignments",
|
||||
"help": ""
|
||||
},
|
||||
"Assignment": {
|
||||
|
@ -1113,7 +1113,7 @@
|
||||
"20": "20小时"
|
||||
},
|
||||
"Event": {
|
||||
"name": "有活动时优先做活动委托",
|
||||
"name": "有活动时参加活动委托",
|
||||
"help": ""
|
||||
},
|
||||
"Assignment": {
|
||||
|
@ -1113,7 +1113,7 @@
|
||||
"20": "20小時"
|
||||
},
|
||||
"Event": {
|
||||
"name": "有活動時優先做活動委託",
|
||||
"name": "有活動時參加活動委託",
|
||||
"help": ""
|
||||
},
|
||||
"Assignment": {
|
||||
|
@ -1,12 +1,11 @@
|
||||
from tasks.assignment.assets.assets_assignment_ui import (
|
||||
ALL_ABOUT_BOOTHILL_CHECK, ALL_ABOUT_BOOTHILL_CLICK,
|
||||
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
||||
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK, GROUP_SEARCH,
|
||||
SPACE_STATION_TASK_FORCE_CHECK, SPACE_STATION_TASK_FORCE_CLICK,
|
||||
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK
|
||||
)
|
||||
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK)
|
||||
|
||||
for group_button_wrapper in (
|
||||
SPACE_STATION_TASK_FORCE_CHECK, SPACE_STATION_TASK_FORCE_CLICK,
|
||||
ALL_ABOUT_BOOTHILL_CHECK, ALL_ABOUT_BOOTHILL_CLICK,
|
||||
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
||||
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK,
|
||||
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK,
|
||||
|
@ -5,30 +5,57 @@ from module.base.button import Button, ButtonWrapper
|
||||
|
||||
ASSIGNMENT_START = ButtonWrapper(
|
||||
name='ASSIGNMENT_START',
|
||||
cn=Button(
|
||||
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.png',
|
||||
area=(563, 341, 716, 376),
|
||||
search=(552, 299, 725, 412),
|
||||
color=(103, 92, 72),
|
||||
button=(563, 341, 716, 376),
|
||||
),
|
||||
en=Button(
|
||||
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.png',
|
||||
area=(693, 343, 831, 374),
|
||||
search=(669, 297, 831, 416),
|
||||
color=(95, 86, 67),
|
||||
button=(693, 343, 831, 374),
|
||||
),
|
||||
cn=[
|
||||
Button(
|
||||
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.png',
|
||||
area=(563, 341, 716, 376),
|
||||
search=(552, 299, 725, 412),
|
||||
color=(103, 92, 72),
|
||||
button=(563, 341, 716, 376),
|
||||
),
|
||||
Button(
|
||||
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.2.png',
|
||||
area=(579, 373, 702, 405),
|
||||
search=(552, 299, 725, 412),
|
||||
color=(84, 75, 59),
|
||||
button=(579, 373, 702, 405),
|
||||
),
|
||||
],
|
||||
en=[
|
||||
Button(
|
||||
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.png',
|
||||
area=(693, 343, 831, 374),
|
||||
search=(669, 297, 831, 416),
|
||||
color=(95, 86, 67),
|
||||
button=(693, 343, 831, 374),
|
||||
),
|
||||
Button(
|
||||
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.2.png',
|
||||
area=(676, 376, 787, 404),
|
||||
search=(669, 297, 831, 416),
|
||||
color=(80, 71, 56),
|
||||
button=(676, 376, 787, 404),
|
||||
),
|
||||
],
|
||||
)
|
||||
ASSIGNMENT_STARTED_CHECK = ButtonWrapper(
|
||||
name='ASSIGNMENT_STARTED_CHECK',
|
||||
share=Button(
|
||||
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.png',
|
||||
area=(542, 412, 1156, 422),
|
||||
search=(522, 392, 1176, 442),
|
||||
color=(232, 230, 226),
|
||||
button=(542, 412, 1156, 422),
|
||||
),
|
||||
share=[
|
||||
Button(
|
||||
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.png',
|
||||
area=(542, 412, 1156, 422),
|
||||
search=(522, 392, 1176, 442),
|
||||
color=(232, 230, 226),
|
||||
button=(542, 412, 1156, 422),
|
||||
),
|
||||
Button(
|
||||
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.2.png',
|
||||
area=(542, 412, 1156, 422),
|
||||
search=(522, 392, 1176, 442),
|
||||
color=(254, 244, 221),
|
||||
button=(542, 412, 1156, 422),
|
||||
),
|
||||
],
|
||||
)
|
||||
CHARACTER_1 = ButtonWrapper(
|
||||
name='CHARACTER_1',
|
||||
|
@ -3,6 +3,40 @@ from module.base.button import Button, ButtonWrapper
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.button_extract ```
|
||||
|
||||
ALL_ABOUT_BOOTHILL_CHECK = ButtonWrapper(
|
||||
name='ALL_ABOUT_BOOTHILL_CHECK',
|
||||
cn=Button(
|
||||
file='./assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png',
|
||||
area=(153, 98, 226, 118),
|
||||
search=(133, 78, 246, 138),
|
||||
color=(186, 180, 164),
|
||||
button=(153, 98, 226, 118),
|
||||
),
|
||||
en=Button(
|
||||
file='./assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png',
|
||||
area=(154, 89, 240, 129),
|
||||
search=(134, 69, 260, 149),
|
||||
color=(207, 201, 183),
|
||||
button=(154, 89, 240, 129),
|
||||
),
|
||||
)
|
||||
ALL_ABOUT_BOOTHILL_CLICK = ButtonWrapper(
|
||||
name='ALL_ABOUT_BOOTHILL_CLICK',
|
||||
cn=Button(
|
||||
file='./assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png',
|
||||
area=(153, 98, 227, 119),
|
||||
search=(133, 78, 247, 139),
|
||||
color=(80, 79, 77),
|
||||
button=(153, 98, 227, 119),
|
||||
),
|
||||
en=Button(
|
||||
file='./assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png',
|
||||
area=(154, 90, 241, 128),
|
||||
search=(134, 70, 261, 148),
|
||||
color=(59, 57, 56),
|
||||
button=(154, 90, 241, 128),
|
||||
),
|
||||
)
|
||||
CHARACTER_MATERIALS_CHECK = ButtonWrapper(
|
||||
name='CHARACTER_MATERIALS_CHECK',
|
||||
cn=Button(
|
||||
|
@ -2,7 +2,9 @@ from datetime import datetime
|
||||
|
||||
from module.logger import logger
|
||||
from tasks.assignment.claim import AssignmentClaim
|
||||
from tasks.assignment.keywords import (AssignmentEntry, AssignmentEventGroup, KEYWORDS_ASSIGNMENT_GROUP)
|
||||
from tasks.assignment.keywords import (KEYWORDS_ASSIGNMENT_GROUP,
|
||||
AssignmentEntry, AssignmentEventEntry,
|
||||
AssignmentEventGroup)
|
||||
from tasks.assignment.ui import AssignmentStatus
|
||||
from tasks.base.page import page_assignment, page_menu
|
||||
from tasks.daily.keywords import KEYWORDS_DAILY_QUEST
|
||||
@ -10,7 +12,7 @@ from tasks.daily.synthesize import SynthesizeUI
|
||||
|
||||
|
||||
class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
def run(self, assignments: list[AssignmentEntry] = None, duration: int = None, event_first: bool = None):
|
||||
def run(self, assignments: list[AssignmentEntry] = None, duration: int = None, join_event: bool = None):
|
||||
self.config.update_battle_pass_quests()
|
||||
self.config.update_daily_quests()
|
||||
|
||||
@ -26,25 +28,24 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
'There are duplicate assignments in config, check it out')
|
||||
if duration is None:
|
||||
duration = self.config.Assignment_Duration
|
||||
if event_first is None:
|
||||
event_first = self.config.Assignment_Event
|
||||
if join_event is None:
|
||||
join_event = self.config.Assignment_Event
|
||||
|
||||
self.dispatched = dict()
|
||||
self.has_new_dispatch = False
|
||||
self.ensure_scroll_top(page_menu)
|
||||
self.ui_ensure(page_assignment)
|
||||
self._wait_until_group_loaded()
|
||||
event_ongoing = next((
|
||||
g for g in self._iter_groups()
|
||||
if isinstance(g, AssignmentEventGroup)
|
||||
), None)
|
||||
if event_first and event_ongoing is not None:
|
||||
undispatched = assignments
|
||||
remain = self._check_all()
|
||||
remain = self._dispatch_event(remain)
|
||||
else:
|
||||
# Iterate in user-specified order, return undispatched ones
|
||||
undispatched = list(self._check_inlist(assignments, duration))
|
||||
remain = self._check_all()
|
||||
if join_event and event_ongoing is not None:
|
||||
if self._check_event():
|
||||
self._check_event()
|
||||
# Iterate in user-specified order, return undispatched ones
|
||||
undispatched = list(self._check_inlist(assignments, duration))
|
||||
remain = self._check_all()
|
||||
undispatched = [x for x in undispatched if x not in self.dispatched]
|
||||
# There are unchecked assignments
|
||||
if remain > 0:
|
||||
@ -89,13 +90,15 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
logger.hr('Assignment check inlist', level=1)
|
||||
logger.info(
|
||||
f'User specified assignments: {", ".join([x.name for x in assignments])}')
|
||||
_, remain, _ = self._limit_status
|
||||
remain = None
|
||||
for assignment in assignments:
|
||||
if assignment in self.dispatched:
|
||||
continue
|
||||
logger.hr('Assignment inlist', level=2)
|
||||
logger.info(f'Check assignment inlist: {assignment}')
|
||||
self.goto_entry(assignment)
|
||||
if remain is None:
|
||||
_, remain, _ = self._limit_status
|
||||
status = self._check_assignment_status()
|
||||
if status == AssignmentStatus.CLAIMABLE:
|
||||
self.claim(assignment, duration, should_redispatch=True)
|
||||
@ -121,10 +124,16 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
"""
|
||||
logger.hr('Assignment check all', level=1)
|
||||
current, remain, _ = self._limit_status
|
||||
len_dispatched = len([
|
||||
x for x in self.dispatched.keys()
|
||||
if not isinstance(x, AssignmentEventEntry)
|
||||
])
|
||||
# current = #Claimable + #Dispatched
|
||||
if current == len(self.dispatched):
|
||||
if current == len_dispatched:
|
||||
return remain
|
||||
for group in self._iter_groups():
|
||||
if isinstance(group, AssignmentEventGroup):
|
||||
continue
|
||||
self.goto_group(group)
|
||||
insight = False
|
||||
for assignment in self._iter_entries():
|
||||
@ -139,14 +148,15 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
current -= 1
|
||||
remain += 1
|
||||
insight = True # Order of entries change after claiming
|
||||
if current == len(self.dispatched):
|
||||
if current == len_dispatched:
|
||||
return remain
|
||||
continue
|
||||
if status == AssignmentStatus.DISPATCHED:
|
||||
self.dispatched[assignment] = datetime.now() + \
|
||||
self._get_assignment_time()
|
||||
len_dispatched += 1
|
||||
insight = False # Order of entries does not change here
|
||||
if current == len(self.dispatched):
|
||||
if current == len_dispatched:
|
||||
return remain
|
||||
continue
|
||||
break
|
||||
@ -183,10 +193,9 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
if remain <= 0:
|
||||
return
|
||||
|
||||
def _dispatch_event(self, remain: int):
|
||||
if remain <= 0:
|
||||
return remain
|
||||
logger.hr('Assignment dispatch event', level=1)
|
||||
def _check_event(self):
|
||||
logger.hr('Assignment check event', level=1)
|
||||
claimed = False
|
||||
for group in self._iter_groups():
|
||||
if not isinstance(group, AssignmentEventGroup):
|
||||
continue
|
||||
@ -199,12 +208,14 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
# Order of entries does not change during iteration
|
||||
self.goto_entry(assignment, insight=False)
|
||||
status = self._check_assignment_status()
|
||||
# Should only be dispatchable or locked after _check_all
|
||||
if status == AssignmentStatus.LOCKED:
|
||||
continue
|
||||
if status == AssignmentStatus.CLAIMABLE:
|
||||
self.claim(assignment, None, should_redispatch=False)
|
||||
claimed = True
|
||||
if status == AssignmentStatus.DISPATCHABLE:
|
||||
self.dispatch(assignment, None)
|
||||
remain -= 1
|
||||
if remain <= 0:
|
||||
return remain
|
||||
continue
|
||||
break
|
||||
return remain
|
||||
if status == AssignmentStatus.DISPATCHED:
|
||||
self.dispatched[assignment] = datetime.now() + \
|
||||
self._get_assignment_time()
|
||||
return claimed
|
||||
|
@ -30,7 +30,7 @@ KEYWORDS_ASSIGNMENT_GROUP.Synthesis_Materials.entries = (
|
||||
KEYWORDS_ASSIGNMENT_ENTRY.Fragments_of_Illusory_Dreams,
|
||||
KEYWORDS_ASSIGNMENT_ENTRY.Scalpel_and_Screwdriver,
|
||||
)
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force.entries = (
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill.entries = (
|
||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Activate_Genetic_Samples,
|
||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Reproduce_Experimental_Data,
|
||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Burned_Warehouse,
|
||||
@ -60,7 +60,7 @@ for group in (
|
||||
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
||||
KEYWORDS_ASSIGNMENT_GROUP.EXP_Materials_Credits,
|
||||
KEYWORDS_ASSIGNMENT_GROUP.Synthesis_Materials,
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill,
|
||||
):
|
||||
for entry in group.entries:
|
||||
assert entry.group is None
|
||||
|
@ -12,3 +12,12 @@ Space_Station_Task_Force = AssignmentEventGroup(
|
||||
jp='ステーション特派',
|
||||
es='Comando de la Estación Espacial',
|
||||
)
|
||||
All_About_Boothill = AssignmentEventGroup(
|
||||
id=2,
|
||||
name='All_About_Boothill',
|
||||
cn='关于波提欧的一切…',
|
||||
cht='關於波提歐的一切……',
|
||||
en='All About Boothill...',
|
||||
jp='ブートヒルに関するすべて…',
|
||||
es='Todo sobre Boothill...',
|
||||
)
|
||||
|
@ -8,13 +8,14 @@ from module.base.timer import Timer
|
||||
from module.exception import ScriptError
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import DigitCounter, Duration, Ocr
|
||||
from tasks.dungeon.ui import DungeonTabSwitch as Switch
|
||||
from module.ui.draggable_list import DraggableList
|
||||
from tasks.assignment.assets.assets_assignment_claim import CLAIM
|
||||
from tasks.assignment.assets.assets_assignment_dispatch import EMPTY_SLOT
|
||||
from tasks.assignment.assets.assets_assignment_ui import *
|
||||
from tasks.assignment.keywords import *
|
||||
from tasks.base.assets.assets_base_page import ASSIGNMENT_CHECK
|
||||
from tasks.base.ui import UI
|
||||
from tasks.dungeon.ui import DungeonTabSwitch as Switch
|
||||
|
||||
|
||||
class AssignmentStatus(Enum):
|
||||
@ -31,17 +32,20 @@ class AssignmentOcr(Ocr):
|
||||
|
||||
OCR_REPLACE = {
|
||||
'cn': [
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Winter_Soldiers.name, '[黑]冬的战士们'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Born_to_Obey.name, '[牛]而服从'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Root_Out_the_Turpitude.name,
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Winter_Soldiers, '[黑]冬的战士们'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Born_to_Obey, '[牛]而服从'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Root_Out_the_Turpitude,
|
||||
'根除恶[擎薯尊掌鞋]?'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Akashic_Records.name, '阿[未][夏复]记录'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Legend_of_the_Puppet_Master.name, '^师传说'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.The_Wages_of_Humanity.name, '[赠]养人类'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Akashic_Records, '阿[未][夏复]记录'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.Legend_of_the_Puppet_Master, '^师传说'),
|
||||
(KEYWORDS_ASSIGNMENT_ENTRY.The_Wages_of_Humanity, '[赠]养人类'),
|
||||
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Car_Thief, '.*的偷车贼.*'),
|
||||
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Synesthesia_Beacon_Function_Iteration, '联觉信标功能[送]代'),
|
||||
],
|
||||
'en': [
|
||||
# (KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Food_Improvement_Plan.name,
|
||||
# 'Food\s*[I]{0}mprovement Plan'),
|
||||
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Car_Thief, '.*Car Thief.*'),
|
||||
]
|
||||
}
|
||||
|
||||
@ -50,7 +54,10 @@ class AssignmentOcr(Ocr):
|
||||
rules = AssignmentOcr.OCR_REPLACE.get(self.lang)
|
||||
if rules is None:
|
||||
return None
|
||||
return re.compile('|'.join('(?P<%s>%s)' % pair for pair in rules))
|
||||
return re.compile('|'.join(
|
||||
f'(?P<{kw.name}>{pat})'
|
||||
for kw, pat in rules
|
||||
))
|
||||
|
||||
def filter_detected(self, result) -> bool:
|
||||
# Drop duration rows
|
||||
@ -78,17 +85,17 @@ class AssignmentOcr(Ocr):
|
||||
matched = self.ocr_regex.fullmatch(result)
|
||||
if matched is None:
|
||||
return result
|
||||
keyword_lang = self.lang
|
||||
for keyword_class in (
|
||||
KEYWORDS_ASSIGNMENT_ENTRY,
|
||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY,
|
||||
):
|
||||
matched = getattr(keyword_class, matched.lastgroup, None)
|
||||
if matched is not None:
|
||||
kw = getattr(keyword_class, matched.lastgroup, None)
|
||||
if kw is not None:
|
||||
matched = kw
|
||||
break
|
||||
else:
|
||||
raise ScriptError(f'No keyword found for {matched.lastgroup}')
|
||||
matched = getattr(matched, keyword_lang)
|
||||
matched = getattr(matched, self.lang)
|
||||
logger.attr(name=f'{self.name} after_process',
|
||||
text=f'{result} -> {matched}')
|
||||
return matched
|
||||
@ -98,10 +105,15 @@ ASSIGNMENT_GROUP_SWITCH = Switch(
|
||||
'AssignmentGroupSwitch',
|
||||
is_selector=True
|
||||
)
|
||||
# ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||
# KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
||||
# check_button=SPACE_STATION_TASK_FORCE_CHECK,
|
||||
# click_button=SPACE_STATION_TASK_FORCE_CLICK
|
||||
# )
|
||||
ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
||||
check_button=SPACE_STATION_TASK_FORCE_CHECK,
|
||||
click_button=SPACE_STATION_TASK_FORCE_CLICK
|
||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill,
|
||||
check_button=ALL_ABOUT_BOOTHILL_CHECK,
|
||||
click_button=ALL_ABOUT_BOOTHILL_CLICK
|
||||
)
|
||||
ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
||||
@ -174,7 +186,7 @@ class AssignmentUI(UI):
|
||||
|
||||
def _wait_until_group_loaded(self):
|
||||
skip_first_screenshot = True
|
||||
timeout = Timer(2, count=3).start()
|
||||
timeout = Timer(3, count=3).start()
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
@ -201,13 +213,17 @@ class AssignmentUI(UI):
|
||||
if timeout.reached():
|
||||
logger.warning('Wait entry loaded timeout')
|
||||
break
|
||||
if self.image_color_count(ENTRY_LOADED, (35, 35, 35), count=800):
|
||||
if self.appear(ASSIGNMENT_CHECK) and \
|
||||
self.image_color_count(ENTRY_LOADED, (35, 35, 35), count=800):
|
||||
logger.info('Entry loaded')
|
||||
break
|
||||
|
||||
@property
|
||||
def _limit_status(self) -> tuple[int, int, int]:
|
||||
self.device.screenshot()
|
||||
if isinstance(ASSIGNMENT_GROUP_SWITCH.get(self), AssignmentEventGroup):
|
||||
ASSIGNMENT_GROUP_SWITCH.set(
|
||||
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials, self)
|
||||
current, remain, total = DigitCounter(
|
||||
OCR_ASSIGNMENT_LIMIT).ocr_single_line(self.device.image)
|
||||
if total and current <= total:
|
||||
|
@ -156,11 +156,6 @@ class CombatSupport(UI):
|
||||
self.interval_reset(POPUP_CANCEL)
|
||||
continue
|
||||
if self.appear(COMBAT_SUPPORT_LIST, interval=2):
|
||||
scroll = AdaptiveScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area,
|
||||
name=COMBAT_SUPPORT_LIST_SCROLL.name)
|
||||
if not scroll.appear(main=self):
|
||||
self.interval_clear(COMBAT_SUPPORT_LIST)
|
||||
continue
|
||||
if not selected_support and support_character_name != "FirstCharacter":
|
||||
self._search_support(support_character_name) # Search support
|
||||
selected_support = True
|
||||
|
@ -591,7 +591,9 @@ class DungeonUI(DungeonState):
|
||||
break
|
||||
|
||||
# Additional
|
||||
pass
|
||||
# Popup that confirm character switch
|
||||
if self.handle_popup_confirm('DUNGEON_ENTER'):
|
||||
continue
|
||||
|
||||
# Click teleport
|
||||
if self.appear(page_guide.check_button, interval=1):
|
||||
|