diff --git a/assets/cn/daily/reward/DAILY_QUEST_FULL.png b/assets/cn/daily/reward/DAILY_QUEST_FULL.png new file mode 100644 index 000000000..a8d642e8c Binary files /dev/null and b/assets/cn/daily/reward/DAILY_QUEST_FULL.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_1_CHECKED.png b/assets/share/daily/reward/ACTIVE_POINTS_1_CHECKED.png new file mode 100644 index 000000000..ae4ac5c8c Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_1_CHECKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_1_LOCKED.png b/assets/share/daily/reward/ACTIVE_POINTS_1_LOCKED.png new file mode 100644 index 000000000..1da771ad2 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_1_LOCKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_1_UNLOCK.png b/assets/share/daily/reward/ACTIVE_POINTS_1_UNLOCK.png new file mode 100644 index 000000000..ed04cbdb6 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_1_UNLOCK.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_2_CHECKED.png b/assets/share/daily/reward/ACTIVE_POINTS_2_CHECKED.png new file mode 100644 index 000000000..b0afd6335 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_2_CHECKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_2_LOCKED.png b/assets/share/daily/reward/ACTIVE_POINTS_2_LOCKED.png new file mode 100644 index 000000000..5a87f77ed Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_2_LOCKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_2_UNLOCK.png b/assets/share/daily/reward/ACTIVE_POINTS_2_UNLOCK.png new file mode 100644 index 000000000..4b0989806 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_2_UNLOCK.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_3_CHECKED.png b/assets/share/daily/reward/ACTIVE_POINTS_3_CHECKED.png new file mode 100644 index 000000000..64316a011 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_3_CHECKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_3_LOCKED.png b/assets/share/daily/reward/ACTIVE_POINTS_3_LOCKED.png new file mode 100644 index 000000000..45cbc0a47 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_3_LOCKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_3_UNLOCK.png b/assets/share/daily/reward/ACTIVE_POINTS_3_UNLOCK.png new file mode 100644 index 000000000..bb9885cd9 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_3_UNLOCK.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_4_CHECKED.png b/assets/share/daily/reward/ACTIVE_POINTS_4_CHECKED.png new file mode 100644 index 000000000..ba447dc11 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_4_CHECKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_4_LOCKED.png b/assets/share/daily/reward/ACTIVE_POINTS_4_LOCKED.png new file mode 100644 index 000000000..e9d4e393a Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_4_LOCKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_4_UNLOCK.png b/assets/share/daily/reward/ACTIVE_POINTS_4_UNLOCK.png new file mode 100644 index 000000000..d1051d801 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_4_UNLOCK.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_5_CHECKED.png b/assets/share/daily/reward/ACTIVE_POINTS_5_CHECKED.png new file mode 100644 index 000000000..8c06db22b Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_5_CHECKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_5_LOCKED.png b/assets/share/daily/reward/ACTIVE_POINTS_5_LOCKED.png new file mode 100644 index 000000000..00c8b04aa Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_5_LOCKED.png differ diff --git a/assets/share/daily/reward/ACTIVE_POINTS_5_UNLOCK.png b/assets/share/daily/reward/ACTIVE_POINTS_5_UNLOCK.png new file mode 100644 index 000000000..144a3fa06 Binary files /dev/null and b/assets/share/daily/reward/ACTIVE_POINTS_5_UNLOCK.png differ diff --git a/assets/share/daily/reward/DAILY_QUEST_GOTO.png b/assets/share/daily/reward/DAILY_QUEST_GOTO.png new file mode 100644 index 000000000..f06eb8897 Binary files /dev/null and b/assets/share/daily/reward/DAILY_QUEST_GOTO.png differ diff --git a/assets/share/daily/reward/DAILY_QUEST_LEFT_START.png b/assets/share/daily/reward/DAILY_QUEST_LEFT_START.png new file mode 100644 index 000000000..3942ab3ee Binary files /dev/null and b/assets/share/daily/reward/DAILY_QUEST_LEFT_START.png differ diff --git a/assets/share/daily/reward/DAILY_QUEST_REWARD.png b/assets/share/daily/reward/DAILY_QUEST_REWARD.png new file mode 100644 index 000000000..ebf5c2916 Binary files /dev/null and b/assets/share/daily/reward/DAILY_QUEST_REWARD.png differ diff --git a/assets/share/daily/reward/DAILY_QUEST_RIGHT_END.png b/assets/share/daily/reward/DAILY_QUEST_RIGHT_END.png new file mode 100644 index 000000000..8bfd42e74 Binary files /dev/null and b/assets/share/daily/reward/DAILY_QUEST_RIGHT_END.png differ diff --git a/assets/share/daily/reward/OCR_DAILY_QUEST.png b/assets/share/daily/reward/OCR_DAILY_QUEST.png new file mode 100644 index 000000000..e372958c5 Binary files /dev/null and b/assets/share/daily/reward/OCR_DAILY_QUEST.png differ diff --git a/dev_tools/keyword_extract.py b/dev_tools/keyword_extract.py index 6f1016737..0b0a27d24 100644 --- a/dev_tools/keyword_extract.py +++ b/dev_tools/keyword_extract.py @@ -1,4 +1,5 @@ import os +import re import typing as t from functools import cached_property @@ -54,6 +55,19 @@ class TextMap: return 0, '' +def replace_templates(text: str) -> str: + """ + Replace templates in data to make sure it equals to what is shown in game + + Examples: + replace_templates("Complete Echo of War #4 time(s)") + == "Complete Echo of War 1 time(s)" + """ + text = re.sub(r'#4', '1', text) + text = re.sub(r'', '', text) + return text + + class KeywordExtract: def __init__(self): self.text_map: dict[str, TextMap] = {lang: TextMap(lang) for lang in UI_LANGUAGES} @@ -90,10 +104,17 @@ class KeywordExtract: with gen.Object(key=en, object_class=keyword_class): gen.ObjectAttr(key='id', value=index + 1) for lang in UI_LANGUAGES: - gen.ObjectAttr(key=lang, value=self.find_keyword(keyword, lang=lang)[1]) + gen.ObjectAttr(key=lang, value=replace_templates(self.find_keyword(keyword, lang=lang)[1])) gen.write(output_file) + def load_daily_quests_keywords(self, lang='cn'): + daily_quest = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'DailyQuest.json')) + quest_data = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'QuestData.json')) + quests_hash = [quest_data[quest_id]["QuestTitle"]["Hash"] for quest_id in daily_quest] + quest_keywords = [self.text_map[lang].find(quest_hash)[1] for quest_hash in quests_hash] + self.load_keywords(quest_keywords, lang) + def generate(): ex = KeywordExtract() @@ -101,6 +122,8 @@ def generate(): ex.write_keywords(keyword_class='DungeonNav', output_file='./tasks/dungeon/keywords/nav.py') ex.load_keywords(['行动摘要', '生存索引', '每日实训']) ex.write_keywords(keyword_class='DungeonTab', output_file='./tasks/dungeon/keywords/tab.py') + ex.load_daily_quests_keywords() + ex.write_keywords(keyword_class='DailyQuest', output_file='./tasks/daily/keywords/daily_quest.py') if __name__ == '__main__': diff --git a/module/ocr/keyword.py b/module/ocr/keyword.py index 9ee2bcc2d..6b1243fac 100644 --- a/module/ocr/keyword.py +++ b/module/ocr/keyword.py @@ -6,7 +6,7 @@ from typing import ClassVar from module.exception import ScriptError import module.config.server as server -REGEX_PUNCTUATION = re.compile(r'[ ,.\'",。\-—/\\\n\t()()]') +REGEX_PUNCTUATION = re.compile(r'[ ,.\'",。\-—/\\\n\t()()「」『』【】]') def parse_name(n): @@ -15,8 +15,9 @@ def parse_name(n): def text_to_variable(text): - text = re.sub('[ \-]', '_', text) - text = re.sub('[()]', '', text) + text = re.sub(r'[ \-]', '_', text) + text = re.sub(r'[(),#]||\'s', '', text) + text = re.sub(r'[#_]?\d+(_times?)?', '', text) return text diff --git a/tasks/daily/assets/assets_daily_reward.py b/tasks/daily/assets/assets_daily_reward.py new file mode 100644 index 000000000..47cd579e6 --- /dev/null +++ b/tasks/daily/assets/assets_daily_reward.py @@ -0,0 +1,215 @@ +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 ``` + +ACTIVE_POINTS_1_CHECKED = ButtonWrapper( + name='ACTIVE_POINTS_1_CHECKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_1_CHECKED.png', + area=(377, 139, 424, 207), + search=(357, 119, 444, 227), + color=(223, 205, 185), + button=(377, 139, 424, 207), + ), +) +ACTIVE_POINTS_1_LOCKED = ButtonWrapper( + name='ACTIVE_POINTS_1_LOCKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_1_LOCKED.png', + area=(378, 141, 423, 185), + search=(358, 121, 443, 205), + color=(222, 222, 222), + button=(378, 141, 423, 185), + ), +) +ACTIVE_POINTS_1_UNLOCK = ButtonWrapper( + name='ACTIVE_POINTS_1_UNLOCK', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_1_UNLOCK.png', + area=(377, 141, 424, 185), + search=(357, 121, 444, 205), + color=(233, 178, 98), + button=(377, 141, 424, 185), + ), +) +ACTIVE_POINTS_2_CHECKED = ButtonWrapper( + name='ACTIVE_POINTS_2_CHECKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_2_CHECKED.png', + area=(560, 141, 606, 205), + search=(540, 121, 626, 225), + color=(221, 202, 180), + button=(560, 141, 606, 205), + ), +) +ACTIVE_POINTS_2_LOCKED = ButtonWrapper( + name='ACTIVE_POINTS_2_LOCKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_2_LOCKED.png', + area=(561, 141, 606, 185), + search=(541, 121, 626, 205), + color=(222, 222, 222), + button=(561, 141, 606, 185), + ), +) +ACTIVE_POINTS_2_UNLOCK = ButtonWrapper( + name='ACTIVE_POINTS_2_UNLOCK', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_2_UNLOCK.png', + area=(561, 141, 606, 185), + search=(541, 121, 626, 205), + color=(244, 192, 99), + button=(561, 141, 606, 185), + ), +) +ACTIVE_POINTS_3_CHECKED = ButtonWrapper( + name='ACTIVE_POINTS_3_CHECKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_3_CHECKED.png', + area=(743, 141, 788, 205), + search=(723, 121, 808, 225), + color=(221, 201, 179), + button=(743, 141, 788, 205), + ), +) +ACTIVE_POINTS_3_LOCKED = ButtonWrapper( + name='ACTIVE_POINTS_3_LOCKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_3_LOCKED.png', + area=(743, 141, 788, 185), + search=(723, 121, 808, 205), + color=(222, 222, 222), + button=(743, 141, 788, 185), + ), +) +ACTIVE_POINTS_3_UNLOCK = ButtonWrapper( + name='ACTIVE_POINTS_3_UNLOCK', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_3_UNLOCK.png', + area=(744, 141, 788, 185), + search=(724, 121, 808, 205), + color=(231, 176, 94), + button=(744, 141, 788, 185), + ), +) +ACTIVE_POINTS_4_CHECKED = ButtonWrapper( + name='ACTIVE_POINTS_4_CHECKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_4_CHECKED.png', + area=(925, 141, 970, 205), + search=(905, 121, 990, 225), + color=(221, 201, 179), + button=(925, 141, 970, 205), + ), +) +ACTIVE_POINTS_4_LOCKED = ButtonWrapper( + name='ACTIVE_POINTS_4_LOCKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_4_LOCKED.png', + area=(926, 141, 971, 185), + search=(906, 121, 991, 205), + color=(222, 222, 222), + button=(926, 141, 971, 185), + ), +) +ACTIVE_POINTS_4_UNLOCK = ButtonWrapper( + name='ACTIVE_POINTS_4_UNLOCK', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_4_UNLOCK.png', + area=(926, 141, 971, 185), + search=(906, 121, 991, 205), + color=(237, 182, 97), + button=(926, 141, 971, 185), + ), +) +ACTIVE_POINTS_5_CHECKED = ButtonWrapper( + name='ACTIVE_POINTS_5_CHECKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_5_CHECKED.png', + area=(1108, 141, 1154, 205), + search=(1088, 121, 1174, 225), + color=(221, 201, 179), + button=(1108, 141, 1154, 205), + ), +) +ACTIVE_POINTS_5_LOCKED = ButtonWrapper( + name='ACTIVE_POINTS_5_LOCKED', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_5_LOCKED.png', + area=(1108, 141, 1153, 185), + search=(1088, 121, 1173, 205), + color=(222, 222, 222), + button=(1108, 141, 1153, 185), + ), +) +ACTIVE_POINTS_5_UNLOCK = ButtonWrapper( + name='ACTIVE_POINTS_5_UNLOCK', + share=Button( + file='./assets/share/daily/reward/ACTIVE_POINTS_5_UNLOCK.png', + area=(1109, 141, 1154, 185), + search=(1089, 121, 1174, 205), + color=(237, 182, 96), + button=(1109, 141, 1154, 185), + ), +) +DAILY_QUEST_FULL = ButtonWrapper( + name='DAILY_QUEST_FULL', + cn=Button( + file='./assets/cn/daily/reward/DAILY_QUEST_FULL.png', + area=(159, 546, 298, 564), + search=(139, 526, 318, 584), + color=(128, 111, 80), + button=(159, 546, 298, 564), + ), +) +DAILY_QUEST_GOTO = ButtonWrapper( + name='DAILY_QUEST_GOTO', + share=Button( + file='./assets/share/daily/reward/DAILY_QUEST_GOTO.png', + area=(170, 544, 188, 563), + search=(150, 524, 208, 583), + color=(157, 156, 156), + button=(170, 544, 188, 563), + ), +) +DAILY_QUEST_LEFT_START = ButtonWrapper( + name='DAILY_QUEST_LEFT_START', + share=Button( + file='./assets/share/daily/reward/DAILY_QUEST_LEFT_START.png', + area=(1100, 187, 1135, 625), + search=(1080, 167, 1155, 645), + color=(214, 214, 213), + button=(1100, 187, 1135, 625), + ), +) +DAILY_QUEST_REWARD = ButtonWrapper( + name='DAILY_QUEST_REWARD', + share=Button( + file='./assets/share/daily/reward/DAILY_QUEST_REWARD.png', + area=(168, 544, 188, 564), + search=(148, 524, 208, 584), + color=(103, 83, 44), + button=(168, 544, 188, 564), + ), +) +DAILY_QUEST_RIGHT_END = ButtonWrapper( + name='DAILY_QUEST_RIGHT_END', + share=Button( + file='./assets/share/daily/reward/DAILY_QUEST_RIGHT_END.png', + area=(142, 207, 175, 669), + search=(122, 187, 195, 689), + color=(219, 219, 218), + button=(142, 207, 175, 669), + ), +) +OCR_DAILY_QUEST = ButtonWrapper( + name='OCR_DAILY_QUEST', + share=Button( + file='./assets/share/daily/reward/OCR_DAILY_QUEST.png', + area=(119, 232, 1165, 595), + search=(99, 212, 1185, 615), + color=(212, 210, 206), + button=(119, 232, 1165, 595), + ), +) diff --git a/tasks/daily/daily_quest.py b/tasks/daily/daily_quest.py new file mode 100644 index 000000000..e84fe94b3 --- /dev/null +++ b/tasks/daily/daily_quest.py @@ -0,0 +1,128 @@ +import numpy as np + +from module.base.timer import Timer +from module.logger import * +from module.ocr.ocr import Ocr, OcrResultButton +from tasks.daily.assets.assets_daily_reward import * +from tasks.daily.keywords import DailyQuest +from tasks.dungeon.keywords import KEYWORDS_DUNGEON_TAB +from tasks.dungeon.ui import DungeonUI + + +class DailyQuestOcr(Ocr): + def __init__(self, button: ButtonWrapper, lang=None, name=None): + super().__init__(button, lang, name) + + def after_process(self, result): + result = super().after_process(result) + if self.lang == 'ch': + result = result.replace("宇审", "宇宙") + result = result.replace("响J", "响」") + return result + + +class DailyQuestUI(DungeonUI): + def _ensure_position(self, direction: str, skip_first_screenshot=True): + interval = Timer(5) + if direction == 'left': + template = DAILY_QUEST_LEFT_START + elif direction == 'right': + template = DAILY_QUEST_RIGHT_END + else: + logger.warning(f'Unknown drag direction: {direction}') + return + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if self.appear(template): + logger.info(f"Ensure position: {direction}") + break + if interval.reached(): + self._daily_quests_swipe(direction) + interval.reset() + continue + + def _daily_quests_swipe(self, direction: str): + vector = np.random.uniform(0.65, 0.85) + if direction == 'left': + swipe_vector = (vector * OCR_DAILY_QUEST.width, 0) + elif direction == 'right': + swipe_vector = (-vector * OCR_DAILY_QUEST.width, 0) + else: + logger.warning(f'Unknown drag direction: {direction}') + return + self.device.swipe_vector(swipe_vector, box=OCR_DAILY_QUEST.button, + random_range=(-10, -10, 10, 10), name='DAILY_QUEST_DRAG') + + def _ocr_single_page(self) -> list[OcrResultButton]: + ocr = DailyQuestOcr(OCR_DAILY_QUEST) + ocr.merge_thres_y = 20 + results = ocr.matched_ocr(self.device.image, DailyQuest) + if len(results) < 4: + logger.warning(f"Recognition failed at {4 - len(results)} quests on one page") + return results + + def daily_quests_recognition(self): + logger.info("Recognizing daily quests") + self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Daily_Training) + self._ensure_position('left') + results = self._ocr_single_page() + self._ensure_position('right') + results += [result for result in self._ocr_single_page() if result not in results] + logger.info("Daily quests recognition complete") + return results + + def _get_quest_reward(self, skip_first_screenshot=True): + self._ensure_position('left') + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if self.appear(DAILY_QUEST_FULL) or self.appear(DAILY_QUEST_GOTO): + break + if self.appear_then_click(DAILY_QUEST_REWARD): + continue + + def _no_reward_to_get(self): + return ( + (self.appear(ACTIVE_POINTS_1_LOCKED) or self.appear(ACTIVE_POINTS_1_CHECKED)) + and (self.appear(ACTIVE_POINTS_2_LOCKED) or self.appear(ACTIVE_POINTS_2_CHECKED)) + and (self.appear(ACTIVE_POINTS_3_LOCKED) or self.appear(ACTIVE_POINTS_3_CHECKED)) + and (self.appear(ACTIVE_POINTS_4_LOCKED) or self.appear(ACTIVE_POINTS_4_CHECKED)) + and (self.appear(ACTIVE_POINTS_5_LOCKED) or self.appear(ACTIVE_POINTS_5_CHECKED)) + ) + + def _get_active_point_reward(self, skip_first_screenshot=True): + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if self._no_reward_to_get(): + break + if self.handle_reward(): + continue + if self.appear_then_click(ACTIVE_POINTS_1_UNLOCK): + continue + if self.appear_then_click(ACTIVE_POINTS_2_UNLOCK): + continue + if self.appear_then_click(ACTIVE_POINTS_3_UNLOCK): + continue + if self.appear_then_click(ACTIVE_POINTS_4_UNLOCK): + continue + if self.appear_then_click(ACTIVE_POINTS_5_UNLOCK): + continue + + def get_daily_rewards(self): + self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Daily_Training) + logger.info("Getting quest rewards") + self._get_quest_reward() + logger.info("Getting active point rewards") + self._get_active_point_reward() + logger.info("All daily reward got") diff --git a/tasks/daily/keywords/__init__.py b/tasks/daily/keywords/__init__.py new file mode 100644 index 000000000..937e9460e --- /dev/null +++ b/tasks/daily/keywords/__init__.py @@ -0,0 +1,2 @@ +import tasks.daily.keywords.daily_quest as KEYWORDS_DAILY_QUEST +from tasks.daily.keywords.classes import DailyQuest diff --git a/tasks/daily/keywords/classes.py b/tasks/daily/keywords/classes.py new file mode 100644 index 000000000..39ba677b0 --- /dev/null +++ b/tasks/daily/keywords/classes.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass +from typing import ClassVar + +from module.ocr.keyword import Keyword + + +@dataclass +class DailyQuest(Keyword): + instances: ClassVar = {} diff --git a/tasks/daily/keywords/daily_quest.py b/tasks/daily/keywords/daily_quest.py new file mode 100644 index 000000000..ddd226e43 --- /dev/null +++ b/tasks/daily/keywords/daily_quest.py @@ -0,0 +1,180 @@ +from .classes import DailyQuest + +# This file was auto-generated, do not modify it manually. To generate: +# ``` python -m dev_tools.keyword_extract ``` + +Complete_Daily_Mission = DailyQuest( + id=1, + cn='完成1个日常任务', + cht='完成1個每日任務', + en='Complete 1 Daily Mission', + jp='デイリークエストを1回クリアする', +) +Clear_Calyx_Golden = DailyQuest( + id=2, + cn='完成1次「拟造花萼(金)」', + cht='完成1次「擬造花萼(金)」', + en='Clear Calyx (Golden) 1 time(s)', + jp='「疑似花萼(金)」を1回クリアする', +) +Complete_Calyx_Crimson = DailyQuest( + id=3, + cn='完成1次「拟造花萼(赤)」', + cht='完成1次「擬造花萼(赤)」', + en='Complete Calyx (Crimson) 1 time', + jp='「疑似花萼(赤)」を1回クリアする', +) +Clear_Stagnant_Shadow = DailyQuest( + id=4, + cn='完成1次「凝滞虚影」', + cht='完成1次「凝滯虛影」', + en='Clear Stagnant Shadow 1 time(s)', + jp='「凝結虚影」を1回クリアする', +) +Clear_Cavern_of_Corrosion = DailyQuest( + id=5, + cn='完成1次「侵蚀隧洞」', + cht='完成1次「侵蝕隧洞」', + en='Clear Cavern of Corrosion 1 time(s)', + jp='「侵蝕トンネル」を1回クリアする', +) +In_a_single_battle_inflict_Weakness_Break_of_different_Types = DailyQuest( + id=6, + cn='单场战斗中,触发3种不同属性的弱点击破', + cht='單場戰鬥中,觸發3種不同屬性的弱點擊破', + en='In a single battle, inflict 3 Weakness Break of different Types', + jp='一度の戦闘で、異なる3種の属性の弱点撃破を発動する', +) +Inflict_Weakness_Break = DailyQuest( + id=7, + cn='累计触发弱点击破效果5次', + cht='累積觸發弱點擊破效果5次', + en='Inflict Weakness Break 5 times', + jp='累計で弱点撃破効果を5回発動する', +) +Defeat_a_total_of_enemies = DailyQuest( + id=8, + cn='累计消灭20个敌人', + cht='累積消滅20個敵人', + en='Defeat a total of 20 enemies', + jp='敵を累計で20体倒す', +) +Enter_combat_by_attacking_enemy_Weakness_and_win = DailyQuest( + id=9, + cn='利用弱点进入战斗并获胜3次', + cht='利用弱點進入戰鬥並獲勝3次', + en="Enter combat by attacking enemy's Weakness and win 3 times", + jp='弱点を攻撃して戦闘に入り、3回勝利する', +) +Use_Technique = DailyQuest( + id=10, + cn='累计施放2次秘技', + cht='累計施放2次秘技', + en='Use Technique 2 times', + jp='秘技を累計2回発動する', +) +Go_on_assignment = DailyQuest( + id=11, + cn='派遣1次委托', + cht='派遣1次委託', + en='Go on assignment 1 time', + jp='依頼に1回派遣する', +) +Take_photo = DailyQuest( + id=12, + cn='拍照1次', + cht='拍照1次', + en='Take 1 photo', + jp='1回撮影する', +) +Destroy_destructible_objects = DailyQuest( + id=13, + cn='累计击碎3个可破坏物', + cht='累計擊碎3個可破壞物', + en='Destroy 3 destructible objects', + jp='破壊できるオブジェクトを累計で3つ破壊する', +) +Complete_Forgotten_Hall = DailyQuest( + id=14, + cn='完成1次「忘却之庭」', + cht='完成1次「忘卻之庭」', + en='Complete Forgotten Hall 1 time', + jp='「忘却の庭」を1回クリアする', +) +Complete_Echo_of_War = DailyQuest( + id=15, + cn='完成1次「历战余响」', + cht='完成1次「歷戰餘響」', + en='Complete Echo of War 1 time(s)', + jp='「歴戦余韻」を1回クリアする', +) +Complete_stage_in_Simulated_Universe_Any_world = DailyQuest( + id=16, + cn='通关「模拟宇宙」(任意世界)的1个区域', + cht='完成「模擬宇宙」任意世界的1個區域', + en='Complete 1 stage in Simulated Universe (Any world)', + jp='「模擬宇宙」のエリアを1つクリアする(任意の世界)', +) +Obtain_victory_in_combat_with_support_characters = DailyQuest( + id=17, + cn='使用支援角色并获得战斗胜利1次', + cht='使用支援角色並獲得戰鬥勝利1次', + en='Obtain victory in combat with support characters 1 time', + jp='サポートキャラを使い、戦闘に1回勝利する', +) +Use_an_Ultimate_to_deal_the_final_blow = DailyQuest( + id=18, + cn='施放终结技造成制胜一击1次', + cht='施放終結技造成制勝一擊1次', + en='Use an Ultimate to deal the final blow 1 time', + jp='必殺技で最後の一撃を1回与える', +) +Level_up_any_character = DailyQuest( + id=19, + cn='将任意角色等级提升1次', + cht='將任意角色等級提升1次', + en='Level up any character 1 time', + jp='任意のキャラを1回レベルアップする', +) +Level_up_any_Light_Cone = DailyQuest( + id=20, + cn='将任意光锥等级提升1次', + cht='將任意光錐等級提升1次', + en='Level up any Light Cone 1 time', + jp='任意の光円錐を1回レベルアップする', +) +Level_up_any_Relic = DailyQuest( + id=21, + cn='将任意遗器等级提升1次', + cht='將任意遺器等級提升1次', + en='Level up any Relic 1 time', + jp='任意の遺物を1回レベルアップする', +) +Salvage_any_Relic = DailyQuest( + id=22, + cn='分解任意1件遗器', + cht='分解任意1件遺器', + en='Salvage any Relic', + jp='任意の遺物1つを分解する', +) +Synthesize_Consumable = DailyQuest( + id=23, + cn='合成1次消耗品', + cht='合成1次消耗品', + en='Synthesize Consumable 1 time', + jp='消耗品を1回合成する', +) +Synthesize_material = DailyQuest( + id=24, + cn='合成1次材料', + cht='合成1次素材', + en='Synthesize material 1 time', + jp='素材を1回合成する', +) +Use_Consumables = DailyQuest( + id=25, + cn='使用1件消耗品', + cht='使用1件消耗品', + en='Use Consumables 1 time', + jp='消耗品を1個使う', +)