diff --git a/assets/share/rogue/blessing/BLESSING_ENFORCE.png b/assets/share/rogue/blessing/BLESSING_ENFORCE.png new file mode 100644 index 000000000..6d2ff2d6a Binary files /dev/null and b/assets/share/rogue/blessing/BLESSING_ENFORCE.png differ diff --git a/assets/share/rogue/blessing/BLESSING_RESET.png b/assets/share/rogue/blessing/BLESSING_RESET.png new file mode 100644 index 000000000..fafb39edf Binary files /dev/null and b/assets/share/rogue/blessing/BLESSING_RESET.png differ diff --git a/assets/share/rogue/blessing/BLESSING_STABLE_FLAG.png b/assets/share/rogue/blessing/BLESSING_STABLE_FLAG.png new file mode 100644 index 000000000..8f4d6ca80 Binary files /dev/null and b/assets/share/rogue/blessing/BLESSING_STABLE_FLAG.png differ diff --git a/assets/share/rogue/blessing/CONFIRM.png b/assets/share/rogue/blessing/CONFIRM.png new file mode 100644 index 000000000..b54b5345c Binary files /dev/null and b/assets/share/rogue/blessing/CONFIRM.png differ diff --git a/assets/share/rogue/blessing/OCR_RESET_COUNT.png b/assets/share/rogue/blessing/OCR_RESET_COUNT.png new file mode 100644 index 000000000..55de9d3ed Binary files /dev/null and b/assets/share/rogue/blessing/OCR_RESET_COUNT.png differ diff --git a/assets/share/rogue/blessing/OCR_ROGUE_BUFF.png b/assets/share/rogue/blessing/OCR_ROGUE_BUFF.png new file mode 100644 index 000000000..989c8ea06 Binary files /dev/null and b/assets/share/rogue/blessing/OCR_ROGUE_BUFF.png differ diff --git a/assets/share/rogue/ui/PAGE_CHOOSE_BUFF.png b/assets/share/rogue/ui/PAGE_CHOOSE_BUFF.png new file mode 100644 index 000000000..dd8e36da0 Binary files /dev/null and b/assets/share/rogue/ui/PAGE_CHOOSE_BUFF.png differ diff --git a/assets/share/rogue/ui/PAGE_CHOOSE_MIRACLE.png b/assets/share/rogue/ui/PAGE_CHOOSE_MIRACLE.png new file mode 100644 index 000000000..1af80558f Binary files /dev/null and b/assets/share/rogue/ui/PAGE_CHOOSE_MIRACLE.png differ diff --git a/config/template.json b/config/template.json index fbe284d7d..020892a60 100644 --- a/config/template.json +++ b/config/template.json @@ -77,5 +77,20 @@ "Name_3": "The_Invisible_Hand", "Name_4": "Nine_Billion_Names" } + }, + "Rogue": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "Rogue", + "ServerUpdate": "04:00" + }, + "Rogue": { + "Path": "The Hunt", + "PresetResonanceFilter": "preset-1", + "CustomResonanceFilter": "回响构音:均晶转变 > 回响构音:零维强化\n> 回响构音:第二次初恋 > 回响构音:体验的富翁\n> 回响构音:局外人 > 回响构音:怀疑的四重根\n> 回响构音:诸法无我 > 回响构音:诸行无常\n> 回响构音:射不主皮 > 回响构音:柘弓危矢\n> 回响构音:激变变星 > 回响构音:极端氦闪\n> 回响构音:末日狂欢 > 回响构音:树苗长高舞", + "PresetBlessingFilter": "preset-1", + "CustomBlessingFilter": "巡猎-3 > 《冠军晚餐·猫的摇篮》 > 丰饶众生,一法界心 > 毁灭-3 \n> 火堆外的夜 > 巡猎-2 > 毁灭-2 > 巡猎 > reset > random" + } } } \ No newline at end of file diff --git a/dev_tools/keyword_extract.py b/dev_tools/keyword_extract.py index 82787c90b..fcd32928a 100644 --- a/dev_tools/keyword_extract.py +++ b/dev_tools/keyword_extract.py @@ -13,8 +13,8 @@ UI_LANGUAGES = ['cn', 'cht', 'en', 'jp'] def text_to_variable(text): text = re.sub("'s |s' ", '_', text) - text = re.sub('[ \-—:\'/•]+', '_', text) - text = re.sub(r'[(),#"?]|', '', text) + text = re.sub('[ \-—:\'/•.]+', '_', text) + text = re.sub(r'[(),#"?!&]|', '', text) # text = re.sub(r'[#_]?\d+(_times?)?', '', text) return text @@ -30,6 +30,12 @@ def dungeon_name(name: str) -> str: return name +def blessing_name(name: str) -> str: + name = text_to_variable(name) + name = re.sub(r'^\d', lambda match: f"_{match.group(0)}", name) + return name + + nickname_count = 0 @@ -147,7 +153,8 @@ class KeywordExtract: keyword_class, output_file: str = '', text_convert=text_to_variable, - generator: CodeGenerator = None + generator: CodeGenerator = None, + extra_attrs: dict[str, dict] = None ): """ Args: @@ -155,6 +162,7 @@ class KeywordExtract: output_file: text_convert: generator: Reuse an existing code generator + extra_attrs: Extra attributes write in keywords """ if generator is None: gen = CodeGenerator() @@ -166,6 +174,12 @@ class KeywordExtract: gen = generator last_id = getattr(gen, 'last_id', 0) + if extra_attrs: + keyword_num = len(self.keywords_id) + for attr_key, attr_value in extra_attrs.items(): + if len(attr_value) != keyword_num: + print(f"Extra attribute {attr_key} does not match the size of keywords") + return for index, keyword in enumerate(self.keywords_id): _, name = self.find_keyword(keyword, lang='en') name = text_convert(replace_templates(name)) @@ -174,6 +188,9 @@ class KeywordExtract: gen.ObjectAttr(key='name', value=name) for lang in UI_LANGUAGES: gen.ObjectAttr(key=lang, value=replace_templates(self.find_keyword(keyword, lang=lang)[1])) + if extra_attrs: + for attr_key, attr_value in extra_attrs.items(): + gen.ObjectAttr(key=attr_key, value=attr_value[keyword]) gen.last_id = index + last_id + 1 if output_file: @@ -279,6 +296,41 @@ class KeywordExtract: self.load_quests(quests) self.write_keywords(keyword_class='BattlePassQuest', output_file='./tasks/battle_pass/keywords/quest.py') + def generate_rogue_buff(self): + # paths + aeons = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'RogueAeon.json')) + aeons_hash = [deep_get(aeon, '1.RogueAeonPathName2.Hash') for aeon in aeons.values()] + self.keywords_id = aeons_hash + self.write_keywords(keyword_class='RoguePath', output_file='./tasks/rogue/keywords/path.py') + + # blessings + blessings_info = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'RogueBuff.json')) + blessings_name_map = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'RogueMazeBuff.json')) + blessings_id = [deep_get(blessing, '1.MazeBuffID') for blessing in blessings_info.values() + if not deep_get(blessing, '1.AeonID')][1:] + resonances_id = [deep_get(blessing, '1.MazeBuffID') for blessing in blessings_info.values() + if deep_get(blessing, '1.AeonID')] + + def get_blessing_infos(id_list): + blessings_hash = [deep_get(blessings_name_map, f"{blessing_id}.1.BuffName.Hash") + for blessing_id in id_list] + blessings_path_id = {blessing_hash: int(deep_get(blessings_info, f'{blessing_id}.1.RogueBuffType')) - 119 + # 119 is the magic number make type match with path in keyword above + for blessing_hash, blessing_id in zip(blessings_hash, id_list)} + blessings_rarity = {blessing_hash: deep_get(blessings_info, f'{blessing_id}.1.RogueBuffRarity') + for blessing_hash, blessing_id in zip(blessings_hash, id_list)} + return blessings_hash, {'path_id': blessings_path_id, 'rarity': blessings_rarity} + + hash_list, extra_attrs = get_blessing_infos(blessings_id) + self.keywords_id = hash_list + self.write_keywords(keyword_class='RogueBlessing', output_file='./tasks/rogue/keywords/blessing.py', + text_convert=blessing_name, extra_attrs=extra_attrs) + + hash_list, extra_attrs = get_blessing_infos(resonances_id) + self.keywords_id = hash_list + self.write_keywords(keyword_class='RogueResonance', output_file='./tasks/rogue/keywords/resonance.py', + text_convert=blessing_name, extra_attrs=extra_attrs) + def generate(self): self.load_keywords(['模拟宇宙', '拟造花萼(金)', '拟造花萼(赤)', '凝滞虚影', '侵蚀隧洞', '历战余响', '忘却之庭']) self.write_keywords(keyword_class='DungeonNav', output_file='./tasks/dungeon/keywords/nav.py') @@ -308,6 +360,7 @@ class KeywordExtract: self.load_keywords(['养成材料', '光锥', '遗器', '其他材料', '消耗品', '任务', '贵重物']) self.write_keywords(keyword_class='ItemTab', text_convert=lambda name: name.replace(' ', ''), output_file='./tasks/item/keywords/tab.py') + self.generate_rogue_buff() if __name__ == '__main__': diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 59cb81b0a..00f1bf30c 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -432,5 +432,67 @@ ] } } + }, + "Rogue": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "Rogue", + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Rogue": { + "Path": { + "type": "select", + "value": "The Hunt", + "option": [ + "Preservation", + "Remembrance", + "Nihility", + "Abundance", + "The Hunt", + "Destruction", + "Elation" + ] + }, + "PresetResonanceFilter": { + "type": "select", + "value": "preset-1", + "option": [ + "preset-1", + "custom" + ] + }, + "CustomResonanceFilter": { + "type": "textarea", + "value": "回响构音:均晶转变 > 回响构音:零维强化\n> 回响构音:第二次初恋 > 回响构音:体验的富翁\n> 回响构音:局外人 > 回响构音:怀疑的四重根\n> 回响构音:诸法无我 > 回响构音:诸行无常\n> 回响构音:射不主皮 > 回响构音:柘弓危矢\n> 回响构音:激变变星 > 回响构音:极端氦闪\n> 回响构音:末日狂欢 > 回响构音:树苗长高舞" + }, + "PresetBlessingFilter": { + "type": "select", + "value": "preset-1", + "option": [ + "preset-1", + "custom" + ] + }, + "CustomBlessingFilter": { + "type": "textarea", + "value": "巡猎-3 > 《冠军晚餐·猫的摇篮》 > 丰饶众生,一法界心 > 毁灭-3 \n> 火堆外的夜 > 巡猎-2 > 毁灭-2 > 巡猎 > reset > random" + } + } } } \ No newline at end of file diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 8eb6ba1ce..cacdb6523 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -73,7 +73,7 @@ Dungeon: Name: # Options will be injected in config updater value: Calyx_Golden_Treasures - option: [Calyx_Golden_Treasures, ] + option: [ Calyx_Golden_Treasures, ] NameAtDoubleCalyx: # Options will be injected in config updater value: Calyx_Golden_Treasures @@ -83,26 +83,50 @@ Dungeon: option: [ 1, 2, 3, 4, 5, 6 ] Support: value: when_daily - option: [do_not_use, always_use, when_daily] + option: [ do_not_use, always_use, when_daily ] SupportCharacter: # Options will be injected in config updater value: FirstCharacter - option: [FirstCharacter, ] + option: [ FirstCharacter, ] Assignment: Duration: value: 20 - option: [4, 8, 12, 20] + option: [ 4, 8, 12, 20 ] # Options in Name_x will be injected in config updater Name_1: value: Nameless_Land_Nameless_People - option: [Nameless_Land_Nameless_People, ] + option: [ Nameless_Land_Nameless_People, ] Name_2: value: Akashic_Records - option: [Nameless_Land_Nameless_People, ] + option: [ Nameless_Land_Nameless_People, ] Name_3: value: The_Invisible_Hand - option: [Nameless_Land_Nameless_People, ] + option: [ Nameless_Land_Nameless_People, ] Name_4: value: Nine_Billion_Names - option: [Nameless_Land_Nameless_People, ] \ No newline at end of file + option: [ Nameless_Land_Nameless_People, ] + +# ==================== Rogue ==================== + +Rogue: + Path: + value: The Hunt + option: [ Preservation, Remembrance, Nihility, Abundance, The Hunt, Destruction, Elation ] + PresetResonanceFilter: + value: preset-1 + option: [ preset-1, custom ] + CustomResonanceFilter: |- + 回响构音:均晶转变 > 回响构音:零维强化 + > 回响构音:第二次初恋 > 回响构音:体验的富翁 + > 回响构音:局外人 > 回响构音:怀疑的四重根 + > 回响构音:诸法无我 > 回响构音:诸行无常 + > 回响构音:射不主皮 > 回响构音:柘弓危矢 + > 回响构音:激变变星 > 回响构音:极端氦闪 + > 回响构音:末日狂欢 > 回响构音:树苗长高舞 + PresetBlessingFilter: + value: preset-1 + option: [ preset-1, custom ] + CustomBlessingFilter: |- + 巡猎-3 > 《冠军晚餐·猫的摇篮》 > 丰饶众生,一法界心 > 毁灭-3 + > 火堆外的夜 > 巡猎-2 > 毁灭-2 > 巡猎 > reset > random diff --git a/module/config/argument/menu.json b/module/config/argument/menu.json index e164e6947..cd12b2b03 100644 --- a/module/config/argument/menu.json +++ b/module/config/argument/menu.json @@ -16,5 +16,12 @@ "BattlePass", "Assignment" ] + }, + "Rogue": { + "menu": "list", + "page": "setting", + "tasks": [ + "Rogue" + ] } } \ No newline at end of file diff --git a/module/config/argument/task.yaml b/module/config/argument/task.yaml index 6edcdb991..2563e53d5 100644 --- a/module/config/argument/task.yaml +++ b/module/config/argument/task.yaml @@ -32,3 +32,13 @@ Daily: Assignment: - Scheduler - Assignment + +# ==================== Rogue ==================== + +Rogue: + menu: 'list' + page: 'setting' + tasks: + Rogue: + - Scheduler + - Rogue diff --git a/module/config/config_generated.py b/module/config/config_generated.py index 05646fbf2..895668b75 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -51,3 +51,10 @@ class GeneratedConfig: Assignment_Name_2 = 'Akashic_Records' # Nine_Billion_Names, Destruction_of_the_Destroyer, Winter_Soldiers, Born_to_Obey, Root_Out_the_Turpitude, Fire_Lord_Inflames_Blades_of_War, Nameless_Land_Nameless_People, Akashic_Records, The_Invisible_Hand, Abandoned_and_Insulted, Spring_of_Life, The_Land_of_Gold, The_Blossom_in_the_Storm Assignment_Name_3 = 'The_Invisible_Hand' # Nine_Billion_Names, Destruction_of_the_Destroyer, Winter_Soldiers, Born_to_Obey, Root_Out_the_Turpitude, Fire_Lord_Inflames_Blades_of_War, Nameless_Land_Nameless_People, Akashic_Records, The_Invisible_Hand, Abandoned_and_Insulted, Spring_of_Life, The_Land_of_Gold, The_Blossom_in_the_Storm Assignment_Name_4 = 'Nine_Billion_Names' # Nine_Billion_Names, Destruction_of_the_Destroyer, Winter_Soldiers, Born_to_Obey, Root_Out_the_Turpitude, Fire_Lord_Inflames_Blades_of_War, Nameless_Land_Nameless_People, Akashic_Records, The_Invisible_Hand, Abandoned_and_Insulted, Spring_of_Life, The_Land_of_Gold, The_Blossom_in_the_Storm + + # Group `Rogue` + Rogue_Path = 'The Hunt' # Preservation, Remembrance, Nihility, Abundance, The Hunt, Destruction, Elation + Rogue_PresetResonanceFilter = 'preset-1' # preset-1, custom + Rogue_CustomResonanceFilter = '回响构音:均晶转变 > 回响构音:零维强化\n> 回响构音:第二次初恋 > 回响构音:体验的富翁\n> 回响构音:局外人 > 回响构音:怀疑的四重根\n> 回响构音:诸法无我 > 回响构音:诸行无常\n> 回响构音:射不主皮 > 回响构音:柘弓危矢\n> 回响构音:激变变星 > 回响构音:极端氦闪\n> 回响构音:末日狂欢 > 回响构音:树苗长高舞' + Rogue_PresetBlessingFilter = 'preset-1' # preset-1, custom + Rogue_CustomBlessingFilter = '巡猎-3 > 《冠军晚餐·猫的摇篮》 > 丰饶众生,一法界心 > 毁灭-3 \n> 火堆外的夜 > 巡猎-2 > 毁灭-2 > 巡猎 > reset > random' diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 465a06efb..0b6541eba 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -7,6 +7,10 @@ "Daily": { "name": "Daily", "help": "" + }, + "Rogue": { + "name": "Menu.Rogue.name", + "help": "Menu.Rogue.help" } }, "Task": { @@ -33,6 +37,10 @@ "Assignment": { "name": "Assignment", "help": "" + }, + "Rogue": { + "name": "Task.Rogue.name", + "help": "Task.Rogue.help" } }, "Scheduler": { @@ -359,6 +367,43 @@ "The_Blossom_in_the_Storm": "Gaseous Liquid & Seed (The Blossom in the Storm)" } }, + "Rogue": { + "_info": { + "name": "Rogue._info.name", + "help": "Rogue._info.help" + }, + "Path": { + "name": "Rogue.Path.name", + "help": "Rogue.Path.help", + "Preservation": "Preservation", + "Remembrance": "Remembrance", + "Nihility": "Nihility", + "Abundance": "Abundance", + "The Hunt": "The Hunt", + "Destruction": "Destruction", + "Elation": "Elation" + }, + "PresetResonanceFilter": { + "name": "Rogue.PresetResonanceFilter.name", + "help": "Rogue.PresetResonanceFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomResonanceFilter": { + "name": "Rogue.CustomResonanceFilter.name", + "help": "Rogue.CustomResonanceFilter.help" + }, + "PresetBlessingFilter": { + "name": "Rogue.PresetBlessingFilter.name", + "help": "Rogue.PresetBlessingFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomBlessingFilter": { + "name": "Rogue.CustomBlessingFilter.name", + "help": "Rogue.CustomBlessingFilter.help" + } + }, "Gui": { "Aside": { "Install": "Install", diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index b3e809399..12c674571 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -7,6 +7,10 @@ "Daily": { "name": "Menu.Daily.name", "help": "Menu.Daily.help" + }, + "Rogue": { + "name": "Menu.Rogue.name", + "help": "Menu.Rogue.help" } }, "Task": { @@ -33,6 +37,10 @@ "Assignment": { "name": "依頼設定", "help": "" + }, + "Rogue": { + "name": "Task.Rogue.name", + "help": "Task.Rogue.help" } }, "Scheduler": { @@ -359,6 +367,43 @@ "The_Blossom_in_the_Storm": "気態流体と種子(嵐の中で咲き誇る花)" } }, + "Rogue": { + "_info": { + "name": "Rogue._info.name", + "help": "Rogue._info.help" + }, + "Path": { + "name": "Rogue.Path.name", + "help": "Rogue.Path.help", + "Preservation": "Preservation", + "Remembrance": "Remembrance", + "Nihility": "Nihility", + "Abundance": "Abundance", + "The Hunt": "The Hunt", + "Destruction": "Destruction", + "Elation": "Elation" + }, + "PresetResonanceFilter": { + "name": "Rogue.PresetResonanceFilter.name", + "help": "Rogue.PresetResonanceFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomResonanceFilter": { + "name": "Rogue.CustomResonanceFilter.name", + "help": "Rogue.CustomResonanceFilter.help" + }, + "PresetBlessingFilter": { + "name": "Rogue.PresetBlessingFilter.name", + "help": "Rogue.PresetBlessingFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomBlessingFilter": { + "name": "Rogue.CustomBlessingFilter.name", + "help": "Rogue.CustomBlessingFilter.help" + } + }, "Gui": { "Aside": { "Install": "インストール", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index c636b6183..6fc2f823a 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -7,6 +7,10 @@ "Daily": { "name": "每日", "help": "" + }, + "Rogue": { + "name": "模拟宇宙", + "help": "" } }, "Task": { @@ -33,6 +37,10 @@ "Assignment": { "name": "委托设置", "help": "" + }, + "Rogue": { + "name": "模拟宇宙", + "help": "" } }, "Scheduler": { @@ -359,6 +367,43 @@ "The_Blossom_in_the_Storm": "气态流体&种子(风暴中怒放的花)" } }, + "Rogue": { + "_info": { + "name": "模拟宇宙", + "help": "" + }, + "Path": { + "name": "命途", + "help": "", + "Preservation": "存护", + "Remembrance": "记忆", + "Nihility": "虚无", + "Abundance": "丰饶", + "The Hunt": "巡猎", + "Destruction": "毁灭", + "Elation": "欢愉" + }, + "PresetResonanceFilter": { + "name": "命途回响过滤器", + "help": "", + "preset-1": "预设 1", + "custom": "自定义" + }, + "CustomResonanceFilter": { + "name": "自定义命途回响过滤器", + "help": "" + }, + "PresetBlessingFilter": { + "name": "祝福过滤器", + "help": "", + "preset-1": "预设 1", + "custom": "自定义" + }, + "CustomBlessingFilter": { + "name": "自定义祝福过滤器", + "help": "" + } + }, "Gui": { "Aside": { "Install": "安装", @@ -452,4 +497,4 @@ "Clear": "清除" } } -} \ No newline at end of file +} diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index f57426a53..32fb043e3 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -7,6 +7,10 @@ "Daily": { "name": "每日", "help": "" + }, + "Rogue": { + "name": "Menu.Rogue.name", + "help": "Menu.Rogue.help" } }, "Task": { @@ -33,6 +37,10 @@ "Assignment": { "name": "委託設置", "help": "" + }, + "Rogue": { + "name": "Task.Rogue.name", + "help": "Task.Rogue.help" } }, "Scheduler": { @@ -359,6 +367,43 @@ "The_Blossom_in_the_Storm": "氣態流體&種子(風暴中怒放的花)" } }, + "Rogue": { + "_info": { + "name": "Rogue._info.name", + "help": "Rogue._info.help" + }, + "Path": { + "name": "Rogue.Path.name", + "help": "Rogue.Path.help", + "Preservation": "Preservation", + "Remembrance": "Remembrance", + "Nihility": "Nihility", + "Abundance": "Abundance", + "The Hunt": "The Hunt", + "Destruction": "Destruction", + "Elation": "Elation" + }, + "PresetResonanceFilter": { + "name": "Rogue.PresetResonanceFilter.name", + "help": "Rogue.PresetResonanceFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomResonanceFilter": { + "name": "Rogue.CustomResonanceFilter.name", + "help": "Rogue.CustomResonanceFilter.help" + }, + "PresetBlessingFilter": { + "name": "Rogue.PresetBlessingFilter.name", + "help": "Rogue.PresetBlessingFilter.help", + "preset-1": "preset-1", + "custom": "custom" + }, + "CustomBlessingFilter": { + "name": "Rogue.CustomBlessingFilter.name", + "help": "Rogue.CustomBlessingFilter.help" + } + }, "Gui": { "Aside": { "Install": "安裝", diff --git a/tasks/rogue/assets/assets_rogue_blessing.py b/tasks/rogue/assets/assets_rogue_blessing.py new file mode 100644 index 000000000..dbb7c53da --- /dev/null +++ b/tasks/rogue/assets/assets_rogue_blessing.py @@ -0,0 +1,65 @@ +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 ``` + +BLESSING_ENFORCE = ButtonWrapper( + name='BLESSING_ENFORCE', + share=Button( + file='./assets/share/rogue/blessing/BLESSING_ENFORCE.png', + area=(500, 141, 608, 556), + search=(480, 121, 628, 576), + color=(123, 100, 78), + button=(500, 141, 608, 556), + ), +) +BLESSING_RESET = ButtonWrapper( + name='BLESSING_RESET', + share=Button( + file='./assets/share/rogue/blessing/BLESSING_RESET.png', + area=(652, 629, 889, 677), + search=(632, 609, 909, 697), + color=(204, 203, 204), + button=(652, 629, 889, 677), + ), +) +BLESSING_STABLE_FLAG = ButtonWrapper( + name='BLESSING_STABLE_FLAG', + share=Button( + file='./assets/share/rogue/blessing/BLESSING_STABLE_FLAG.png', + area=(846, 520, 896, 542), + search=(826, 500, 916, 562), + color=(250, 250, 250), + button=(846, 520, 896, 542), + ), +) +CONFIRM = ButtonWrapper( + name='CONFIRM', + share=Button( + file='./assets/share/rogue/blessing/CONFIRM.png', + area=(960, 629, 1233, 677), + search=(940, 609, 1253, 697), + color=(217, 218, 218), + button=(960, 629, 1233, 677), + ), +) +OCR_RESET_COUNT = ButtonWrapper( + name='OCR_RESET_COUNT', + share=Button( + file='./assets/share/rogue/blessing/OCR_RESET_COUNT.png', + area=(714, 595, 824, 620), + search=(694, 575, 844, 640), + color=(37, 37, 41), + button=(714, 595, 824, 620), + ), +) +OCR_ROGUE_BUFF = ButtonWrapper( + name='OCR_ROGUE_BUFF', + share=Button( + file='./assets/share/rogue/blessing/OCR_ROGUE_BUFF.png', + area=(155, 139, 1125, 337), + search=(135, 119, 1145, 357), + color=(79, 86, 104), + button=(155, 139, 1125, 337), + ), +) diff --git a/tasks/rogue/assets/assets_rogue_ui.py b/tasks/rogue/assets/assets_rogue_ui.py new file mode 100644 index 000000000..8a9f258eb --- /dev/null +++ b/tasks/rogue/assets/assets_rogue_ui.py @@ -0,0 +1,25 @@ +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 ``` + +PAGE_CHOOSE_BUFF = ButtonWrapper( + name='PAGE_CHOOSE_BUFF', + share=Button( + file='./assets/share/rogue/ui/PAGE_CHOOSE_BUFF.png', + area=(1105, 95, 1154, 113), + search=(1085, 75, 1174, 133), + color=(81, 82, 83), + button=(1105, 95, 1154, 113), + ), +) +PAGE_CHOOSE_MIRACLE = ButtonWrapper( + name='PAGE_CHOOSE_MIRACLE', + share=Button( + file='./assets/share/rogue/ui/PAGE_CHOOSE_MIRACLE.png', + area=(988, 17, 1028, 57), + search=(968, 0, 1048, 77), + color=(40, 39, 34), + button=(988, 17, 1028, 57), + ), +) diff --git a/tasks/rogue/blessing.py b/tasks/rogue/blessing.py new file mode 100644 index 000000000..def18136f --- /dev/null +++ b/tasks/rogue/blessing.py @@ -0,0 +1,295 @@ +import re + +import numpy as np + +from dev_tools.keyword_extract import UI_LANGUAGES +from module.base.filter import Filter +from module.base.timer import Timer +from module.base.utils import area_offset +from module.logger import logger +from module.ocr.ocr import Ocr, OcrResultButton, DigitCounter +from tasks.rogue.assets.assets_rogue_blessing import * +from tasks.rogue.keywords import * +from tasks.rogue.preset import * +from tasks.rogue.ui import RogueUI + +REGEX_PUNCTUATION = re.compile(r'[ ,.\'"“”,。::!!??·•—/()()「」『』【】]') + + +def parse_name(n): + n = REGEX_PUNCTUATION.sub('', str(n)).lower() + return n + + +def get_regex_from_keyword_name(keyword, attr_name): + regex_pat = "" + attrs = tuple() + for server in UI_LANGUAGES: + string = "" + for path in keyword.instances.values(): + string += f"{parse_name(getattr(path, server))}|" + # some pattern contain each other, make sure each pattern end with "-" or the end of string + regex_pat += f"(?:({string[:-1]})(?:-|$))?" + attrs += (f"{attr_name}_{server}",) + return regex_pat, attrs + + +# normal blessing +pattern = "" +BLESSING_FILTER_ATTR = tuple() +PATH_ATTR_NAME = 'path' +path_regex, path_attr = get_regex_from_keyword_name(RoguePath, PATH_ATTR_NAME) +pattern += path_regex +BLESSING_FILTER_ATTR += path_attr + +pattern += "([123])?-?" +BLESSING_FILTER_ATTR += ("rarity",) +BLESSING_ATTR_NAME = 'blessing' +blessing_regex, blessing_attr = get_regex_from_keyword_name(RogueBlessing, BLESSING_ATTR_NAME) +pattern += blessing_regex +BLESSING_FILTER_ATTR += blessing_attr + +FILETER_REGEX = re.compile(pattern) +BLESSING_FILTER_PRESET = ("reset", "same_path", "random") +BLESSING_FILTER = Filter(FILETER_REGEX, BLESSING_FILTER_ATTR, BLESSING_FILTER_PRESET) + +# resonance +RESONANCE_ATTR_NAME = 'resonance' +pattern, RESONANCE_FILTER_ATTR = get_regex_from_keyword_name(RogueResonance, 'resonance') + +FILETER_REGEX = re.compile(pattern) +RESONANCE_FILTER_PRESET = ("random",) +RESONANCE_FILTER = Filter(FILETER_REGEX, RESONANCE_FILTER_ATTR, RESONANCE_FILTER_PRESET) + + +class RogueBuffOcr(Ocr): + merge_thres_x = 40 + + def after_process(self, result): + result = super().after_process(result) + if self.lang == 'ch': + replace_pattern_dict = { + "蓬失": "蓬矢", + "柘弓危失": "柘弓危矢", + "飞虹凿齿": "飞虹诛凿齿", + "天培步危": "天棓步危", + "云[摘销]": "云镝", + "制桑": "制穹桑", + "乌号基": "乌号綦", + "追摩物": "追孽物", + "特月": "狩月", + "彤弓素增": "彤弓素矰", + "苦表": "苦衷", + "[沦沧]肌髓": "沦浃肌髓", + "进发": "迸发", + "永缩体": "永坍缩体", + } + for pattern, replace in replace_pattern_dict.items(): + result = re.sub(pattern, replace, result) + return result + + +class RogueBlessingUI(RogueUI): + def buffs_recognition(self): + ocr = RogueBuffOcr(OCR_ROGUE_BUFF) + results = ocr.matched_ocr(self.device.image, [RogueBlessing, RogueResonance]) + + if results: + logger.info(f"Buffs recognized: {len(results)}") + else: + logger.warning("No buff recognized") + self.blessings = results + return results + + def ui_select_blessing(self, blessing: OcrResultButton | None, skip_first_screenshot=True, enforce=False): + """ + Select buff once. Multiple calls needed if there's more than one time to choose + It might occur that all listed blessings are not recognized + So this method provides a hard code way to choose one, which fit in case when blessing num is 1-3 + """ + + def is_blessing_selected(): + """ + There is a white border if a blessing is selected. + """ + top_border = area_offset(blessing.area, (0, -180)) + return self.image_color_count(top_border, (255, 255, 255)) + + def is_select_blessing_complete(): + """ + Case 1: back to main page + Case 2: choose curio + Case 3: another choose blessings, but no blessing is selected when the new selection page loaded + """ + return (self.is_in_main() or self.is_page_choose_curio() + or (self.is_page_choose_blessing() and not is_blessing_selected())) + + interval = Timer(1) + if not blessing: + enforce = True + + # start -> selected + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if is_blessing_selected(): + if enforce: + logger.info("Buff selected (enforce)") + else: + logger.info(f"Buff {blessing} selected") + break + if interval.reached(): + if enforce: + self.device.click(BLESSING_ENFORCE) + else: + self.device.click(blessing) + interval.reset() + + skip_first_screenshot = True + # selected -> confirm + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if is_select_blessing_complete(): + break + if interval.reached(): + self.device.click(CONFIRM) + interval.reset() + + def get_reset_count(self): + current, _, _ = DigitCounter(OCR_RESET_COUNT).ocr_single_line(self.device.image) + return current + + def wait_until_blessing_loaded(self, skip_first_screenshot=True): + timeout = Timer(2, count=4).start() + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if timeout.reached(): + logger.warning('Wait blessing page loaded timeout') + return False + if self.image_color_count(BLESSING_STABLE_FLAG, (255, 255, 255)): + logger.info("Blessing page loaded") + return True + + def reset_blessing_list(self, skip_first_screenshot=True): + if not self.is_page_choose_blessing(): + return False + + reset_count = self.get_reset_count() + if not reset_count: + return False + + interval = Timer(1) + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + new_count = self.get_reset_count() + + if reset_count - new_count == 1: + logger.info("Reset once") + break + if interval.reached(): + self.device.click(BLESSING_RESET) + interval.reset() + return True + + +class RogueBlessingSelector(RogueBlessingUI): + """ + Usage: + self = RogueBlessingSelector('alas') + self.device.screenshot() + self.buff_recognition() + self.select_blessing(self.) + """ + + def apply_filter(self): + paths = RoguePath.instances + + if not self.blessings: + return [] + + if isinstance(self.blessings[0].matched_keyword, RogueBlessing): + for blessing in self.blessings: + path = paths[blessing.matched_keyword.path_id] + for server in UI_LANGUAGES: + setattr(blessing, f"{PATH_ATTR_NAME}_{server}", parse_name(getattr(path, server))) + setattr(blessing, f"{BLESSING_ATTR_NAME}_{server}", + parse_name(getattr(blessing.matched_keyword, server))) + setattr(blessing, "rarity", getattr(blessing.matched_keyword, "rarity")) + + if self.config.Rogue_PresetBlessingFilter == 'preset-1': + BLESSING_FILTER.load(parse_name(BLESSING_PRESET_1)) + if self.config.Rogue_PresetBlessingFilter == 'custom': + BLESSING_FILTER.load(parse_name(self.config.Rogue_CustomBlessingFilter)) + + if isinstance(self.blessings[0].matched_keyword, RogueResonance): + if len(self.blessings) == 1: # resonance can not be reset. So have not choice when there's only one option + return self.blessings + for blessing in self.blessings: + for server in UI_LANGUAGES: + setattr(blessing, f"{RESONANCE_ATTR_NAME}_{server}", + parse_name(getattr(blessing.matched_keyword, server))) + + if self.config.Rogue_PresetResonanceFilter == 'preset-1': + RESONANCE_FILTER.load(parse_name(RESONANCE_PRESET_1)) + if self.config.Rogue_PresetResonanceFilter == 'custom': + RESONANCE_FILTER.load(parse_name(self.config.Rogue_CustomResonanceFilter)) + + priority = BLESSING_FILTER.apply(self.blessings) + return priority + + def select_blessing(self, priority: list): + if not self.blessings: + logger.info('No blessing recognized, randomly choose one') + self.ui_select_blessing(None, enforce=True) + return + + if not len(priority): + logger.info('No blessing project satisfies current filter, randomly choose one') + choose = np.random.choice(self.blessings) + self.ui_select_blessing(choose) + return + + for option in priority: + # preset + if isinstance(option, str): + if option.lower() == 'reset': + if self.reset_blessing_list(): + self.wait_until_blessing_loaded() + self.buffs_recognition() + self.select_blessing(self.apply_filter()) + return + else: + continue + if option.lower() == 'same_path': + chosen = False + for blessing in self.blessings: + if blessing.path_id == self.path.id: + self.ui_select_blessing(blessing) + chosen = True + if chosen: + return + else: + continue + if option.lower() == 'random': + choose = np.random.choice(self.blessings) + self.ui_select_blessing(choose) + return + + if isinstance(option, OcrResultButton): + self.ui_select_blessing(option) + return diff --git a/tasks/rogue/keywords/__init__.py b/tasks/rogue/keywords/__init__.py new file mode 100644 index 000000000..d8cb6676c --- /dev/null +++ b/tasks/rogue/keywords/__init__.py @@ -0,0 +1,5 @@ +import tasks.rogue.keywords.blessing as KEYWORDS_ROGUE_BLESSING +import tasks.rogue.keywords.path as KEYWORDS_ROGUE_PATH +import tasks.rogue.keywords.resonance as KEYWORDS_ROGUE_RESONANCE + +from tasks.rogue.keywords.classes import RogueBlessing, RoguePath, RogueResonance diff --git a/tasks/rogue/keywords/blessing.py b/tasks/rogue/keywords/blessing.py new file mode 100644 index 000000000..1b3ee5510 --- /dev/null +++ b/tasks/rogue/keywords/blessing.py @@ -0,0 +1,1265 @@ +from .classes import RogueBlessing + +# This file was auto-generated, do not modify it manually. To generate: +# ``` python -m dev_tools.keyword_extract ``` + +Divine_Construct_Resonance_Transfer = RogueBlessing( + id=1, + name='Divine_Construct_Resonance_Transfer', + cn='神性构筑•谐振传递', + cht='神性構築•諧振傳遞', + en='Divine Construct: Resonance Transfer', + jp='神性構築・共鳴伝達', + path_id=1, + rarity=3, +) +Divine_Construct_Metastatic_Field = RogueBlessing( + id=2, + name='Divine_Construct_Metastatic_Field', + cn='神性构筑•超静定场', + cht='神性構築•超靜定場', + en='Divine Construct: Metastatic Field', + jp='神性構築・不静定構造', + path_id=1, + rarity=3, +) +Divine_Construct_Macrosegregation = RogueBlessing( + id=3, + name='Divine_Construct_Macrosegregation', + cn='神性构筑•宏观偏析', + cht='神性構築•宏觀偏析', + en='Divine Construct: Macrosegregation', + jp='神性構築・マクロ偏析', + path_id=1, + rarity=3, +) +Interstellar_Construct_Shear_Structure = RogueBlessing( + id=4, + name='Interstellar_Construct_Shear_Structure', + cn='星间构筑•切变结构', + cht='星間構築•切變結構', + en='Interstellar Construct: Shear Structure', + jp='星間構築・剪断構造', + path_id=1, + rarity=2, +) +Interstellar_Construct_Burst_Lattice = RogueBlessing( + id=5, + name='Interstellar_Construct_Burst_Lattice', + cn='星间构筑•迸裂晶格', + cht='星間構築•迸裂晶格', + en='Interstellar Construct: Burst Lattice', + jp='星間構築・格子欠陥', + path_id=1, + rarity=2, +) +Interstellar_Construct_Solid_Solution = RogueBlessing( + id=6, + name='Interstellar_Construct_Solid_Solution', + cn='星间构筑•固溶强化', + cht='星間構築•固溶強化', + en='Interstellar Construct: Solid Solution', + jp='星間構築・固溶強化', + path_id=1, + rarity=2, +) +Interstellar_Construct_Safe_Load = RogueBlessing( + id=7, + name='Interstellar_Construct_Safe_Load', + cn='星间构筑•安全载荷', + cht='星間構築•安全載荷', + en='Interstellar Construct: Safe Load', + jp='星間構築・安全荷重', + path_id=1, + rarity=2, +) +Interstellar_Construct_Sanctuary = RogueBlessing( + id=8, + name='Interstellar_Construct_Sanctuary', + cn='星间构筑•回馈庇护', + cht='星間構築•回饋庇護', + en='Interstellar Construct: Sanctuary', + jp='星間構築・反作用庇護', + path_id=1, + rarity=2, +) +Interstellar_Construct_Quadrangular_Pyramid = RogueBlessing( + id=9, + name='Interstellar_Construct_Quadrangular_Pyramid', + cn='星间构筑•四棱锥体', + cht='星間構築•四稜錐體', + en='Interstellar Construct: Quadrangular Pyramid', + jp='星間構築・四角錐', + path_id=1, + rarity=2, +) +Interstellar_Construct_Hypoeutectoid = RogueBlessing( + id=10, + name='Interstellar_Construct_Hypoeutectoid', + cn='星间构筑•亚共晶体', + cht='星間構築•亞共晶體', + en='Interstellar Construct: Hypoeutectoid', + jp='星間構築・亜共晶', + path_id=1, + rarity=2, +) +Construct_Assemble = RogueBlessing( + id=11, + name='Construct_Assemble', + cn='构筑•聚塑', + cht='構築•聚塑', + en='Construct: Assemble', + jp='構築・集塑', + path_id=1, + rarity=1, +) +Construct_Sentinel = RogueBlessing( + id=12, + name='Construct_Sentinel', + cn='构筑•哨戒', + cht='構築•哨戒', + en='Construct: Sentinel', + jp='構築・哨戒', + path_id=1, + rarity=1, +) +Construct_Patch = RogueBlessing( + id=13, + name='Construct_Patch', + cn='构筑•弥合', + cht='構築•彌合', + en='Construct: Patch', + jp='構築・溶着', + path_id=1, + rarity=1, +) +Construct_Compensation = RogueBlessing( + id=14, + name='Construct_Compensation', + cn='构筑•补偿', + cht='構築•補償', + en='Construct: Compensation', + jp='構築・補填', + path_id=1, + rarity=1, +) +Construct_Firmness = RogueBlessing( + id=15, + name='Construct_Firmness', + cn='构筑•坚定', + cht='構築•堅定', + en='Construct: Firmness', + jp='構築・確固', + path_id=1, + rarity=1, +) +Construct_Rotation = RogueBlessing( + id=16, + name='Construct_Rotation', + cn='构筑•回转', + cht='構築•迴轉', + en='Construct: Rotation', + jp='構築・回転', + path_id=1, + rarity=1, +) +Construct_Burst = RogueBlessing( + id=17, + name='Construct_Burst', + cn='构筑•迸发', + cht='構築•迸發', + en='Construct: Burst', + jp='構築・勃発', + path_id=1, + rarity=1, +) +Construct_Concentration = RogueBlessing( + id=18, + name='Construct_Concentration', + cn='构筑•专注', + cht='構築•專注', + en='Construct: Concentration', + jp='構築・専念', + path_id=1, + rarity=1, +) +Perfect_Experience_Fuli = RogueBlessing( + id=19, + name='Perfect_Experience_Fuli', + cn='完美体验:浮黎', + cht='完美體驗:浮黎', + en='Perfect Experience: Fuli', + jp='完璧体験:浮黎', + path_id=2, + rarity=3, +) +Perfect_Experience_Innocence = RogueBlessing( + id=20, + name='Perfect_Experience_Innocence', + cn='完美体验:纯真', + cht='完美體驗:純真', + en='Perfect Experience: Innocence', + jp='完璧体験:純真', + path_id=2, + rarity=3, +) +Perfect_Experience_Reticence = RogueBlessing( + id=21, + name='Perfect_Experience_Reticence', + cn='完美体验:缄默', + cht='完美體驗:緘默', + en='Perfect Experience: Reticence', + jp='完璧体験:沈黙', + path_id=2, + rarity=3, +) +Ultimate_Experience_Melancholia = RogueBlessing( + id=22, + name='Ultimate_Experience_Melancholia', + cn='极端体验:怅然若失', + cht='極端體驗:悵然若失', + en='Ultimate Experience: Melancholia', + jp='極端体験:茫然自失', + path_id=2, + rarity=2, +) +Ultimate_Experience_Dizziness = RogueBlessing( + id=23, + name='Ultimate_Experience_Dizziness', + cn='极端体验:头晕目眩', + cht='極端體驗:頭暈目眩', + en='Ultimate Experience: Dizziness', + jp='極端体験:眩暈', + path_id=2, + rarity=2, +) +Ultimate_Experience_Insensitivity = RogueBlessing( + id=24, + name='Ultimate_Experience_Insensitivity', + cn='极端体验:麻木不仁', + cht='極端體驗:麻木不仁', + en='Ultimate Experience: Insensitivity', + jp='極端体験:無感覚', + path_id=2, + rarity=2, +) +Ultimate_Experience_Sentimentality = RogueBlessing( + id=25, + name='Ultimate_Experience_Sentimentality', + cn='极端体验:多愁善感', + cht='極端體驗:多愁善感', + en='Ultimate Experience: Sentimentality', + jp='極端体験:多感', + path_id=2, + rarity=2, +) +Ultimate_Experience_Indelibility = RogueBlessing( + id=26, + name='Ultimate_Experience_Indelibility', + cn='极端体验:沦浃肌髓', + cht='極端體驗:淪浹肌髓', + en='Ultimate Experience: Indelibility', + jp='極端体験:感銘', + path_id=2, + rarity=2, +) +Ultimate_Experience_Shudder = RogueBlessing( + id=27, + name='Ultimate_Experience_Shudder', + cn='极端体验:不寒而栗', + cht='極端體驗:不寒而慄', + en='Ultimate Experience: Shudder', + jp='極端体験:戦慄', + path_id=2, + rarity=2, +) +Ultimate_Experience_Maverick = RogueBlessing( + id=28, + name='Ultimate_Experience_Maverick', + cn='极端体验:特立独行', + cht='極端體驗:特立獨行', + en='Ultimate Experience: Maverick', + jp='極端体験:異端児', + path_id=2, + rarity=2, +) +Experience_Unspeakable_Shame = RogueBlessing( + id=29, + name='Experience_Unspeakable_Shame', + cn='体验:难言的羞耻', + cht='體驗:難言的羞恥', + en='Experience: Unspeakable Shame', + jp='体験:言えない恥', + path_id=2, + rarity=1, +) +Experience_The_Torment_of_Alienation = RogueBlessing( + id=30, + name='Experience_The_Torment_of_Alienation', + cn='体验:疏离的煎熬', + cht='體驗:疏離的煎熬', + en='Experience: The Torment of Alienation', + jp='体験:疎遠の苦しみ', + path_id=2, + rarity=1, +) +Experience_Lost_Memory = RogueBlessing( + id=31, + name='Experience_Lost_Memory', + cn='体验:丢失的记忆', + cht='體驗:遺失的記憶', + en='Experience: Lost Memory', + jp='体験:失われた記憶', + path_id=2, + rarity=1, +) +Experience_Stone_Cold_Hatred = RogueBlessing( + id=32, + name='Experience_Stone_Cold_Hatred', + cn='体验:决绝的痛恨', + cht='體驗:決絕的痛恨', + en='Experience: Stone Cold Hatred', + jp='体験:凄烈な憎悪', + path_id=2, + rarity=1, +) +Experience_Pain__Suffering = RogueBlessing( + id=33, + name='Experience_Pain__Suffering', + cn='体验:病痛的折磨', + cht='體驗:病痛的折磨', + en='Experience: Pain & Suffering', + jp='体験:病の苛み', + path_id=2, + rarity=1, +) +Experience_Primordial_Hardship = RogueBlessing( + id=34, + name='Experience_Primordial_Hardship', + cn='体验:原初的苦衷', + cht='體驗:原初的苦衷', + en='Experience: Primordial Hardship', + jp='体験:原初の苦衷', + path_id=2, + rarity=1, +) +Experience_Thrill_of_Escalation = RogueBlessing( + id=35, + name='Experience_Thrill_of_Escalation', + cn='体验:攀升的刺激', + cht='體驗:攀升的刺激', + en='Experience: Thrill of Escalation', + jp='体験:上昇の刺激', + path_id=2, + rarity=1, +) +Experience_Responsive_Excitement = RogueBlessing( + id=36, + name='Experience_Responsive_Excitement', + cn='体验:回应的兴奋', + cht='體驗:回應的興奮', + en='Experience: Responsive Excitement', + jp='体験:反響の興奮', + path_id=2, + rarity=1, +) +Funeral_of_Sensory_Pursuivant = RogueBlessing( + id=37, + name='Funeral_of_Sensory_Pursuivant', + cn='感官追奉者的葬礼', + cht='感官追奉者的葬禮', + en='Funeral of Sensory Pursuivant', + jp='感覚追奉者の葬式', + path_id=3, + rarity=3, +) +The_Man_in_the_Cover = RogueBlessing( + id=38, + name='The_Man_in_the_Cover', + cn='被装在套子里的人', + cht='被裝在套子裡的人', + en='The Man in the Cover', + jp='箱に入った人', + path_id=3, + rarity=3, +) +Why_Hasn_t_Everything_Already_Disappeared = RogueBlessing( + id=39, + name='Why_Hasn_t_Everything_Already_Disappeared', + cn='为何一切尚未消失', + cht='為何一切尚未消失', + en="Why Hasn't Everything Already Disappeared?", + jp='なぜすべては消えぬか', + path_id=3, + rarity=3, +) +Beginning_and_End = RogueBlessing( + id=40, + name='Beginning_and_End', + cn='开端与终结', + cht='開端與終結', + en='Beginning and End', + jp='発端と結末', + path_id=3, + rarity=2, +) +Café_Self_Deceit = RogueBlessing( + id=41, + name='Café_Self_Deceit', + cn='自欺咖啡馆', + cht='自欺咖啡館', + en='Café Self-Deceit', + jp='自己欺瞞カフェ', + path_id=3, + rarity=2, +) +Call_of_the_Wilderness = RogueBlessing( + id=42, + name='Call_of_the_Wilderness', + cn='旷野的呼告', + cht='曠野的呼告', + en='Call of the Wilderness', + jp='広野の呼び声', + path_id=3, + rarity=2, +) +Night_Beyond_Pyre = RogueBlessing( + id=43, + name='Night_Beyond_Pyre', + cn='火堆外的夜', + cht='火堆外的夜', + en='Night Beyond Pyre', + jp='焚火の外の夜', + path_id=3, + rarity=2, +) +Hell_is_Other_People = RogueBlessing( + id=44, + name='Hell_is_Other_People', + cn='他人即地狱', + cht='他人即地獄', + en='Hell is Other People', + jp='他人は地獄', + path_id=3, + rarity=2, +) +Twilight_of_Existence = RogueBlessing( + id=45, + name='Twilight_of_Existence', + cn='存在的黄昏', + cht='存在的黃昏', + en='Twilight of Existence', + jp='存在の黄昏', + path_id=3, + rarity=2, +) +All_Things_are_Possible = RogueBlessing( + id=46, + name='All_Things_are_Possible', + cn='无根据颂歌', + cht='無根據頌歌', + en='All Things are Possible', + jp='根拠なき賛歌', + path_id=3, + rarity=2, +) +Ignosticism = RogueBlessing( + id=47, + name='Ignosticism', + cn='漠视主义', + cht='漠視主義', + en='Ignosticism', + jp='漠視主義', + path_id=3, + rarity=1, +) +Questioning_of_Purpose = RogueBlessing( + id=48, + name='Questioning_of_Purpose', + cn='意义质询', + cht='意義質詢', + en='Questioning of Purpose', + jp='意義への詰問', + path_id=3, + rarity=1, +) +Blind_Vision = RogueBlessing( + id=49, + name='Blind_Vision', + cn='盲目视界', + cht='盲目視界', + en='Blind Vision', + jp='盲目の視界', + path_id=3, + rarity=1, +) +Tragic_Lecture = RogueBlessing( + id=50, + name='Tragic_Lecture', + cn='悲剧讲座', + cht='悲劇講座', + en='Tragic Lecture', + jp='悲劇講座', + path_id=3, + rarity=1, +) +Sensory_Labyrinth = RogueBlessing( + id=51, + name='Sensory_Labyrinth', + cn='知觉迷墙', + cht='知覺迷牆', + en='Sensory Labyrinth', + jp='知覚の壁', + path_id=3, + rarity=1, +) +Emotional_Decluttering = RogueBlessing( + id=52, + name='Emotional_Decluttering', + cn='情绪舍离', + cht='情緒捨離', + en='Emotional Decluttering', + jp='情緒捨離', + path_id=3, + rarity=1, +) +Offerings_of_Deception = RogueBlessing( + id=53, + name='Offerings_of_Deception', + cn='虚妄供品', + cht='虛妄供品', + en='Offerings of Deception', + jp='虚妄の供物', + path_id=3, + rarity=1, +) +Before_Sunrise = RogueBlessing( + id=54, + name='Before_Sunrise', + cn='日出之前', + cht='日出之前', + en='Before Sunrise', + jp='日の出前', + path_id=3, + rarity=1, +) +Prosperity_Longevity = RogueBlessing( + id=55, + name='Prosperity_Longevity', + cn='葳蕤繁祉,延彼遐龄', + cht='葳蕤繁祉,延彼遐齡', + en='Prosperity, Longevity', + jp='彼の遐齢を延さん', + path_id=4, + rarity=3, +) +Mudra_of_Blessing = RogueBlessing( + id=56, + name='Mudra_of_Blessing', + cn='若罪若福,施诸愿印', + cht='若罪若福,施諸願印', + en='Mudra of Blessing', + jp='若の罪福、皆に施願を', + path_id=4, + rarity=3, +) +Being_of_Abundance_Becoming_One_Mind = RogueBlessing( + id=57, + name='Being_of_Abundance_Becoming_One_Mind', + cn='丰饶众生,一法界心', + cht='豐饒眾生,一法界心', + en='Being of Abundance, Becoming One Mind', + jp='衆生に豊穣を', + path_id=4, + rarity=3, +) +Good_Deeds_Come_After_Old_Sins = RogueBlessing( + id=58, + name='Good_Deeds_Come_After_Old_Sins', + cn='灭罪累生善', + cht='滅罪累生善', + en='Good Deeds Come After Old Sins', + jp='滅罪生善', + path_id=4, + rarity=2, +) +Mortals_of_the_Buddha_Field = RogueBlessing( + id=59, + name='Mortals_of_the_Buddha_Field', + cn='天人不动众', + cht='天人不動眾', + en='Mortals of the Buddha-Field', + jp='天人不動衆', + path_id=4, + rarity=2, +) +Salvation_From_Damnation = RogueBlessing( + id=60, + name='Salvation_From_Damnation', + cn='慧海度慈航', + cht='慧海度慈航', + en='Salvation From Damnation', + jp='慧海を渡る慈航', + path_id=4, + rarity=2, +) +Precious_Moon_Like_Candlelight = RogueBlessing( + id=61, + name='Precious_Moon_Like_Candlelight', + cn='宝光烛日月', + cht='寶光燭日月', + en='Precious Moon-Like Candlelight', + jp='日月を燭らす宝光', + path_id=4, + rarity=2, +) +Aversion_to_Suffering = RogueBlessing( + id=62, + name='Aversion_to_Suffering', + cn='厌离邪秽苦', + cht='厭離邪穢苦', + en='Aversion to Suffering', + jp='邪穢の苦を厭離す', + path_id=4, + rarity=2, +) +Clear_Lucite_Body = RogueBlessing( + id=63, + name='Clear_Lucite_Body', + cn='明澈琉璃身', + cht='明澈琉璃身', + en='Clear Lucite Body', + jp='明澄琉璃の身', + path_id=4, + rarity=2, +) +Prajna_Boat = RogueBlessing( + id=64, + name='Prajna_Boat', + cn='大愿般若船', + cht='大願般若船', + en='Prajna Boat', + jp='大愿、般若の船', + path_id=4, + rarity=2, +) +Rain_of_Truth = RogueBlessing( + id=65, + name='Rain_of_Truth', + cn='法雨', + cht='法雨', + en='Rain of Truth', + jp='法雨', + path_id=4, + rarity=1, +) +Sweet_Dew = RogueBlessing( + id=66, + name='Sweet_Dew', + cn='甘露', + cht='甘露', + en='Sweet Dew', + jp='甘露', + path_id=4, + rarity=1, +) +Extended_Life = RogueBlessing( + id=67, + name='Extended_Life', + cn='延寿', + cht='延壽', + en='Extended Life', + jp='延寿', + path_id=4, + rarity=1, +) +Seal = RogueBlessing( + id=68, + name='Seal', + cn='愿印', + cht='願印', + en='Seal', + jp='願印', + path_id=4, + rarity=1, +) +Dispel_Disaster = RogueBlessing( + id=69, + name='Dispel_Disaster', + cn='禳灾', + cht='禳災', + en='Dispel Disaster', + jp='厄払い', + path_id=4, + rarity=1, +) +Rebirth = RogueBlessing( + id=70, + name='Rebirth', + cn='回生', + cht='回生', + en='Rebirth', + jp='回生', + path_id=4, + rarity=1, +) +Victorious_Force = RogueBlessing( + id=71, + name='Victorious_Force', + cn='胜军', + cht='勝軍', + en='Victorious Force', + jp='勝軍', + path_id=4, + rarity=1, +) +Blessing = RogueBlessing( + id=72, + name='Blessing', + cn='加持', + cht='加持', + en='Blessing', + jp='加持', + path_id=4, + rarity=1, +) +Imperial_Reign = RogueBlessing( + id=73, + name='Imperial_Reign', + cn='帝星君临制穹桑', + cht='帝星君臨制穹桑', + en='Imperial Reign', + jp='帝星臨めば穹桑を制す', + path_id=5, + rarity=3, +) +Imperishable_Victory = RogueBlessing( + id=74, + name='Imperishable_Victory', + cn='帝车超光所向捷', + cht='帝車超光所向捷', + en='Imperishable Victory', + jp='光越す制勝の帝車', + path_id=5, + rarity=3, +) +Celestial_Annihilation = RogueBlessing( + id=75, + name='Celestial_Annihilation', + cn='帝弓断空彻太清', + cht='帝弓斷空徹太清', + en='Celestial Annihilation', + jp='太清を徹す断空の帝弓', + path_id=5, + rarity=3, +) +Battle_Against_the_Old_Foe = RogueBlessing( + id=76, + name='Battle_Against_the_Old_Foe', + cn='天舟缴夙敌', + cht='天舟繳夙敵', + en='Battle Against the Old Foe', + jp='夙敵繳める天舟', + path_id=5, + rarity=2, +) +Archery_Duel = RogueBlessing( + id=77, + name='Archery_Duel', + cn='白矢决射御', + cht='白矢決射御', + en='Archery Duel', + jp='射御を決する白矢', + path_id=5, + rarity=2, +) +Adept_Bow = RogueBlessing( + id=78, + name='Adept_Bow', + cn='序师执迟彝', + cht='序師執遲彝', + en="Adept's Bow", + jp='遅彝弓を執る序師', + path_id=5, + rarity=2, +) +Flowing_Mist = RogueBlessing( + id=79, + name='Flowing_Mist', + cn='流岚追孽物', + cht='流嵐追孽物', + en='Flowing Mist', + jp='忌み物を追う流嵐', + path_id=5, + rarity=2, +) +Auspicious_Star = RogueBlessing( + id=80, + name='Auspicious_Star', + cn='景星助狩月', + cht='景星助狩月', + en='Auspicious Star', + jp='狩月を助ける景星', + path_id=5, + rarity=2, +) +Ejecting_the_Borisin = RogueBlessing( + id=81, + name='Ejecting_the_Borisin', + cn='云镝逐步离', + cht='雲鏑逐步離', + en='Ejecting the Borisin', + jp='歩離を駆逐せし雲鏑', + path_id=5, + rarity=2, +) +Monster_Expelling_Rainbow = RogueBlessing( + id=82, + name='Monster_Expelling_Rainbow', + cn='飞虹诛凿齿', + cht='飛虹誅鑿齒', + en='Monster-Expelling Rainbow', + jp='鑿齒を誅つ飛虹', + path_id=5, + rarity=2, +) +Vermeil_Bow_and_White_Arrow = RogueBlessing( + id=83, + name='Vermeil_Bow_and_White_Arrow', + cn='彤弓素矰', + cht='彤弓素矰', + en='Vermeil Bow and White Arrow', + jp='緋弓素矢', + path_id=5, + rarity=1, +) +Skirting_Life_and_Death = RogueBlessing( + id=84, + name='Skirting_Life_and_Death', + cn='背生击死', + cht='背生擊死', + en='Skirting Life and Death', + jp='背生撃死', + path_id=5, + rarity=1, +) +Shrewd_Arrangement = RogueBlessing( + id=85, + name='Shrewd_Arrangement', + cn='背孤击虚', + cht='背孤擊虛', + en='Shrewd Arrangement', + jp='背孤撃虚', + path_id=5, + rarity=1, +) +Thundering_Chariot = RogueBlessing( + id=86, + name='Thundering_Chariot', + cn='雷车动地', + cht='雷車動地', + en='Thundering Chariot', + jp='雷車動地', + path_id=5, + rarity=1, +) +Constellation_Surge = RogueBlessing( + id=87, + name='Constellation_Surge', + cn='电射牛斗', + cht='電射牛斗', + en='Constellation Surge', + jp='牛斗射る紫電', + path_id=5, + rarity=1, +) +Catastrophic_Constellation = RogueBlessing( + id=88, + name='Catastrophic_Constellation', + cn='天棓步危', + cht='天棓步危', + en='Catastrophic Constellation', + jp='危宮へ歩む天棓', + path_id=5, + rarity=1, +) +Vaulting_Ambition = RogueBlessing( + id=89, + name='Vaulting_Ambition', + cn='桑弧蓬矢', + cht='桑弧蓬矢', + en='Vaulting Ambition', + jp='桑弧蓬矢', + path_id=5, + rarity=1, +) +Blessed_Bow_and_Arrow = RogueBlessing( + id=90, + name='Blessed_Bow_and_Arrow', + cn='乌号綦箭', + cht='烏號綦箭', + en='Blessed Bow and Arrow', + jp='烏号綦箭', + path_id=5, + rarity=1, +) +Non_Inverse_Antimatter_Equation = RogueBlessing( + id=91, + name='Non_Inverse_Antimatter_Equation', + cn='反物质非逆方程', + cht='反物質非逆方程式', + en='Non-Inverse Antimatter Equation', + jp='反物質非可逆方程式', + path_id=6, + rarity=3, +) +Universal_Heat_Death_Characteristic = RogueBlessing( + id=92, + name='Universal_Heat_Death_Characteristic', + cn='寰宇热寂特征数', + cht='寰宇熱寂特徵數', + en='Universal Heat Death Characteristic', + jp='熱的死の固有値', + path_id=6, + rarity=3, +) +Regression_Inequality_of_Annihilation = RogueBlessing( + id=93, + name='Regression_Inequality_of_Annihilation', + cn='湮灭回归不等式', + cht='湮滅回歸不等式', + en='Regression Inequality of Annihilation', + jp='対消滅回帰不等式', + path_id=6, + rarity=3, +) +Incremental_Doomsday = RogueBlessing( + id=94, + name='Incremental_Doomsday', + cn='递增性末日', + cht='遞增性末日', + en='Incremental Doomsday', + jp='逓増的終末', + path_id=6, + rarity=2, +) +Catastrophic_Resonance = RogueBlessing( + id=95, + name='Catastrophic_Resonance', + cn='灾难性共振', + cht='災難性共振', + en='Catastrophic Resonance', + jp='災難的共振', + path_id=6, + rarity=2, +) +Indicative_Depth_of_Field = RogueBlessing( + id=96, + name='Indicative_Depth_of_Field', + cn='预兆性景深', + cht='預兆性景深', + en='Indicative Depth of Field', + jp='予兆的被写界深度', + path_id=6, + rarity=2, +) +Devastating_Accretion = RogueBlessing( + id=97, + name='Devastating_Accretion', + cn='毁灭性吸积', + cht='毀滅性吸積', + en='Devastating Accretion', + jp='壊滅的降着', + path_id=6, + rarity=2, +) +Destructive_Flare = RogueBlessing( + id=98, + name='Destructive_Flare', + cn='破坏性耀发', + cht='破壞性耀發', + en='Destructive Flare', + jp='破壊的フレア', + path_id=6, + rarity=2, +) +Disciplinary_Flicker = RogueBlessing( + id=99, + name='Disciplinary_Flicker', + cn='戒律性闪变', + cht='戒律性閃變', + en='Disciplinary Flicker', + jp='戒律的フラッシュ', + path_id=6, + rarity=2, +) +Hazardous_Lucent_Residue = RogueBlessing( + id=100, + name='Hazardous_Lucent_Residue', + cn='危害性余光', + cht='危害性餘光', + en='Hazardous Lucent Residue', + jp='危害的余光', + path_id=6, + rarity=2, +) +Primordial_Black_Hole = RogueBlessing( + id=101, + name='Primordial_Black_Hole', + cn='原生黑洞', + cht='原生黑洞', + en='Primordial Black Hole', + jp='原始ブラックホール', + path_id=6, + rarity=1, +) +Reflection = RogueBlessing( + id=102, + name='Reflection', + cn='回光效应', + cht='回光效應', + en='Reflection', + jp='光壊変', + path_id=6, + rarity=1, +) +Orbital_Redshift = RogueBlessing( + id=103, + name='Orbital_Redshift', + cn='轨道红移', + cht='軌道紅移', + en='Orbital Redshift', + jp='軌道赤方偏移', + path_id=6, + rarity=1, +) +Instability_Strip = RogueBlessing( + id=104, + name='Instability_Strip', + cn='不稳定带', + cht='不穩定帶', + en='Instability Strip', + jp='不安定帯', + path_id=6, + rarity=1, +) +Metric_Reservation = RogueBlessing( + id=105, + name='Metric_Reservation', + cn='储备度规', + cht='儲備度規', + en='Metric Reservation', + jp='備蓄計量', + path_id=6, + rarity=1, +) +Sentinel_Satellite = RogueBlessing( + id=106, + name='Sentinel_Satellite', + cn='哨戒卫星', + cht='哨戒衛星', + en='Sentinel Satellite', + jp='哨戒衛星', + path_id=6, + rarity=1, +) +Polarization_Receptor = RogueBlessing( + id=107, + name='Polarization_Receptor', + cn='偏振受体', + cht='偏振受體', + en='Polarization Receptor', + jp='偏光受容体', + path_id=6, + rarity=1, +) +Eternally_Collapsing_Object = RogueBlessing( + id=108, + name='Eternally_Collapsing_Object', + cn='永坍缩体', + cht='永坍縮體', + en='Eternally Collapsing Object', + jp='永久崩壊天体', + path_id=6, + rarity=1, +) +Auto_Harmonica_Whitest_Night = RogueBlessing( + id=109, + name='Auto_Harmonica_Whitest_Night', + cn='《自动口琴•茫茫白夜》', + cht='《自動口琴•茫茫白夜》', + en='Auto-Harmonica: Whitest Night', + jp='『自動ハーモニカ・茫々たる白夜』', + path_id=7, + rarity=3, +) +Slaughterhouse_No_4_Rest_in_Peace = RogueBlessing( + id=110, + name='Slaughterhouse_No_4_Rest_in_Peace', + cn='《四号屠场•众生安眠》', + cht='《四號屠場•眾生安眠》', + en='Slaughterhouse No. 4: Rest in Peace', + jp='『四番屠畜場・皆眠りて』', + path_id=7, + rarity=3, +) +Champion_Dinner_Cat_Cradle = RogueBlessing( + id=111, + name='Champion_Dinner_Cat_Cradle', + cn='《冠军晚餐•猫的摇篮》', + cht='《冠軍晚餐•貓的搖籃》', + en="Champion's Dinner: Cat's Cradle", + jp='『チャンピオンのディナー・猫のゆりかご』', + path_id=7, + rarity=3, +) +Portrait_of_A_Man_On_Fire = RogueBlessing( + id=112, + name='Portrait_of_A_Man_On_Fire', + cn='《燃烧男子的肖像》', + cht='《燃燒男子的肖像》', + en='Portrait of A Man On Fire', + jp='『燃ゆる男の肖像』', + path_id=7, + rarity=2, +) +Just_Keep_on_Crying = RogueBlessing( + id=113, + name='Just_Keep_on_Crying', + cn='《流吧,你的眼泪》', + cht='《流吧,你的眼淚》', + en='Just Keep on Crying!', + jp='『流れよ汝が涙』', + path_id=7, + rarity=2, +) +The_Hourglass_Kindergarten = RogueBlessing( + id=114, + name='The_Hourglass_Kindergarten', + cn='《砂时镜下的幼园》', + cht='《砂時鏡下的幼園》', + en='The Hourglass Kindergarten', + jp='『砂時計の幼稚園』', + path_id=7, + rarity=2, +) +The_Painted_Albatross = RogueBlessing( + id=115, + name='The_Painted_Albatross', + cn='《被涂污的信天翁》', + cht='《被塗汙的信天翁》', + en='The Painted Albatross', + jp='『汚されたアホウドリ』', + path_id=7, + rarity=2, +) +_12_Monkeys_and_Angry_Men = RogueBlessing( + id=116, + name='_12_Monkeys_and_Angry_Men', + cn='《十二猴子与怒汉》', + cht='《十二猴子與怒漢》', + en='12 Monkeys and Angry Men', + jp='『十二のサルと怒れる男』', + path_id=7, + rarity=2, +) +Aiden_Gravitational_Rainbow = RogueBlessing( + id=117, + name='Aiden_Gravitational_Rainbow', + cn='《利尔他引力之虹》', + cht='《利爾他引力之虹》', + en='Aiden Gravitational Rainbow', + jp='『リルタ重力の虹』', + path_id=7, + rarity=2, +) +Twenty_First_Military_Rule = RogueBlessing( + id=118, + name='Twenty_First_Military_Rule', + cn='《第二十一条军规》', + cht='《第二十一條軍規》', + en='Twenty-First Military Rule', + jp='『キャッチ=21』', + path_id=7, + rarity=2, +) +Exemplary_Conduct = RogueBlessing( + id=119, + name='Exemplary_Conduct', + cn='《操行满分》', + cht='《操行滿分》', + en='Exemplary Conduct', + jp='『素行満点』', + path_id=7, + rarity=1, +) +Mostly_Harmful = RogueBlessing( + id=120, + name='Mostly_Harmful', + cn='《基本有害》', + cht='《基本有害》', + en='Mostly Harmful', + jp='『ほとんど有害』', + path_id=7, + rarity=1, +) +Suspiria = RogueBlessing( + id=121, + name='Suspiria', + cn='《阴风阵阵》', + cht='《陰風陣陣》', + en='Suspiria', + jp='『サスペンス』', + path_id=7, + rarity=1, +) +Pale_Fire = RogueBlessing( + id=122, + name='Pale_Fire', + cn='《灰暗的火》', + cht='《灰暗的火》', + en='Pale Fire', + jp='『仄暗い炎』', + path_id=7, + rarity=1, +) +Back_to_the_Lighthouse = RogueBlessing( + id=123, + name='Back_to_the_Lighthouse', + cn='《回灯塔去》', + cht='《回燈塔去》', + en='Back to the Lighthouse', + jp='『灯台へ戻ろう』', + path_id=7, + rarity=1, +) +Doctor_of_Love = RogueBlessing( + id=124, + name='Doctor_of_Love', + cn='《奇爱医生》', + cht='《奇愛醫生》', + en='Doctor of Love', + jp='『医者の異常な愛情』', + path_id=7, + rarity=1, +) +Platinum_Age = RogueBlessing( + id=125, + name='Platinum_Age', + cn='《铂金时代》', + cht='《鉑金時代》', + en='Platinum Age', + jp='『白金時代』', + path_id=7, + rarity=1, +) +Clockwork_Apple = RogueBlessing( + id=126, + name='Clockwork_Apple', + cn='《发条苹果》', + cht='《發條蘋果》', + en='Clockwork Apple', + jp='『時計仕掛けのリンゴ』', + path_id=7, + rarity=1, +) diff --git a/tasks/rogue/keywords/classes.py b/tasks/rogue/keywords/classes.py new file mode 100644 index 000000000..5941d0d8e --- /dev/null +++ b/tasks/rogue/keywords/classes.py @@ -0,0 +1,23 @@ +from dataclasses import dataclass +from typing import ClassVar + +from module.ocr.keyword import Keyword + + +@dataclass(repr=False) +class RogueBlessing(Keyword): + instances: ClassVar = {} + path_id: int + rarity: int + + +@dataclass(repr=False) +class RoguePath(Keyword): + instances: ClassVar = {} + + +@dataclass(repr=False) +class RogueResonance(Keyword): + instances: ClassVar = {} + path_id: int + rarity: int diff --git a/tasks/rogue/keywords/path.py b/tasks/rogue/keywords/path.py new file mode 100644 index 000000000..c9553a693 --- /dev/null +++ b/tasks/rogue/keywords/path.py @@ -0,0 +1,61 @@ +from .classes import RoguePath + +# This file was auto-generated, do not modify it manually. To generate: +# ``` python -m dev_tools.keyword_extract ``` + +Preservation = RoguePath( + id=1, + name='Preservation', + cn='存护', + cht='存護', + en='Preservation', + jp='存護', +) +Remembrance = RoguePath( + id=2, + name='Remembrance', + cn='记忆', + cht='記憶', + en='Remembrance', + jp='記憶', +) +Nihility = RoguePath( + id=3, + name='Nihility', + cn='虚无', + cht='虛無', + en='Nihility', + jp='虚無', +) +Abundance = RoguePath( + id=4, + name='Abundance', + cn='丰饶', + cht='豐饒', + en='Abundance', + jp='豊穣', +) +The_Hunt = RoguePath( + id=5, + name='The_Hunt', + cn='巡猎', + cht='巡獵', + en='The Hunt', + jp='巡狩', +) +Destruction = RoguePath( + id=6, + name='Destruction', + cn='毁灭', + cht='毀滅', + en='Destruction', + jp='壊滅', +) +Elation = RoguePath( + id=7, + name='Elation', + cn='欢愉', + cht='歡愉', + en='Elation', + jp='愉悦', +) diff --git a/tasks/rogue/keywords/resonance.py b/tasks/rogue/keywords/resonance.py new file mode 100644 index 000000000..d99f9e667 --- /dev/null +++ b/tasks/rogue/keywords/resonance.py @@ -0,0 +1,285 @@ +from .classes import RogueResonance + +# This file was auto-generated, do not modify it manually. To generate: +# ``` python -m dev_tools.keyword_extract ``` + +Path_Resonance_Preservation = RogueResonance( + id=1, + name='Path_Resonance_Preservation', + cn='命途回响:「存护」', + cht='命途迴響:「存護」', + en='Path Resonance: Preservation', + jp='運命の反響:「存護」', + path_id=1, + rarity=3, +) +Resonance_Formation_Zero_Dimensional_Reinforcement = RogueResonance( + id=2, + name='Resonance_Formation_Zero_Dimensional_Reinforcement', + cn='回响构音:零维强化', + cht='迴響構音:零維強化', + en='Resonance Formation: Zero-Dimensional Reinforcement', + jp='反響構音:析出硬化', + path_id=1, + rarity=3, +) +Resonance_Formation_Eutectic_Reaction = RogueResonance( + id=3, + name='Resonance_Formation_Eutectic_Reaction', + cn='回响构音:共晶反应', + cht='迴響構音:共晶反應', + en='Resonance Formation: Eutectic Reaction', + jp='反響構音:共晶反応', + path_id=1, + rarity=3, +) +Resonance_Formation_Isomorphous_Reaction = RogueResonance( + id=4, + name='Resonance_Formation_Isomorphous_Reaction', + cn='回响构音:均晶转变', + cht='迴響構音:均晶轉變', + en='Resonance Formation: Isomorphous Reaction', + jp='反響構音:全率固溶体', + path_id=1, + rarity=3, +) +Path_Resonance_Remembrance = RogueResonance( + id=5, + name='Path_Resonance_Remembrance', + cn='命途回响:「记忆」', + cht='命途迴響:「記憶」', + en='Path Resonance: Remembrance', + jp='運命の反響:「記憶」', + path_id=2, + rarity=3, +) +Resonance_Formation_Total_Recall = RogueResonance( + id=6, + name='Resonance_Formation_Total_Recall', + cn='回响构音:全面回忆', + cht='迴響構音:全面回憶', + en='Resonance Formation: Total Recall', + jp='反響構音:全面追憶', + path_id=2, + rarity=3, +) +Resonance_Formation_Rich_Experience = RogueResonance( + id=7, + name='Resonance_Formation_Rich_Experience', + cn='回响构音:体验的富翁', + cht='迴響構音:體驗的富翁', + en='Resonance Formation: Rich Experience', + jp='反響構音:体験の富豪', + path_id=2, + rarity=3, +) +Resonance_Formation_First_Love_Once_More = RogueResonance( + id=8, + name='Resonance_Formation_First_Love_Once_More', + cn='回响构音:第二次初恋', + cht='迴響構音:第二次初戀', + en='Resonance Formation: First Love Once More', + jp='反響構音:二度目の初恋', + path_id=2, + rarity=3, +) +Path_Resonance_Nihility = RogueResonance( + id=9, + name='Path_Resonance_Nihility', + cn='命途回响:「虚无」', + cht='命途迴響:「虛無」', + en='Path Resonance: Nihility', + jp='運命の反響:「虚無」', + path_id=3, + rarity=3, +) +Resonance_Formation_The_Doubtful_Fourfold_Root = RogueResonance( + id=10, + name='Resonance_Formation_The_Doubtful_Fourfold_Root', + cn='回响构音:怀疑的四重根', + cht='迴響構音:懷疑的四重根', + en='Resonance Formation: The Doubtful Fourfold Root', + jp='反響構音:疑いの四つの根', + path_id=3, + rarity=3, +) +Resonance_Formation_Suffering_and_Sunshine = RogueResonance( + id=11, + name='Resonance_Formation_Suffering_and_Sunshine', + cn='回响构音:苦难与阳光', + cht='迴響構音:苦難與陽光', + en='Resonance Formation: Suffering and Sunshine', + jp='反響構音:苦難と陽光', + path_id=3, + rarity=3, +) +Resonance_Formation_Outsider = RogueResonance( + id=12, + name='Resonance_Formation_Outsider', + cn='回响构音:局外人', + cht='迴響構音:局外人', + en='Resonance Formation: Outsider', + jp='反響構音:異邦人', + path_id=3, + rarity=3, +) +Path_Resonance_Abundance = RogueResonance( + id=13, + name='Path_Resonance_Abundance', + cn='命途回响:「丰饶」', + cht='命途迴響:「豐饒」', + en='Path Resonance: Abundance', + jp='運命の反響:「豊穣」', + path_id=4, + rarity=3, +) +Resonance_Formation_Terminal_Nirvana = RogueResonance( + id=14, + name='Resonance_Formation_Terminal_Nirvana', + cn='回响构音:无余涅槃', + cht='迴響構音:無餘涅槃', + en='Resonance Formation: Terminal Nirvana', + jp='反響構音:無余涅槃', + path_id=4, + rarity=3, +) +Resonance_Formation_Anicca = RogueResonance( + id=15, + name='Resonance_Formation_Anicca', + cn='回响构音:诸行无常', + cht='迴響構音:諸行無常', + en='Resonance Formation: Anicca', + jp='反響構音:諸行無常', + path_id=4, + rarity=3, +) +Resonance_Formation_Anatta = RogueResonance( + id=16, + name='Resonance_Formation_Anatta', + cn='回响构音:诸法无我', + cht='迴響構音:諸法無我', + en='Resonance Formation: Anatta', + jp='反響構音:諸法無我', + path_id=4, + rarity=3, +) +Path_Resonance_The_Hunt = RogueResonance( + id=17, + name='Path_Resonance_The_Hunt', + cn='命途回响:「巡猎」', + cht='命途迴響:「巡獵」', + en='Path Resonance: The Hunt', + jp='運命の反響:「巡狩」', + path_id=5, + rarity=3, +) +Resonance_Formation_Star_Hunter = RogueResonance( + id=18, + name='Resonance_Formation_Star_Hunter', + cn='回响构音:狩星巡日', + cht='迴響構音:狩星巡日', + en='Resonance Formation: Star Hunter', + jp='反響構音:星を狩りて日を巡る', + path_id=5, + rarity=3, +) +Resonance_Formation_Bow_and_Arrow = RogueResonance( + id=19, + name='Resonance_Formation_Bow_and_Arrow', + cn='回响构音:柘弓危矢', + cht='迴響構音:柘弓危矢', + en='Resonance Formation: Bow and Arrow', + jp='反響構音:柘弓に疾矢', + path_id=5, + rarity=3, +) +Resonance_Formation_Perfect_Aim = RogueResonance( + id=20, + name='Resonance_Formation_Perfect_Aim', + cn='回响构音:射不主皮', + cht='迴響構音:射不主皮', + en='Resonance Formation: Perfect Aim', + jp='反響構音:射は皮を主とせず', + path_id=5, + rarity=3, +) +Path_Resonance_Destruction = RogueResonance( + id=21, + name='Path_Resonance_Destruction', + cn='命途回响:「毁灭」', + cht='命途迴響:「毀滅」', + en='Path Resonance: Destruction', + jp='運命の反響:「壊滅」', + path_id=6, + rarity=3, +) +Resonance_Formation_Cataclysmic_Variable = RogueResonance( + id=22, + name='Resonance_Formation_Cataclysmic_Variable', + cn='回响构音:激变变星', + cht='迴響構音:激變變星', + en='Resonance Formation: Cataclysmic Variable', + jp='反響構音:激変星', + path_id=6, + rarity=3, +) +Resonance_Formation_Extreme_Helium_Flash = RogueResonance( + id=23, + name='Resonance_Formation_Extreme_Helium_Flash', + cn='回响构音:极端氦闪', + cht='迴響構音:極端氦閃', + en='Resonance Formation: Extreme Helium Flash', + jp='反響構音:ヘリウムフラッシュ', + path_id=6, + rarity=3, +) +Resonance_Formation_Event_Horizon = RogueResonance( + id=24, + name='Resonance_Formation_Event_Horizon', + cn='回响构音:事件视界', + cht='迴響構音:事件視界', + en='Resonance Formation: Event Horizon', + jp='反響構音:事象の地平線', + path_id=6, + rarity=3, +) +Path_Resonance_Elation = RogueResonance( + id=25, + name='Path_Resonance_Elation', + cn='命途回响:「欢愉」', + cht='命途迴響:「歡愉」', + en='Path Resonance: Elation', + jp='運命の反響:「愉悦」', + path_id=7, + rarity=3, +) +Resonance_Formation_Doomsday_Carnival = RogueResonance( + id=26, + name='Resonance_Formation_Doomsday_Carnival', + cn='回响构音:末日狂欢', + cht='迴響構音:末日狂歡', + en='Resonance Formation: Doomsday Carnival', + jp='反響構音:終末の狂宴', + path_id=7, + rarity=3, +) +Resonance_Formation_Dance_of_Growth = RogueResonance( + id=27, + name='Resonance_Formation_Dance_of_Growth', + cn='回响构音:树苗长高舞', + cht='迴響構音:樹苗長高舞', + en='Resonance Formation: Dance of Growth', + jp='反響構音:苗木が育つ踊り', + path_id=7, + rarity=3, +) +Resonance_Formation_Instant_Win = RogueResonance( + id=28, + name='Resonance_Formation_Instant_Win', + cn='回响构音:开盖有奖', + cht='迴響構音:開蓋有獎', + en='Resonance Formation: Instant Win', + jp='反響構音:もう1本', + path_id=7, + rarity=3, +) diff --git a/tasks/rogue/preset.py b/tasks/rogue/preset.py new file mode 100644 index 000000000..2c14534a3 --- /dev/null +++ b/tasks/rogue/preset.py @@ -0,0 +1,9 @@ +BLESSING_PRESET_1 = ("巡猎-3 > 《冠军晚餐•猫的摇篮》 > 丰饶众生,一法界心 > 毁灭-3 " + "> 火堆外的夜 > 巡猎-2 > 戒律性闪变 > 巡猎 > 存护-2 > reset > random") +RESONANCE_PRESET_1 = ("回响构音:均晶转变 > 回响构音:零维强化" + "> 回响构音:第二次初恋 > 回响构音:体验的富翁" + "> 回响构音:局外人 > 回响构音:怀疑的四重根" + "> 回响构音:诸法无我 > 回响构音:诸行无常" + "> 回响构音:射不主皮 > 回响构音:柘弓危矢" + "> 回响构音:激变变星 > 回响构音:极端氦闪" + "> 回响构音:末日狂欢 > 回响构音:树苗长高舞") diff --git a/tasks/rogue/selector.py b/tasks/rogue/selector.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tasks/rogue/ui.py b/tasks/rogue/ui.py new file mode 100644 index 000000000..bbb2f26be --- /dev/null +++ b/tasks/rogue/ui.py @@ -0,0 +1,14 @@ +from tasks.base.ui import UI +from tasks.rogue.assets.assets_rogue_ui import * +from tasks.rogue.keywords import * + + +class RogueUI(UI): + path: RoguePath + blessings: list + + def is_page_choose_blessing(self): + return self.image_color_count(PAGE_CHOOSE_BUFF, (245, 245, 245)) + + def is_page_choose_curio(self): + return self.appear(PAGE_CHOOSE_MIRACLE)