Refactor: Link task dungeon with daily quests

This commit is contained in:
LmeSzinc 2023-08-27 17:13:05 +08:00
parent 4719d3da60
commit a5e2eb0004
20 changed files with 2401 additions and 163 deletions

View File

@ -43,9 +43,20 @@
"Name": "Calyx_Golden_Treasures",
"NameAtDoubleCalyx": "Calyx_Golden_Treasures",
"NameAtDoubleRelic": "Cavern_of_Corrosion_Path_of_Providence",
"Team": 1,
"Support": "when_daily",
"SupportCharacter": "FirstCharacter"
"Team": 1
},
"DungeonDaily": {
"CalyxGolden": "Calyx_Golden_Treasures",
"CalyxCrimson": "Calyx_Crimson_Erudition",
"StagnantShadow": "do_not_archive",
"CavernOfCorrosion": "Cavern_of_Corrosion_Path_of_Providence"
},
"DungeonSupport": {
"Use": "when_daily",
"Character": "FirstCharacter"
},
"DungeonStorage": {
"DungeonDouble": {}
}
},
"DailyQuest": {
@ -54,6 +65,37 @@
"NextRun": "2020-01-01 00:00:00",
"Command": "DailyQuest",
"ServerUpdate": "04:00"
},
"AchievableQuest": {
"Complete_1_Daily_Mission": "not_supported",
"Clear_Calyx_Golden_1_times": "not_set",
"Complete_Calyx_Crimson_1_time": "not_set",
"Clear_Stagnant_Shadow_1_times": "not_set",
"Clear_Cavern_of_Corrosion_1_times": "not_set",
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": "not_supported",
"Inflict_Weakness_Break_5_times": "not_supported",
"Defeat_a_total_of_20_enemies": "not_supported",
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": "not_supported",
"Use_Technique_2_times": "achievable",
"Go_on_assignment_1_time": "not_set",
"Take_1_photo": "achievable",
"Destroy_3_destructible_objects": "not_supported",
"Complete_Forgotten_Hall_1_time": "not_supported",
"Complete_Echo_of_War_1_times": "not_supported",
"Complete_1_stage_in_Simulated_Universe_Any_world": "not_supported",
"Obtain_victory_in_combat_with_support_characters_1_time": "not_set",
"Use_an_Ultimate_to_deal_the_final_blow_1_time": "not_supported",
"Level_up_any_character_1_time": "not_supported",
"Level_up_any_Light_Cone_1_time": "not_supported",
"Level_up_any_Relic_1_time": "not_supported",
"Salvage_any_Relic": "achievable",
"Synthesize_Consumable_1_time": "achievable",
"Synthesize_material_1_time": "achievable",
"Use_Consumables_1_time": "achievable"
},
"DailyStorage": {
"DailyActivity": {},
"DailyQuest": {}
}
},
"BattlePass": {

View File

@ -243,17 +243,76 @@
5,
6
]
}
},
"DungeonDaily": {
"CalyxGolden": {
"type": "select",
"value": "Calyx_Golden_Treasures",
"option": [
"do_not_achieve",
"Calyx_Golden_Memories",
"Calyx_Golden_Aether",
"Calyx_Golden_Treasures"
]
},
"Support": {
"CalyxCrimson": {
"type": "select",
"value": "Calyx_Crimson_Erudition",
"option": [
"do_not_achieve",
"Calyx_Crimson_Destruction",
"Calyx_Crimson_Preservation",
"Calyx_Crimson_Hunt",
"Calyx_Crimson_Abundance",
"Calyx_Crimson_Erudition",
"Calyx_Crimson_Harmony",
"Calyx_Crimson_Nihility"
]
},
"StagnantShadow": {
"type": "select",
"value": "do_not_archive",
"option": [
"do_not_achieve",
"Stagnant_Shadow_Quanta",
"Stagnant_Shadow_Gust",
"Stagnant_Shadow_Fulmination",
"Stagnant_Shadow_Blaze",
"Stagnant_Shadow_Spike",
"Stagnant_Shadow_Rime",
"Stagnant_Shadow_Mirage",
"Stagnant_Shadow_Icicle",
"Stagnant_Shadow_Doom",
"Stagnant_Shadow_Celestial"
]
},
"CavernOfCorrosion": {
"type": "select",
"value": "Cavern_of_Corrosion_Path_of_Providence",
"option": [
"do_not_achieve",
"Cavern_of_Corrosion_Path_of_Gelid_Wind",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch",
"Cavern_of_Corrosion_Path_of_Drifting",
"Cavern_of_Corrosion_Path_of_Providence",
"Cavern_of_Corrosion_Path_of_Holy_Hymn",
"Cavern_of_Corrosion_Path_of_Conflagration",
"Cavern_of_Corrosion_Path_of_Elixir_Seekers"
]
}
},
"DungeonSupport": {
"Use": {
"type": "select",
"value": "when_daily",
"option": [
"do_not_use",
"always_use",
"when_daily"
"when_daily",
"do_not_use"
]
},
"SupportCharacter": {
"Character": {
"type": "select",
"value": "FirstCharacter",
"option": [
@ -290,6 +349,14 @@
"Yukong"
]
}
},
"DungeonStorage": {
"DungeonDouble": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredDungeonDouble"
}
}
},
"DailyQuest": {
@ -313,6 +380,397 @@
"value": "04:00",
"display": "hide"
}
},
"AchievableQuest": {
"Complete_1_Daily_Mission": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Clear_Calyx_Golden_1_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Complete_Calyx_Crimson_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Clear_Stagnant_Shadow_1_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Clear_Cavern_of_Corrosion_1_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Inflict_Weakness_Break_5_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Defeat_a_total_of_20_enemies": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Use_Technique_2_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Go_on_assignment_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Take_1_photo": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Destroy_3_destructible_objects": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Complete_Forgotten_Hall_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Complete_Echo_of_War_1_times": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Complete_1_stage_in_Simulated_Universe_Any_world": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Obtain_victory_in_combat_with_support_characters_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Use_an_Ultimate_to_deal_the_final_blow_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Level_up_any_character_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Level_up_any_Light_Cone_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Level_up_any_Relic_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Salvage_any_Relic": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Synthesize_Consumable_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Synthesize_material_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
},
"Use_Consumables_1_time": {
"type": "state",
"value": "achievable",
"option": [
"achievable",
"not_set",
"not_supported"
],
"option_bold": [
"achievable"
],
"option_light": [
"not_supported"
]
}
},
"DailyStorage": {
"DailyActivity": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredDailyActivity"
},
"DailyQuest": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredDaily"
}
}
},
"BattlePass": {

View File

@ -71,27 +71,56 @@ Optimization:
Dungeon:
Name:
# Options will be injected in config updater
# Dungeon names will be injected in config updater
value: Calyx_Golden_Treasures
option: [Calyx_Golden_Treasures, ]
option: [ ]
NameAtDoubleCalyx:
# Options will be injected in config updater
value: Calyx_Golden_Treasures
option: [ do_not_participate, ]
NameAtDoubleRelic:
# Options will be injected in config updater
value: Cavern_of_Corrosion_Path_of_Providence
option: [ do_not_participate, ]
Team:
value: 1
option: [ 1, 2, 3, 4, 5, 6 ]
Support:
DungeonDaily:
# Dungeon names will be injected in config updater
CalyxGolden:
value: Calyx_Golden_Treasures
option: [ do_not_achieve, ]
CalyxCrimson:
value: Calyx_Crimson_Erudition
option: [ do_not_achieve, ]
StagnantShadow:
value: do_not_archive
option: [ do_not_achieve, ]
CavernOfCorrosion:
value: Cavern_of_Corrosion_Path_of_Providence
option: [ do_not_achieve, ]
DungeonSupport:
Use:
value: when_daily
option: [do_not_use, always_use, when_daily]
SupportCharacter:
option: [ always_use, when_daily, do_not_use ]
Character:
# Options will be injected in config updater
value: FirstCharacter
option: [FirstCharacter, ]
option: [ FirstCharacter, ]
DungeonStorage:
DungeonDouble:
stored: StoredDungeonDouble
AchievableQuest:
# Quests will be injected in config updater
# Complete_1_Daily_Mission:
# type: state
# value: achievable
# option: [ achievable, not_set, not_supported ]
# option_bold: [ achievable, ]
DailyStorage:
DailyActivity:
stored: StoredDailyActivity
DailyQuest:
stored: StoredDaily
Assignment:
Duration:

View File

@ -25,8 +25,13 @@ Daily:
Dungeon:
- Scheduler
- Dungeon
- DungeonDaily
- DungeonSupport
- DungeonStorage
DailyQuest:
- Scheduler
- AchievableQuest
- DailyStorage
BattlePass:
- Scheduler
Assignment:

View File

@ -3,11 +3,14 @@ import datetime
import operator
import threading
from module.base.decorator import cached_property, del_cached_property
from module.base.filter import Filter
from module.base.utils import SelectedGrids
from module.config.config_generated import GeneratedConfig
from module.config.config_manual import ManualConfig
from module.config.config_updater import ConfigUpdater
from module.config.stored.stored_generated import StoredGenerated
from module.config.stored.classes import iter_attribute
from module.config.utils import *
from module.config.watcher import ConfigWatcher
from module.exception import RequestHumanTakeover, ScriptError
@ -168,6 +171,15 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
self.data, keys="Alas.Optimization.CloseGameDuringWait", default=False
)
@cached_property
def stored(self) -> StoredGenerated:
stored = StoredGenerated()
# Bind config
for _, value in iter_attribute(stored):
value._bind(self)
del_cached_property(value, '_stored')
return stored
def get_next_task(self):
"""
Calculate tasks, set pending_task and waiting_task
@ -241,6 +253,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
)
# Don't use self.modified = {}, that will create a new object.
self.modified.clear()
del_cached_property(self, 'stored')
self.write_file(self.config_name, data=self.data)
def update(self):

View File

@ -43,8 +43,50 @@ class GeneratedConfig:
Dungeon_NameAtDoubleCalyx = 'Calyx_Golden_Treasures' # do_not_participate, Calyx_Golden_Memories, Calyx_Golden_Aether, Calyx_Golden_Treasures, Calyx_Crimson_Destruction, Calyx_Crimson_Preservation, Calyx_Crimson_Hunt, Calyx_Crimson_Abundance, Calyx_Crimson_Erudition, Calyx_Crimson_Harmony, Calyx_Crimson_Nihility
Dungeon_NameAtDoubleRelic = 'Cavern_of_Corrosion_Path_of_Providence' # do_not_participate, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers
Dungeon_Team = 1 # 1, 2, 3, 4, 5, 6
Dungeon_Support = 'when_daily' # do_not_use, always_use, when_daily
Dungeon_SupportCharacter = 'FirstCharacter' # FirstCharacter, Arlan, Asta, Bailu, Blade, Bronya, Clara, DanHeng, Gepard, Herta, Himeko, Hook, JingYuan, Kafka, Luka, Luocha, March7th, Natasha, Pela, Qingque, Sampo, Seele, Serval, SilverWolf, Sushang, Tingyun, TrailblazerDestruction, TrailblazerPreservation, Welt, Yanqing, Yukong
# Group `DungeonDaily`
DungeonDaily_CalyxGolden = 'Calyx_Golden_Treasures' # do_not_achieve, Calyx_Golden_Memories, Calyx_Golden_Aether, Calyx_Golden_Treasures
DungeonDaily_CalyxCrimson = 'Calyx_Crimson_Erudition' # do_not_achieve, Calyx_Crimson_Destruction, Calyx_Crimson_Preservation, Calyx_Crimson_Hunt, Calyx_Crimson_Abundance, Calyx_Crimson_Erudition, Calyx_Crimson_Harmony, Calyx_Crimson_Nihility
DungeonDaily_StagnantShadow = 'do_not_archive' # do_not_achieve, Stagnant_Shadow_Quanta, Stagnant_Shadow_Gust, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Blaze, Stagnant_Shadow_Spike, Stagnant_Shadow_Rime, Stagnant_Shadow_Mirage, Stagnant_Shadow_Icicle, Stagnant_Shadow_Doom, Stagnant_Shadow_Celestial
DungeonDaily_CavernOfCorrosion = 'Cavern_of_Corrosion_Path_of_Providence' # do_not_achieve, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers
# Group `DungeonSupport`
DungeonSupport_Use = 'when_daily' # always_use, when_daily, do_not_use
DungeonSupport_Character = 'FirstCharacter' # FirstCharacter, Arlan, Asta, Bailu, Blade, Bronya, Clara, DanHeng, Gepard, Herta, Himeko, Hook, JingYuan, Kafka, Luka, Luocha, March7th, Natasha, Pela, Qingque, Sampo, Seele, Serval, SilverWolf, Sushang, Tingyun, TrailblazerDestruction, TrailblazerPreservation, Welt, Yanqing, Yukong
# Group `DungeonStorage`
DungeonStorage_DungeonDouble = {}
# Group `AchievableQuest`
AchievableQuest_Complete_1_Daily_Mission = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Clear_Calyx_Golden_1_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Complete_Calyx_Crimson_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Clear_Stagnant_Shadow_1_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Clear_Cavern_of_Corrosion_1_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_In_a_single_battle_inflict_3_Weakness_Break_of_different_Types = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Inflict_Weakness_Break_5_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Defeat_a_total_of_20_enemies = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Enter_combat_by_attacking_enemy_Weakness_and_win_3_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Use_Technique_2_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Go_on_assignment_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Take_1_photo = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Destroy_3_destructible_objects = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Complete_Forgotten_Hall_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Complete_Echo_of_War_1_times = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Complete_1_stage_in_Simulated_Universe_Any_world = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Obtain_victory_in_combat_with_support_characters_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Use_an_Ultimate_to_deal_the_final_blow_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Level_up_any_character_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Level_up_any_Light_Cone_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Level_up_any_Relic_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Salvage_any_Relic = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Synthesize_Consumable_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Synthesize_material_1_time = 'achievable' # achievable, not_set, not_supported
AchievableQuest_Use_Consumables_1_time = 'achievable' # achievable, not_set, not_supported
# Group `DailyStorage`
DailyStorage_DailyActivity = {}
DailyStorage_DailyQuest = {}
# Group `Assignment`
Assignment_Duration = 20 # 4, 8, 12, 20

View File

@ -8,7 +8,7 @@ class ManualConfig:
SCHEDULER_PRIORITY = """
Restart
> Dungeon > Assignment > DailyQuest > BattlePass
> DailyQuest > Dungeon > Assignment > BattlePass
"""
"""

View File

@ -4,7 +4,7 @@ from cached_property import cached_property
from deploy.Windows.utils import DEPLOY_TEMPLATE, poor_yaml_read, poor_yaml_write
from module.base.timer import timer
from module.config.server import to_package, VALID_PACKAGE, VALID_CHANNEL_PACKAGE
from module.config.server import VALID_CHANNEL_PACKAGE, VALID_PACKAGE, to_package
from module.config.utils import *
CONFIG_IMPORT = '''
@ -32,6 +32,11 @@ def gui_lang_to_ingame_lang(lang: str) -> str:
return DICT_GUI_TO_INGAME.get(lang, 'en')
def get_generator():
from module.base.code_generator import CodeGenerator
return CodeGenerator()
class ConfigGenerator:
@cached_property
def argument(self):
@ -47,6 +52,55 @@ class ConfigGenerator:
"""
data = {}
raw = read_file(filepath_argument('argument'))
def option_add(keys, options):
options = deep_get(raw, keys=keys, default=[]) + options
deep_set(raw, keys=keys, value=options)
# Insert dungeons
from tasks.dungeon.keywords import DungeonList
option_add(
keys='Dungeon.Name.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_daily_dungeon])
# Double events
option_add(
keys='Dungeon.NameAtDoubleCalyx.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx])
option_add(
keys='Dungeon.NameAtDoubleRelic.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Cavern_of_Corrosion])
# Dungeon daily
option_add(
keys='DungeonDaily.CalyxGolden.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Golden])
option_add(
keys='DungeonDaily.CalyxCrimson.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Crimson])
option_add(
keys='DungeonDaily.StagnantShadow.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Stagnant_Shadow])
option_add(
keys='DungeonDaily.CavernOfCorrosion.option',
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Cavern_of_Corrosion])
# Insert characters
from tasks.character.keywords import CharacterList
unsupported_characters = ["DanHengImbibitorLunae"]
characters = [character.name for character in CharacterList.instances.values()
if character.name not in unsupported_characters]
option_add(keys='DungeonSupport.Character.option', options=characters)
# Insert daily quests
from tasks.daily.keywords import DailyQuest
for quest in DailyQuest.instances.values():
quest: DailyQuest
deep_set(raw, keys=['AchievableQuest', quest.name], value={
'type': 'state',
'value': 'achievable',
'option': ['achievable', 'not_set', 'not_supported'],
'option_bold': ['achievable'],
'option_light': ['not_supported'],
})
# Load
for path, value in deep_iter(raw, depth=2):
arg = {
'type': 'input',
@ -56,6 +110,9 @@ class ConfigGenerator:
if not isinstance(value, dict):
value = {'value': value}
arg['type'] = data_to_type(value, arg=path[1])
if arg['type'] == 'stored':
value['value'] = {}
arg['display'] = 'hide' # Hide `stored` by default
if isinstance(value['value'], datetime):
arg['type'] = 'datetime'
arg['validate'] = 'datetime'
@ -63,14 +120,6 @@ class ConfigGenerator:
arg.update(value)
deep_set(data, keys=path, value=arg)
# Define storage group
# arg = {
# 'type': 'storage',
# 'value': {},
# 'valuetype': 'ignore',
# 'display': 'disabled',
# }
# deep_set(data, keys=['Storage', 'Storage'], value=arg)
return data
@cached_property
@ -216,6 +265,28 @@ class ConfigGenerator:
for text in lines:
f.write(text + '\n')
@timer
def generate_stored(self):
import module.config.stored.classes as classes
gen = get_generator()
gen.add('from module.config.stored.classes import (')
with gen.tab():
for cls in sorted([name for name in dir(classes) if name.startswith('Stored')]):
gen.add(cls + ',')
gen.add(')')
gen.Empty()
gen.Empty()
gen.Empty()
gen.CommentAutoGenerage('module/config/config_updater.py')
with gen.Class('StoredGenerated'):
for path, data in deep_iter(self.args, depth=3):
cls = data.get('stored')
if cls:
gen.add(f'{path[-1]} = {cls}("{".".join(path)}")')
gen.write('module/config/stored/stored_generated.py')
@timer
def generate_i18n(self, lang):
"""
@ -282,27 +353,44 @@ class ConfigGenerator:
if dungeon.name in dailies:
value = dungeon.__getattribute__(ingame_lang)
deep_set(new, keys=['Dungeon', 'Name', dungeon.name], value=value)
# Copy dungeon i18n to double events
for dungeon in deep_get(new, keys='Dungeon.NameAtDoubleCalyx').values():
if '_' in dungeon:
value = deep_get(new, keys=['Dungeon', 'Name', dungeon])
if value:
deep_set(new, keys=['Dungeon', 'NameAtDoubleCalyx', dungeon], value=value)
for dungeon in deep_get(new, keys='Dungeon.NameAtDoubleRelic').values():
if '_' in dungeon:
value = deep_get(new, keys=['Dungeon', 'Name', dungeon])
if value:
deep_set(new, keys=['Dungeon', 'NameAtDoubleRelic', dungeon], value=value)
# Copy dungeon i18n to double events
def update_dungeon_names(keys):
for dungeon in deep_get(new, keys=keys).values():
if '_' in dungeon:
value = deep_get(new, keys=['Dungeon', 'Name', dungeon])
if value:
deep_set(new, keys=f'{keys}.{dungeon}', value=value)
update_dungeon_names('Dungeon.NameAtDoubleCalyx')
update_dungeon_names('Dungeon.NameAtDoubleRelic')
update_dungeon_names('DungeonDaily.CalyxGolden')
update_dungeon_names('DungeonDaily.CalyxCrimson')
update_dungeon_names('DungeonDaily.StagnantShadow')
update_dungeon_names('DungeonDaily.CavernOfCorrosion')
# Character names
from tasks.character.keywords import CharacterList
ingame_lang = gui_lang_to_ingame_lang(lang)
characters = deep_get(self.argument, keys='Dungeon.SupportCharacter.option')
characters = deep_get(self.argument, keys='DungeonSupport.Character.option')
for character in CharacterList.instances.values():
if character.name in characters:
value = character.__getattribute__(ingame_lang)
if "Trailblazer" in value:
continue
deep_set(new, keys=['Dungeon', 'SupportCharacter', character.name], value=value)
deep_set(new, keys=['DungeonSupport', 'Character', character.name], value=value)
# Daily quests
from tasks.daily.keywords import DailyQuest
for quest in DailyQuest.instances.values():
value = quest.__getattribute__(ingame_lang)
deep_set(new, keys=['AchievableQuest', quest.name, 'name'], value=value)
# deep_set(new, keys=['DailyQuest', quest.name, 'help'], value='')
copy_from = 'Complete_1_Daily_Mission'
if quest.name != copy_from:
for option in deep_get(self.args, keys=['DailyQuest', 'AchievableQuest', copy_from, 'option']):
value = deep_get(new, keys=['AchievableQuest', copy_from, option])
deep_set(new, keys=['AchievableQuest', quest.name, option], value=value)
# GUI i18n
for path, _ in deep_iter(self.gui, depth=2):
@ -371,30 +459,6 @@ class ConfigGenerator:
# update('template-docker', docker)
# update('template-docker-cn', docker, cn)
def insert_dungeon(self):
from tasks.dungeon.keywords import DungeonList
dungeons = [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_daily_dungeon]
deep_set(self.argument, keys='Dungeon.Name.option', value=dungeons)
deep_set(self.args, keys='Dungeon.Dungeon.Name.option', value=dungeons)
from tasks.character.keywords import CharacterList
unsupported_characters = ["DanHengImbibitorLunae"]
characters = ['FirstCharacter'] + [character.name for character in CharacterList.instances.values() if
character.name not in unsupported_characters]
deep_set(self.argument, keys='Dungeon.SupportCharacter.option', value=characters)
deep_set(self.args, keys='Dungeon.Dungeon.SupportCharacter.option', value=characters)
# Double events
dungeons = deep_get(self.argument, keys='Dungeon.NameAtDoubleCalyx.option')
dungeons += [dungeon.name for dungeon in DungeonList.instances.values()
if dungeon.is_Calyx_Golden or dungeon.is_Calyx_Crimson]
deep_set(self.argument, keys='Dungeon.NameAtDoubleCalyx.option', value=dungeons)
deep_set(self.args, keys='Dungeon.Dungeon.NameAtDoubleCalyx.option', value=dungeons)
dungeons = deep_get(self.argument, keys='Dungeon.NameAtDoubleRelic.option')
dungeons += [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Cavern_of_Corrosion]
deep_set(self.argument, keys='Dungeon.NameAtDoubleRelic.option', value=dungeons)
deep_set(self.args, keys='Dungeon.Dungeon.NameAtDoubleRelic.option', value=dungeons)
def insert_assignment(self):
from tasks.assignment.keywords import AssignmentEntry
assignments = [entry.name for entry in AssignmentEntry.instances.values()]
@ -414,13 +478,13 @@ class ConfigGenerator:
_ = self.args
_ = self.menu
# _ = self.event
self.insert_dungeon()
self.insert_assignment()
self.insert_package()
# self.insert_server()
write_file(filepath_args(), self.args)
write_file(filepath_args('menu'), self.menu)
self.generate_code()
self.generate_stored()
for lang in LANGUAGES:
self.generate_i18n(lang)
self.generate_deploy_template()
@ -429,6 +493,8 @@ class ConfigGenerator:
class ConfigUpdater:
# source, target, (optional)convert_func
redirection = [
('Dungeon.Dungeon.Support', 'Dungeon.DungeonSupport.Use'),
('Dungeon.Dungeon.SupportCharacter', 'Dungeon.DungeonSupport.Character'),
]
@cached_property
@ -449,7 +515,9 @@ class ConfigUpdater:
def deep_load(keys):
data = deep_get(self.args, keys=keys, default={})
value = deep_get(old, keys=keys, default=data['value'])
if is_template or value is None or value == '' or data['type'] == 'lock' or data.get('display') == 'hide':
typ = data['type']
display = data.get('display')
if is_template or value is None or value == '' or typ == 'lock' or (display == 'hide' and typ != 'stored'):
value = data['value']
value = parse_value(value, data=data)
deep_set(new, keys=keys, value=value)
@ -459,6 +527,7 @@ class ConfigUpdater:
if not is_template:
new = self.config_redirect(old, new)
new = self.update_state(new)
return new
@ -511,6 +580,53 @@ class ConfigUpdater:
return new
@staticmethod
def update_state(data):
def set_daily(quest, value):
if value is True:
value = 'achievable'
if value is False:
value = 'not_set'
deep_set(data, keys=['DailyQuest', 'AchievableQuest', quest], value=value)
set_daily('Complete_1_Daily_Mission', 'not_supported')
# Dungeon
dungeon = deep_get(data, keys='Dungeon.Scheduler.Enable')
set_daily('Clear_Calyx_Golden_1_times',
dungeon and deep_get(data, 'Dungeon.DungeonDaily.CalyxGolden') != 'do_not_achieve')
set_daily('Complete_Calyx_Crimson_1_time',
dungeon and deep_get(data, 'Dungeon.DungeonDaily.CalyxCrimson') != 'do_not_achieve')
set_daily('Clear_Stagnant_Shadow_1_times',
dungeon and deep_get(data, 'Dungeon.DungeonDaily.StagnantShadow') != 'do_not_achieve')
set_daily('Clear_Cavern_of_Corrosion_1_times',
dungeon and deep_get(data, 'Dungeon.DungeonDaily.CavernOfCorrosion') != 'do_not_achieve')
# Combat requirements
set_daily('In_a_single_battle_inflict_3_Weakness_Break_of_different_Types', 'not_supported')
set_daily('Inflict_Weakness_Break_5_times', 'not_supported')
set_daily('Defeat_a_total_of_20_enemies', 'not_supported')
set_daily('Enter_combat_by_attacking_enemy_Weakness_and_win_3_times', 'not_supported')
set_daily('Use_Technique_2_times', 'achievable')
# Other game systems
set_daily('Go_on_assignment_1_time', deep_get(data, 'Assignment.Scheduler.Enable'))
set_daily('Take_1_photo', 'achievable')
set_daily('Destroy_3_destructible_objects', 'not_supported')
set_daily('Complete_Forgotten_Hall_1_time', 'not_supported')
set_daily('Complete_Echo_of_War_1_times', 'not_supported')
set_daily('Complete_1_stage_in_Simulated_Universe_Any_world', 'not_supported')
set_daily('Obtain_victory_in_combat_with_support_characters_1_time',
dungeon and deep_get(data, 'Dungeon.DungeonSupport.Use') in ['when_daily', 'always_use'])
set_daily('Use_an_Ultimate_to_deal_the_final_blow_1_time', 'not_supported')
# Build
set_daily('Level_up_any_character_1_time', 'not_supported')
set_daily('Level_up_any_Light_Cone_1_time', 'not_supported')
set_daily('Level_up_any_Relic_1_time', 'not_supported')
# Items
set_daily('Salvage_any_Relic', 'achievable')
set_daily('Synthesize_Consumable_1_time', 'achievable')
set_daily('Synthesize_material_1_time', 'achievable')
set_daily('Use_Consumables_1_time', 'achievable')
return data
def read_file(self, config_name, is_template=False):
"""
Read and update config file.

View File

@ -247,18 +247,77 @@
"4": "4",
"5": "5",
"6": "6"
}
},
"DungeonDaily": {
"_info": {
"name": "Daily Quest Settings",
"help": "Clear required dungeon once to achieve daily quests"
},
"Support": {
"name": "Enable buddy support",
"help": "Whether to enable buddy support",
"do_not_use": "do_not_use",
"always_use": "always_use",
"when_daily": "when_daily"
"CalyxGolden": {
"name": "Clear Calyx Golden 1 times",
"help": "",
"do_not_achieve": "Don't Do This Quest",
"Calyx_Golden_Memories": "Material: Character EXP (Bud of Memories)",
"Calyx_Golden_Aether": "Material: Light Cone EXP (Bud of Aether)",
"Calyx_Golden_Treasures": "Material: Credit (Bud of Treasures)"
},
"SupportCharacter": {
"name": "Dungeon.SupportCharacter.name",
"help": "Dungeon.SupportCharacter.help",
"FirstCharacter": "FirstCharacter",
"CalyxCrimson": {
"name": "Clear Calyx Crimson 1 times",
"help": "",
"do_not_achieve": "Don't Do This Quest",
"Calyx_Crimson_Destruction": "Trace: Destruction (Bud of Destruction)",
"Calyx_Crimson_Preservation": "Trace: Preservation (Bud of Preservation)",
"Calyx_Crimson_Hunt": "Trace: Hunt (Bud of Hunt)",
"Calyx_Crimson_Abundance": "Trace: Abundance (Bud of Abundance)",
"Calyx_Crimson_Erudition": "Trace: Erudition (Bud of Erudition)",
"Calyx_Crimson_Harmony": "Trace: Harmony (Bud of Harmony)",
"Calyx_Crimson_Nihility": "Trace: Nihility (Bud of Nihility)"
},
"StagnantShadow": {
"name": "Clear Stagnant Shadow 1 times",
"help": "",
"do_not_achieve": "Don't Do This Quest",
"Stagnant_Shadow_Quanta": "Ascension: Quantum (Shape of Quanta)",
"Stagnant_Shadow_Gust": "Ascension: Wind (Shape of Gust)",
"Stagnant_Shadow_Fulmination": "Ascension: Lighting (Shape of Fulmination)",
"Stagnant_Shadow_Blaze": "Ascension: Fire (Shape of Blaze)",
"Stagnant_Shadow_Spike": "Ascension: Physical (Shape of Spike)",
"Stagnant_Shadow_Rime": "Ascension: Ice (Shape of Rime)",
"Stagnant_Shadow_Mirage": "Ascension: Imaginary (Shape of Mirage)",
"Stagnant_Shadow_Icicle": "Ascension: Ice (Shape of Icicle)",
"Stagnant_Shadow_Doom": "Ascension: Lighting (Shape of Doom)",
"Stagnant_Shadow_Celestial": "Ascension: Wind (Shape of Celestial)"
},
"CavernOfCorrosion": {
"name": "Clear Cavern of Corrosion 1 times",
"help": "",
"do_not_achieve": "Don't Do This Quest",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Relics: Ice Set & Wind Set (Path of Gelid Wind)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Relics: Physical Set & Break Effect Set (Path of Jabbing Punch)",
"Cavern_of_Corrosion_Path_of_Drifting": "Relics: Healing Set & Musketeer Set (Path of Drifting)",
"Cavern_of_Corrosion_Path_of_Providence": "Relics: Guard Set & Quantum Set (Path of Providence)",
"Cavern_of_Corrosion_Path_of_Holy_Hymn": "Relics: DEF Set & Lighting Set (Path of Holy Hymn)",
"Cavern_of_Corrosion_Path_of_Conflagration": "Relics: Fire Set & Imaginary Set (Path of Conflagration)",
"Cavern_of_Corrosion_Path_of_Elixir_Seekers": "Relics: HP Set & SPD Set (Path of Elixir Seekers)"
}
},
"DungeonSupport": {
"_info": {
"name": "Support Settings",
"help": ""
},
"Use": {
"name": "Use Friend Support",
"help": "",
"always_use": "Always Use",
"when_daily": "Use Only When Required by Dailies",
"do_not_use": "Don't Use"
},
"Character": {
"name": "Support Character",
"help": "Select a friend support character, if not found, select the default (first) role",
"FirstCharacter": "First Character",
"Arlan": "Arlan",
"Asta": "Asta",
"Bailu": "Bailu",
@ -284,13 +343,218 @@
"SilverWolf": "Silver Wolf",
"Sushang": "Sushang",
"Tingyun": "Tingyun",
"TrailblazerDestruction": "TrailblazerDestruction",
"TrailblazerPreservation": "TrailblazerPreservation",
"TrailblazerDestruction": "Trailblazer Destruction",
"TrailblazerPreservation": "Trailblazer Preservation",
"Welt": "Welt",
"Yanqing": "Yanqing",
"Yukong": "Yukong"
}
},
"DungeonStorage": {
"_info": {
"name": "DungeonStorage._info.name",
"help": "DungeonStorage._info.help"
},
"DungeonDouble": {
"name": "DungeonStorage.DungeonDouble.name",
"help": "DungeonStorage.DungeonDouble.help"
}
},
"AchievableQuest": {
"_info": {
"name": "Achievable Quests",
"help": "When the task status is \"Not Set\", you need to configure the SRC as required to achieve the quest\nNote: Please keep more tasks in \"Achievable\" status, otherwise SRC may not be able to grind 500 activity"
},
"Complete_1_Daily_Mission": {
"name": "Complete 1 Daily Mission",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Clear_Calyx_Golden_1_times": {
"name": "Clear Calyx (Golden) 1 time(s)",
"help": "Need to configure and enable the \"Dungeon\" task",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Complete_Calyx_Crimson_1_time": {
"name": "Complete Calyx (Crimson) 1 time",
"help": "Need to configure and enable the \"Dungeon\" task",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Clear_Stagnant_Shadow_1_times": {
"name": "Clear Stagnant Shadow 1 time(s)",
"help": "Need to configure and enable the \"Dungeon\" task",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Clear_Cavern_of_Corrosion_1_times": {
"name": "Clear Cavern of Corrosion 1 time(s)",
"help": "Need to configure and enable the \"Dungeon\" task",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": {
"name": "In a single battle, inflict 3 Weakness Break of different Types",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Inflict_Weakness_Break_5_times": {
"name": "Inflict Weakness Break 5 times",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Defeat_a_total_of_20_enemies": {
"name": "Defeat a total of 20 enemies",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": {
"name": "Enter combat by attacking enemy's Weakness and win 3 times",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Use_Technique_2_times": {
"name": "Use Technique 2 times",
"help": "Achievable by default, will go to the abyssal 1 and use technique twice",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Go_on_assignment_1_time": {
"name": "Go on assignment 1 time",
"help": "Need to configure and enable the \"Assignment\" task",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Take_1_photo": {
"name": "Take 1 photo",
"help": "Achievable by default",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Destroy_3_destructible_objects": {
"name": "Destroy 3 destructible objects",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Complete_Forgotten_Hall_1_time": {
"name": "Complete Forgotten Hall 1 time",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Complete_Echo_of_War_1_times": {
"name": "Complete Echo of War 1 time(s)",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Complete_1_stage_in_Simulated_Universe_Any_world": {
"name": "Complete 1 stage in Simulated Universe (Any world)",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Obtain_victory_in_combat_with_support_characters_1_time": {
"name": "Obtain victory in combat with support characters 1 time",
"help": "Need to configure and enable the \"Dungeon\" task, configure support settings also",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Use_an_Ultimate_to_deal_the_final_blow_1_time": {
"name": "Use an Ultimate to deal the final blow 1 time",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Level_up_any_character_1_time": {
"name": "Level up any character 1 time",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Level_up_any_Light_Cone_1_time": {
"name": "Level up any Light Cone 1 time",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Level_up_any_Relic_1_time": {
"name": "Level up any Relic 1 time",
"help": "",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Salvage_any_Relic": {
"name": "Salvage any Relic",
"help": "Achievable by default, will salvage the first one in reverse order of rarity",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Synthesize_Consumable_1_time": {
"name": "Synthesize Consumable 1 time",
"help": "Achievable by default, will synthesize low-rarity snacks",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Synthesize_material_1_time": {
"name": "Synthesize material 1 time",
"help": "Achievable by default, will synthesize low-rarity material",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
},
"Use_Consumables_1_time": {
"name": "Use Consumables 1 time",
"help": "Achievable by default, will use gear. If there is no material, synthesized before use",
"achievable": "Achievable",
"not_set": "Not Set",
"not_supported": "Not Supported Yet"
}
},
"DailyStorage": {
"_info": {
"name": "DailyStorage._info.name",
"help": "DailyStorage._info.help"
},
"DailyActivity": {
"name": "DailyStorage.DailyActivity.name",
"help": "DailyStorage.DailyActivity.help"
},
"DailyQuest": {
"name": "DailyStorage.DailyQuest.name",
"help": "DailyStorage.DailyQuest.help"
}
},
"Assignment": {
"_info": {
"name": "Assignment Settings",

View File

@ -247,17 +247,76 @@
"4": "4",
"5": "5",
"6": "6"
}
},
"DungeonDaily": {
"_info": {
"name": "DungeonDaily._info.name",
"help": "DungeonDaily._info.help"
},
"Support": {
"name": "Dungeon.Support.name",
"help": "Dungeon.Support.help",
"do_not_use": "do_not_use",
"CalyxGolden": {
"name": "DungeonDaily.CalyxGolden.name",
"help": "DungeonDaily.CalyxGolden.help",
"do_not_achieve": "do_not_achieve",
"Calyx_Golden_Memories": "疑似花萼(金)・回憶の蕾",
"Calyx_Golden_Aether": "疑似花萼(金)・エーテルの蕾",
"Calyx_Golden_Treasures": "疑似花萼(金)・秘蔵の蕾"
},
"CalyxCrimson": {
"name": "DungeonDaily.CalyxCrimson.name",
"help": "DungeonDaily.CalyxCrimson.help",
"do_not_achieve": "do_not_achieve",
"Calyx_Crimson_Destruction": "疑似花萼(赤)・壊滅の蕾",
"Calyx_Crimson_Preservation": "疑似花萼(赤)・存護の蕾",
"Calyx_Crimson_Hunt": "疑似花萼(赤)・巡狩の蕾",
"Calyx_Crimson_Abundance": "疑似花萼(赤)・豊穣の蕾",
"Calyx_Crimson_Erudition": "疑似花萼(赤)・知恵の蕾",
"Calyx_Crimson_Harmony": "疑似花萼(赤)・調和の蕾",
"Calyx_Crimson_Nihility": "疑似花萼(赤)・虚無の蕾"
},
"StagnantShadow": {
"name": "DungeonDaily.StagnantShadow.name",
"help": "DungeonDaily.StagnantShadow.help",
"do_not_achieve": "do_not_achieve",
"Stagnant_Shadow_Quanta": "凝結虚影・虚海の形",
"Stagnant_Shadow_Gust": "凝結虚影・薫風の形",
"Stagnant_Shadow_Fulmination": "凝結虚影・鳴雷の形",
"Stagnant_Shadow_Blaze": "凝結虚影・炎華の形",
"Stagnant_Shadow_Spike": "凝結虚影・切先の形",
"Stagnant_Shadow_Rime": "凝結虚影・霜晶の形",
"Stagnant_Shadow_Mirage": "凝結虚影・幻光の形",
"Stagnant_Shadow_Icicle": "凝結虚影・氷柱の形",
"Stagnant_Shadow_Doom": "凝結虚影・震厄の形",
"Stagnant_Shadow_Celestial": "凝結虚影・天人の形"
},
"CavernOfCorrosion": {
"name": "DungeonDaily.CavernOfCorrosion.name",
"help": "DungeonDaily.CavernOfCorrosion.help",
"do_not_achieve": "do_not_achieve",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "侵蝕トンネル・霜風の路",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "侵蝕トンネル・迅拳の路",
"Cavern_of_Corrosion_Path_of_Drifting": "侵蝕トンネル・漂泊の路",
"Cavern_of_Corrosion_Path_of_Providence": "侵蝕トンネル・睿治の路",
"Cavern_of_Corrosion_Path_of_Holy_Hymn": "侵蝕トンネル・聖頌の路",
"Cavern_of_Corrosion_Path_of_Conflagration": "侵蝕トンネル・野焔の路",
"Cavern_of_Corrosion_Path_of_Elixir_Seekers": "侵蝕トンネル・薬使の路"
}
},
"DungeonSupport": {
"_info": {
"name": "DungeonSupport._info.name",
"help": "DungeonSupport._info.help"
},
"Use": {
"name": "DungeonSupport.Use.name",
"help": "DungeonSupport.Use.help",
"always_use": "always_use",
"when_daily": "when_daily"
"when_daily": "when_daily",
"do_not_use": "do_not_use"
},
"SupportCharacter": {
"name": "Dungeon.SupportCharacter.name",
"help": "Dungeon.SupportCharacter.help",
"Character": {
"name": "DungeonSupport.Character.name",
"help": "DungeonSupport.Character.help",
"FirstCharacter": "FirstCharacter",
"Arlan": "アーラン",
"Asta": "アスター",
@ -291,6 +350,211 @@
"Yukong": "御空"
}
},
"DungeonStorage": {
"_info": {
"name": "DungeonStorage._info.name",
"help": "DungeonStorage._info.help"
},
"DungeonDouble": {
"name": "DungeonStorage.DungeonDouble.name",
"help": "DungeonStorage.DungeonDouble.help"
}
},
"AchievableQuest": {
"_info": {
"name": "AchievableQuest._info.name",
"help": "AchievableQuest._info.help"
},
"Complete_1_Daily_Mission": {
"name": "デイリークエストを1回クリアする",
"help": "AchievableQuest.Complete_1_Daily_Mission.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Clear_Calyx_Golden_1_times": {
"name": "「疑似花萼」を1回クリアする",
"help": "AchievableQuest.Clear_Calyx_Golden_1_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Complete_Calyx_Crimson_1_time": {
"name": "「疑似花萼」を1回クリアする",
"help": "AchievableQuest.Complete_Calyx_Crimson_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Clear_Stagnant_Shadow_1_times": {
"name": "「凝結虚影」を1回クリアする",
"help": "AchievableQuest.Clear_Stagnant_Shadow_1_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Clear_Cavern_of_Corrosion_1_times": {
"name": "「侵蝕トンネル」を1回クリアする",
"help": "AchievableQuest.Clear_Cavern_of_Corrosion_1_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": {
"name": "一度の戦闘で、異なる3種の属性の弱点撃破を発動する",
"help": "AchievableQuest.In_a_single_battle_inflict_3_Weakness_Break_of_different_Types.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Inflict_Weakness_Break_5_times": {
"name": "累計で弱点撃破効果を5回発動する",
"help": "AchievableQuest.Inflict_Weakness_Break_5_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Defeat_a_total_of_20_enemies": {
"name": "敵を累計で20体倒す",
"help": "AchievableQuest.Defeat_a_total_of_20_enemies.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": {
"name": "弱点を攻撃して戦闘に入り、3回勝利する",
"help": "AchievableQuest.Enter_combat_by_attacking_enemy_Weakness_and_win_3_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Use_Technique_2_times": {
"name": "秘技を累計2回発動する",
"help": "AchievableQuest.Use_Technique_2_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Go_on_assignment_1_time": {
"name": "依頼に1回派遣する",
"help": "AchievableQuest.Go_on_assignment_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Take_1_photo": {
"name": "1回撮影する",
"help": "AchievableQuest.Take_1_photo.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Destroy_3_destructible_objects": {
"name": "破壊できるオブジェクトを累計で3つ破壊する",
"help": "AchievableQuest.Destroy_3_destructible_objects.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Complete_Forgotten_Hall_1_time": {
"name": "「忘却の庭」を1回クリアする",
"help": "AchievableQuest.Complete_Forgotten_Hall_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Complete_Echo_of_War_1_times": {
"name": "「歴戦余韻」を1回クリアする",
"help": "AchievableQuest.Complete_Echo_of_War_1_times.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Complete_1_stage_in_Simulated_Universe_Any_world": {
"name": "「模擬宇宙」のエリアを1つクリアする任意の世界",
"help": "AchievableQuest.Complete_1_stage_in_Simulated_Universe_Any_world.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Obtain_victory_in_combat_with_support_characters_1_time": {
"name": "サポートキャラを使い、戦闘に1回勝利する",
"help": "AchievableQuest.Obtain_victory_in_combat_with_support_characters_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Use_an_Ultimate_to_deal_the_final_blow_1_time": {
"name": "必殺技で最後の一撃を1回与える",
"help": "AchievableQuest.Use_an_Ultimate_to_deal_the_final_blow_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Level_up_any_character_1_time": {
"name": "任意のキャラを1回レベルアップする",
"help": "AchievableQuest.Level_up_any_character_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Level_up_any_Light_Cone_1_time": {
"name": "任意の光円錐を1回レベルアップする",
"help": "AchievableQuest.Level_up_any_Light_Cone_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Level_up_any_Relic_1_time": {
"name": "任意の遺物を1回レベルアップする",
"help": "AchievableQuest.Level_up_any_Relic_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Salvage_any_Relic": {
"name": "任意の遺物1つを分解する",
"help": "AchievableQuest.Salvage_any_Relic.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Synthesize_Consumable_1_time": {
"name": "消耗品を1回合成する",
"help": "AchievableQuest.Synthesize_Consumable_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Synthesize_material_1_time": {
"name": "素材を1回合成する",
"help": "AchievableQuest.Synthesize_material_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
},
"Use_Consumables_1_time": {
"name": "消耗品を1個使う",
"help": "AchievableQuest.Use_Consumables_1_time.help",
"achievable": "achievable",
"not_set": "not_set",
"not_supported": "not_supported"
}
},
"DailyStorage": {
"_info": {
"name": "DailyStorage._info.name",
"help": "DailyStorage._info.help"
},
"DailyActivity": {
"name": "DailyStorage.DailyActivity.name",
"help": "DailyStorage.DailyActivity.help"
},
"DailyQuest": {
"name": "DailyStorage.DailyQuest.name",
"help": "DailyStorage.DailyQuest.help"
}
},
"Assignment": {
"_info": {
"name": "依頼設定",

View File

@ -31,7 +31,7 @@
"help": ""
},
"Assignment": {
"name": "委托设置",
"name": "委托",
"help": ""
}
},
@ -247,15 +247,74 @@
"4": "4",
"5": "5",
"6": "6"
}
},
"DungeonDaily": {
"_info": {
"name": "每日任务设置",
"help": "打一次特定的本,以满足每日任务的要求"
},
"Support": {
"name": "启用好友支援",
"help": "是否启用好友支援",
"do_not_use": "否",
"always_use": "是",
"when_daily": "仅当每日任务需要时"
"CalyxGolden": {
"name": "完成1次拟造花萼",
"help": "",
"do_not_achieve": "不完成这个任务",
"Calyx_Golden_Memories": "材料:角色经验(回忆之蕾•拟造花萼金)",
"Calyx_Golden_Aether": "材料:武器经验(以太之蕾•拟造花萼金)",
"Calyx_Golden_Treasures": "材料:信用点(藏珍之蕾•拟造花萼金)"
},
"SupportCharacter": {
"CalyxCrimson": {
"name": "完成1次拟造花萼",
"help": "",
"do_not_achieve": "不完成这个任务",
"Calyx_Crimson_Destruction": "行迹材料:毁灭(毁灭之蕾•拟造花萼赤)",
"Calyx_Crimson_Preservation": "行迹材料:存护(存护之蕾•拟造花萼赤)",
"Calyx_Crimson_Hunt": "行迹材料:巡猎(存护之蕾•拟造花萼赤)",
"Calyx_Crimson_Abundance": "行迹材料:丰饶(丰饶之蕾•拟造花萼赤)",
"Calyx_Crimson_Erudition": "行迹材料:智识(智识之蕾•拟造花萼赤)",
"Calyx_Crimson_Harmony": "行迹材料:同谐(同谐之蕾•拟造花萼赤)",
"Calyx_Crimson_Nihility": "行迹材料:虚无(虚无之蕾•拟造花萼赤)"
},
"StagnantShadow": {
"name": "完成1次凝滞虚影",
"help": "",
"do_not_achieve": "不完成这个任务",
"Stagnant_Shadow_Quanta": "角色晋阶材料:量子(空海之形•凝滞虚影)",
"Stagnant_Shadow_Gust": "角色晋阶材料:风(巽风之形•凝滞虚影)",
"Stagnant_Shadow_Fulmination": "角色晋阶材料:雷(鸣雷之形•凝滞虚影)",
"Stagnant_Shadow_Blaze": "角色晋阶材料:火(炎华之形•凝滞虚影)",
"Stagnant_Shadow_Spike": "角色晋阶材料:物理(锋芒之形•凝滞虚影)",
"Stagnant_Shadow_Rime": "角色晋阶材料:冰(霜晶之形•凝滞虚影)",
"Stagnant_Shadow_Mirage": "角色晋阶材料:虚数(幻光之形•凝滞虚影)",
"Stagnant_Shadow_Icicle": "角色晋阶材料:冰(冰棱之形•凝滞虚影)",
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(震厄之形•凝滞虚影)",
"Stagnant_Shadow_Celestial": "角色晋阶材料:风(天人之形•凝滞虚影)"
},
"CavernOfCorrosion": {
"name": "完成1次侵蚀隧洞",
"help": "",
"do_not_achieve": "不完成这个任务",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遗器:冰套+风套(霜风之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遗器:物理套+击破套(迅拳之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遗器:治疗套+快枪手(漂泊之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Providence": "遗器:铁卫套+量子套(睿治之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Holy_Hymn": "遗器:防御套+雷套(圣颂之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Conflagration": "遗器:火套+虚数套(野焰之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Elixir_Seekers": "遗器:生命套+速度套(药使之径•侵蚀隧洞)"
}
},
"DungeonSupport": {
"_info": {
"name": "支援设置",
"help": ""
},
"Use": {
"name": "使用好友支援",
"help": "",
"always_use": "总是使用",
"when_daily": "仅当每日任务需要时使用",
"do_not_use": "不使用"
},
"Character": {
"name": "好友支援角色",
"help": "选择好友支援角色,未找到则选择默认(第一个)角色",
"FirstCharacter": "支援列表第一个角色",
@ -291,6 +350,211 @@
"Yukong": "驭空"
}
},
"DungeonStorage": {
"_info": {
"name": "DungeonStorage._info.name",
"help": "DungeonStorage._info.help"
},
"DungeonDouble": {
"name": "DungeonStorage.DungeonDouble.name",
"help": "DungeonStorage.DungeonDouble.help"
}
},
"AchievableQuest": {
"_info": {
"name": "可完成的任务",
"help": "任务状态为 \"未设置\" 时需要按照要求设置SRC才能启用任务\n注意请让更多的任务处于 \"可完成\" 状态否则SRC可能无法完成500点的活跃度要求"
},
"Complete_1_Daily_Mission": {
"name": "完成1个日常任务",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Clear_Calyx_Golden_1_times": {
"name": "完成1次「拟造花萼」",
"help": "需要设置并启用\"每日副本\"任务",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Complete_Calyx_Crimson_1_time": {
"name": "完成1次「拟造花萼」",
"help": "需要设置并启用\"每日副本\"任务",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Clear_Stagnant_Shadow_1_times": {
"name": "完成1次「凝滞虚影」",
"help": "需要设置并启用\"每日副本\"任务",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Clear_Cavern_of_Corrosion_1_times": {
"name": "完成1次「侵蚀隧洞」",
"help": "需要设置并启用\"每日副本\"任务",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": {
"name": "单场战斗中触发3种不同属性的弱点击破",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Inflict_Weakness_Break_5_times": {
"name": "累计触发弱点击破效果5次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Defeat_a_total_of_20_enemies": {
"name": "累计消灭20个敌人",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": {
"name": "利用弱点进入战斗并获胜3次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Use_Technique_2_times": {
"name": "累计施放2次秘技",
"help": "默认可完成将前往深渊一施放2次秘技",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Go_on_assignment_1_time": {
"name": "派遣1次委托",
"help": "需要设置并启用\"委托\"任务",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Take_1_photo": {
"name": "拍照1次",
"help": "默认可完成",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Destroy_3_destructible_objects": {
"name": "累计击碎3个可破坏物",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Complete_Forgotten_Hall_1_time": {
"name": "完成1次「忘却之庭」",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Complete_Echo_of_War_1_times": {
"name": "完成1次「历战余响」",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Complete_1_stage_in_Simulated_Universe_Any_world": {
"name": "通关「模拟宇宙」任意世界的1个区域",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Obtain_victory_in_combat_with_support_characters_1_time": {
"name": "使用支援角色并获得战斗胜利1次",
"help": "需要设置并启用\"每日副本\",且设置好友支援",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Use_an_Ultimate_to_deal_the_final_blow_1_time": {
"name": "施放终结技造成制胜一击1次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Level_up_any_character_1_time": {
"name": "将任意角色等级提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Level_up_any_Light_Cone_1_time": {
"name": "将任意光锥等级提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Level_up_any_Relic_1_time": {
"name": "将任意遗器等级提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Salvage_any_Relic": {
"name": "分解任意1件遗器",
"help": "默认可完成,将分解遗器稀有度倒序的第一个",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Synthesize_Consumable_1_time": {
"name": "合成1次消耗品",
"help": "默认可完成,将合成最低级零食",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Synthesize_material_1_time": {
"name": "合成1次材料",
"help": "默认可完成,将合成最低级材料",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
},
"Use_Consumables_1_time": {
"name": "使用1件消耗品",
"help": "默认可完成,将使用护具,无材料时先合成再使用",
"achievable": "可完成",
"not_set": "未设置",
"not_supported": "暂未支持"
}
},
"DailyStorage": {
"_info": {
"name": "DailyStorage._info.name",
"help": "DailyStorage._info.help"
},
"DailyActivity": {
"name": "DailyStorage.DailyActivity.name",
"help": "DailyStorage.DailyActivity.help"
},
"DailyQuest": {
"name": "DailyStorage.DailyQuest.name",
"help": "DailyStorage.DailyQuest.help"
}
},
"Assignment": {
"_info": {
"name": "委托设置",

View File

@ -31,7 +31,7 @@
"help": ""
},
"Assignment": {
"name": "委託設置",
"name": "委託",
"help": ""
}
},
@ -247,18 +247,77 @@
"4": "4",
"5": "5",
"6": "6"
}
},
"DungeonDaily": {
"_info": {
"name": "每日任務設定",
"help": "打一次特定的本,以滿足每日任務的要求"
},
"Support": {
"name": "Dungeon.Support.name",
"help": "Dungeon.Support.help",
"do_not_use": "do_not_use",
"always_use": "always_use",
"when_daily": "when_daily"
"CalyxGolden": {
"name": "完成1次擬造花萼",
"help": "",
"do_not_achieve": "不完成這個任務",
"Calyx_Golden_Memories": "材料:角色經驗(回憶之蕾•擬造花萼金)",
"Calyx_Golden_Aether": "材料:武器經驗(乙太之蕾•擬造花萼金)",
"Calyx_Golden_Treasures": "材料:信用點(藏珍之蕾•擬造花萼金)"
},
"SupportCharacter": {
"name": "Dungeon.SupportCharacter.name",
"help": "Dungeon.SupportCharacter.help",
"FirstCharacter": "FirstCharacter",
"CalyxCrimson": {
"name": "完成1次擬造花萼",
"help": "",
"do_not_achieve": "不完成這個任務",
"Calyx_Crimson_Destruction": "行跡材料:毀滅(毀滅之蕾•擬造花萼赤)",
"Calyx_Crimson_Preservation": "行跡材料:存護(存護之蕾•擬造花萼赤)",
"Calyx_Crimson_Hunt": "行跡材料:巡獵(存護之蕾•擬造花萼赤)",
"Calyx_Crimson_Abundance": "行跡材料:豐饒(豐饒之蕾•擬造花萼赤)",
"Calyx_Crimson_Erudition": "行跡材料:智識(智識之蕾•擬造花萼赤)",
"Calyx_Crimson_Harmony": "行跡材料:同諧(同諧之蕾•擬造花萼赤)",
"Calyx_Crimson_Nihility": "行跡材料:虛無(虛無之蕾•擬造花萼赤)"
},
"StagnantShadow": {
"name": "完成1次凝滯虛影",
"help": "",
"do_not_achieve": "不完成這個任務",
"Stagnant_Shadow_Quanta": "角色晉階材料:量子(空海之形•凝滯虛影)",
"Stagnant_Shadow_Gust": "角色晉階材料:風(巽風之形•凝滯虛影)",
"Stagnant_Shadow_Fulmination": "角色晉階材料:雷(鳴雷之形•凝滯虛影)",
"Stagnant_Shadow_Blaze": "角色晉階材料:火(炎華之形•凝滯虛影)",
"Stagnant_Shadow_Spike": "角色晉階材料:物理(鋒芒之形•凝滯虛影)",
"Stagnant_Shadow_Rime": "角色晉階材料:冰(霜晶之形•凝滯虛影)",
"Stagnant_Shadow_Mirage": "角色晉階材料:虛數(幻光之形•凝滯虛影)",
"Stagnant_Shadow_Icicle": "角色晉階材料:冰(冰稜之形•凝滯虛影)",
"Stagnant_Shadow_Doom": "角色晉階材料:雷(震厄之形•凝滯虛影)",
"Stagnant_Shadow_Celestial": "角色晉階材料:風(天人之形•凝滯虛影)"
},
"CavernOfCorrosion": {
"name": "完成1次侵蝕隧洞",
"help": "",
"do_not_achieve": "不完成這個任務",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遺器:冰套+風套(霜風之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遺器:物理套+擊破套(迅拳之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遺器:治療套+快槍手(漂泊之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Providence": "遺器:鐵衛套+量子套(睿治之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Holy_Hymn": "遺器:防禦套+雷套(聖頌之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Conflagration": "遺器:火套+虛數套(野焰之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Elixir_Seekers": "遺器:生命套+速度套(藥使之徑•侵蝕隧洞)"
}
},
"DungeonSupport": {
"_info": {
"name": "支援設定",
"help": ""
},
"Use": {
"name": "使用好友支援",
"help": "",
"always_use": "總是使用",
"when_daily": "僅當每日任務需要時使用",
"do_not_use": "不使用"
},
"Character": {
"name": "好友支援角色",
"help": "選擇好友支援角色,未找到則選擇默認(第一個)角色",
"FirstCharacter": "支援列表第一個角色",
"Arlan": "阿蘭",
"Asta": "艾絲妲",
"Bailu": "白露",
@ -284,16 +343,221 @@
"SilverWolf": "銀狼",
"Sushang": "素裳",
"Tingyun": "停雲",
"TrailblazerDestruction": "TrailblazerDestruction",
"TrailblazerPreservation": "TrailblazerPreservation",
"TrailblazerDestruction": "開拓者•毀滅",
"TrailblazerPreservation": "開拓者•存護",
"Welt": "瓦爾特",
"Yanqing": "彥卿",
"Yukong": "馭空"
}
},
"DungeonStorage": {
"_info": {
"name": "DungeonStorage._info.name",
"help": "DungeonStorage._info.help"
},
"DungeonDouble": {
"name": "DungeonStorage.DungeonDouble.name",
"help": "DungeonStorage.DungeonDouble.help"
}
},
"AchievableQuest": {
"_info": {
"name": "可完成的任務",
"help": "任務狀態為 \"未設定\" 時需要按照要求設定SRC才能啟用任務\n注意請讓更多的任務處於 \"可完成\" 狀態否則SRC可能無法完成500點的活躍度要求"
},
"Complete_1_Daily_Mission": {
"name": "完成1個每日任務",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Clear_Calyx_Golden_1_times": {
"name": "完成1次「擬造花萼」",
"help": "需要設定並啟用\"每日副本\"任務",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Complete_Calyx_Crimson_1_time": {
"name": "完成1次「擬造花萼」",
"help": "需要設定並啟用\"每日副本\"任務",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Clear_Stagnant_Shadow_1_times": {
"name": "完成1次「凝滯虛影」",
"help": "需要設定並啟用\"每日副本\"任務",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Clear_Cavern_of_Corrosion_1_times": {
"name": "完成1次「侵蝕隧洞」",
"help": "需要設定並啟用\"每日副本\"任務",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"In_a_single_battle_inflict_3_Weakness_Break_of_different_Types": {
"name": "單場戰鬥中觸發3種不同屬性的弱點擊破",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Inflict_Weakness_Break_5_times": {
"name": "累積觸發弱點擊破效果5次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Defeat_a_total_of_20_enemies": {
"name": "累積消滅20個敵人",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Enter_combat_by_attacking_enemy_Weakness_and_win_3_times": {
"name": "利用弱點進入戰鬥並獲勝3次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Use_Technique_2_times": {
"name": "累積施放2次秘技",
"help": "默認可完成將前往深淵一施放2次秘技",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Go_on_assignment_1_time": {
"name": "派遣1次委託",
"help": "需要設定並啟用\"委託\"任務",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Take_1_photo": {
"name": "拍照1次",
"help": "默认可完成",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Destroy_3_destructible_objects": {
"name": "累積擊碎3個可破壞物",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Complete_Forgotten_Hall_1_time": {
"name": "完成1次「忘卻之庭」",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Complete_Echo_of_War_1_times": {
"name": "完成1次「歷戰餘響」",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Complete_1_stage_in_Simulated_Universe_Any_world": {
"name": "完成「模擬宇宙」任意世界的1個區域",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Obtain_victory_in_combat_with_support_characters_1_time": {
"name": "使用支援角色並獲得戰鬥勝利1次",
"help": "需要設定並啟用\"每日副本\",且設並好友支援",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Use_an_Ultimate_to_deal_the_final_blow_1_time": {
"name": "施放終結技造成制勝一擊1次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Level_up_any_character_1_time": {
"name": "將任意角色等級提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Level_up_any_Light_Cone_1_time": {
"name": "將任意光錐等級提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Level_up_any_Relic_1_time": {
"name": "將任意遺器等級提升1次",
"help": "",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Salvage_any_Relic": {
"name": "分解任意1件遺器",
"help": "默認可完成,將分解遺器稀有度倒序的第一個",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Synthesize_Consumable_1_time": {
"name": "合成1次消耗品",
"help": "默認可完成,將合成最低級零食",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Synthesize_material_1_time": {
"name": "合成1次素材",
"help": "默認可完成,將合成最低級素材",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
},
"Use_Consumables_1_time": {
"name": "使用1件消耗品",
"help": "默認可完成,將使用護具,無材料時先合成再使用",
"achievable": "可完成",
"not_set": "未設定",
"not_supported": "暫未支援"
}
},
"DailyStorage": {
"_info": {
"name": "DailyStorage._info.name",
"help": "DailyStorage._info.help"
},
"DailyActivity": {
"name": "DailyStorage.DailyActivity.name",
"help": "DailyStorage.DailyActivity.help"
},
"DailyQuest": {
"name": "DailyStorage.DailyQuest.name",
"help": "DailyStorage.DailyQuest.help"
}
},
"Assignment": {
"_info": {
"name": "委託設置",
"name": "委託設",
"help": "領取獎勵並派遣,優先處理指定委託\n若處理指定委託之後未達到上限則按經驗材料 → 角色專屬素材 → 合成材料的順序來派遣委託"
},
"Duration": {

View File

@ -0,0 +1,242 @@
import time
from datetime import datetime
from functools import cached_property as functools_cached_property
from module.base.decorator import cached_property
from module.config.utils import DEFAULT_TIME, deep_get, get_server_last_update
from module.exception import ScriptError
def now():
return datetime.now().replace(microsecond=0)
def iter_attribute(cls):
"""
Args:
cls: Class or object
Yields:
str, obj: Attribute name, attribute value
"""
for attr in dir(cls):
if attr.startswith('_'):
continue
value = getattr(cls, attr)
if type(value).__name__ in ['function', 'property']:
continue
yield attr, value
class StoredBase:
time = DEFAULT_TIME
def __init__(self, key):
self._key = key
self._config = None
@cached_property
def _name(self):
return self._key.split('.')[-1]
def _bind(self, config):
"""
Args:
config (AzurLaneConfig):
"""
self._config = config
@functools_cached_property
def _stored(self):
assert self._config is not None, 'StoredBase._bind() must be called before getting stored data'
from module.logger import logger
out = {}
stored = deep_get(self._config.data, keys=self._key, default={})
for attr, default in self._attrs.items():
value = stored.get(attr, default)
if attr == 'time':
if not isinstance(value, datetime):
try:
value = datetime.fromisoformat(value)
except ValueError:
logger.warning(f'{self._name} has invalid attr: {attr}={value}, use default={default}')
value = default
else:
if not isinstance(value, type(default)):
logger.warning(f'{self._name} has invalid attr: {attr}={value}, use default={default}')
value = default
out[attr] = value
return out
@cached_property
def _attrs(self) -> dict:
"""
All attributes defined
"""
attrs = {
# time is the first one
'time': DEFAULT_TIME
}
for attr, value in iter_attribute(self.__class__):
attrs[attr] = value
return attrs
def __setattr__(self, key, value):
if key in self._attrs:
stored = self._stored
stored['time'] = now()
stored[key] = value
self._config.modified[self._key] = stored
if self._config.auto_update:
self._config.update()
else:
super().__setattr__(key, value)
def __getattribute__(self, item):
if not item.startswith('_') and item in self._attrs:
return self._stored[item]
else:
return super().__getattribute__(item)
def is_expired(self) -> bool:
return False
def show(self):
"""
Log self
"""
from module.logger import logger
logger.attr(self._name, self._stored)
def dashboard(self) -> str:
"""
Return a string to show on GUI
"""
return 'None'
def readable_time(self):
diff = self.time.timestamp() - time.time()
if diff < -1:
return '', 'TimeError'
elif diff < 60:
# < 1 min
return '', 'JustNow'
elif diff < 3600:
return str(int(diff // 60)), 'MinutesAgo'
elif diff < 86400:
return str(int(diff // 86400)), 'HoursAgo'
elif diff < 129600:
return str(int(diff // 129600)), 'DaysAgo'
else:
# > 15 days
return '', 'LongTimeAgo'
class StoredExpiredAt0400(StoredBase):
def is_expired(self):
from module.logger import logger
self.show()
expired = self.time < get_server_last_update('04:00')
logger.attr(f'{self._name} expired', expired)
return expired
class StoredInt(StoredBase):
value = 0
class StoredCounter(StoredBase):
current = 0
total = 0
def set(self, current, total):
with self._config.multi_set():
self.current = current
self.total = total
def to_counter(self) -> str:
return f'{self.current}/{self.total}'
def is_full(self) -> bool:
return self.current >= self.total
def get_remain(self) -> int:
return self.total - self.current
class StoredDailyActivity(StoredCounter, StoredExpiredAt0400):
def set(self, current):
return super().set(current=current, total=500)
@property
def _stored(self):
stored = super()._stored
stored['total'] = 500
return stored
class StoredDaily(StoredExpiredAt0400):
quest1 = ''
quest2 = ''
quest3 = ''
quest4 = ''
quest5 = ''
quest6 = ''
def load_quests(self):
"""
Returns:
list[DailyQuest]: Note that must check if quests are expired
"""
# DailyQuest should be lazy loaded
from tasks.daily.keywords import DailyQuest
quests = []
for name in [self.quest1, self.quest2, self.quest3, self.quest4, self.quest5, self.quest6]:
if not name:
continue
try:
quest = DailyQuest.find(name)
quests.append(quest)
except ScriptError:
pass
return quests
def write_quests(self, quests):
"""
Args:
quests (list[DailyQuest, str]):
"""
from tasks.daily.keywords import DailyQuest
quests = [q.name if isinstance(q, DailyQuest) else q for q in quests]
with self._config.multi_set():
try:
self.quest1 = quests[0]
except IndexError:
self.quest1 = ''
try:
self.quest2 = quests[1]
except IndexError:
self.quest2 = ''
try:
self.quest3 = quests[2]
except IndexError:
self.quest3 = ''
try:
self.quest4 = quests[3]
except IndexError:
self.quest4 = ''
try:
self.quest5 = quests[4]
except IndexError:
self.quest5 = ''
try:
self.quest6 = quests[5]
except IndexError:
self.quest6 = ''
class StoredDungeonDouble(StoredExpiredAt0400):
calyx = 0
relic = 0

View File

@ -0,0 +1,18 @@
from module.config.stored.classes import (
StoredBase,
StoredCounter,
StoredDaily,
StoredDailyActivity,
StoredDungeonDouble,
StoredExpiredAt0400,
StoredInt,
)
# This file was auto-generated, do not modify it manually. To generate:
# ``` python -m module/config/config_updater.py ```
class StoredGenerated:
DungeonDouble = StoredDungeonDouble("Dungeon.DungeonStorage.DungeonDouble")
DailyActivity = StoredDailyActivity("DailyQuest.DailyStorage.DailyActivity")
DailyQuest = StoredDaily("DailyQuest.DailyStorage.DailyQuest")

View File

@ -332,8 +332,9 @@ def data_to_type(data, **kwargs):
"""
| Condition | Type |
| ------------------------------------ | -------- |
| Value is bool | checkbox |
| Arg has options | select |
| `value` is bool | checkbox |
| Arg has `options` | select |
| Arg has `stored` | select |
| `Filter` is in name (in data['arg']) | textarea |
| Rest of the args | input |
@ -345,10 +346,12 @@ def data_to_type(data, **kwargs):
str:
"""
kwargs.update(data)
if isinstance(kwargs['value'], bool):
if isinstance(kwargs.get('value'), bool):
return 'checkbox'
elif 'option' in kwargs and kwargs['option']:
return 'select'
elif 'stored' in kwargs and kwargs['stored']:
return 'stored'
elif 'Filter' in kwargs['arg']:
return 'textarea'
else:

View File

@ -3,13 +3,12 @@ from module.logger import logger
from tasks.base.assets.assets_base_page import CLOSE
from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT, COMBAT_TEAM_DISMISSSUPPORT
from tasks.combat.assets.assets_combat_support import COMBAT_SUPPORT_ADD, COMBAT_SUPPORT_LIST
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT
from tasks.combat.interact import CombatInteract
from tasks.combat.prepare import CombatPrepare
from tasks.combat.state import CombatState
from tasks.combat.team import CombatTeam
from tasks.combat.support import CombatSupport
from tasks.combat.team import CombatTeam
from tasks.map.control.joystick import MapControlJoystick
@ -69,9 +68,8 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
"""
Args:
team: 1 to 6.
skip_first_screenshot:
support_character: Support character name
Returns:
bool: True if success to enter combat
False if trialblaze power is not enough
@ -272,21 +270,23 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
self.device.click(COMBAT_EXIT)
continue
def combat(self, team: int = 1, wave_limit: int = 0, skip_first_screenshot=True, support_character: str = None):
def is_stamina_exhausted(self) -> bool:
flag = self.state.TrailblazePower < self.combat_wave_cost
logger.attr('StaminaExhausted', flag)
return flag
def combat(self, team: int = 1, wave_limit: int = 0, support_character: str = None, skip_first_screenshot=True):
"""
Combat until trailblaze power runs out.
Args:
team: 1 to 6.
wave_limit: Limit combat runs, 0 means no limit.
skip_first_screenshot:
use_support: "do_not_use", "always_use", "when_daily"
is_daily: True if is a daily task
support_character: Support character name
skip_first_screenshot:
Returns:
bool: True if trailblaze power exhausted
False if reached wave_limit but still have trailblaze power
int: Run count
Pages:
in: COMBAT_PREPARE
@ -298,6 +298,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
self.combat_wave_limit = wave_limit
self.combat_wave_done = 0
run_count = 0
while 1:
logger.hr('Combat', level=2)
logger.info(f'Combat, team={team}, wave={self.combat_wave_done}/{self.combat_wave_limit}')
@ -312,7 +313,9 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
finish = self.combat_finish()
if self._combat_should_reenter():
continue
run_count += 1
if finish:
break
return self.state.TrailblazePower < self.combat_wave_cost
logger.attr('CombatRunCount', run_count)
return run_count

View File

@ -94,6 +94,7 @@ class CombatState(UI):
self._combat_auto_checked = True
else:
if self._combat_click_interval.reached():
self.device.image_save()
self.device.click(COMBAT_AUTO)
self._combat_click_interval.reset()
return True

View File

@ -99,6 +99,7 @@ class DailyQuestUI(DungeonUI):
results = [result.matched_keyword for result in results]
logger.info("Daily quests recognition complete")
logger.info(f"Daily quests: {results}")
self.config.stored.DailyQuest.write_quests(results)
return results
def _get_quest_reward(self, skip_first_screenshot=True):
@ -128,7 +129,7 @@ class DailyQuestUI(DungeonUI):
def _get_active_point_reward(self, skip_first_screenshot=True):
def get_active():
for button in [
for b in [
ACTIVE_POINTS_1_UNLOCK,
ACTIVE_POINTS_2_UNLOCK,
ACTIVE_POINTS_3_UNLOCK,
@ -136,8 +137,8 @@ class DailyQuestUI(DungeonUI):
ACTIVE_POINTS_5_UNLOCK
]:
# Black gift icon
if self.image_color_count(button, color=(61, 53, 53), threshold=221, count=100):
return button
if self.image_color_count(b, color=(61, 53, 53), threshold=221, count=100):
return b
return None
interval = Timer(2)
@ -156,6 +157,26 @@ class DailyQuestUI(DungeonUI):
self.device.click(active)
interval.reset()
# Write stored
point = 0
for progress, button in zip(
[100, 200, 300, 400, 500],
[
ACTIVE_POINTS_1_CHECKED,
ACTIVE_POINTS_2_CHECKED,
ACTIVE_POINTS_3_CHECKED,
ACTIVE_POINTS_4_CHECKED,
ACTIVE_POINTS_5_CHECKED
]
):
if self.appear(button):
point = progress
logger.attr('Daily activity', point)
with self.config.multi_set():
self.config.stored.DailyActivity.set(point)
if point == 500:
self.config.stored.DailyQuest.write_quests([])
def get_daily_rewards(self):
"""
Returns:

View File

@ -1,58 +1,219 @@
from module.base.utils import area_offset
from module.logger import logger
from tasks.combat.combat import Combat
from tasks.daily.keywords import KEYWORDS_DAILY_QUEST
from tasks.dungeon.event import DungeonEvent
from tasks.dungeon.keywords import DungeonList, KEYWORDS_DUNGEON_LIST, KEYWORDS_DUNGEON_TAB
from tasks.dungeon.ui import DungeonUI
class Dungeon(DungeonUI, DungeonEvent, Combat):
def run(self, dungeon: DungeonList = None, team: int = None, use_support: str = None, is_daily: bool = False,
support_character: str = None):
if dungeon is None:
dungeon = DungeonList.find(self.config.Dungeon_Name)
called_daily_support = False
achieved_daily_quest = False
daily_quests = []
def _dungeon_run(self, dungeon: DungeonList, team: int = None, wave_limit: int = 0, support_character: str = None,
skip_ui_switch: bool = False):
"""
Args:
dungeon:
team: 1 to 6.
wave_limit: Limit combat runs, 0 means no limit.
support_character: Support character name
skip_ui_switch: True if already at dungeon aside
Returns:
int: Run count
Pages:
in: Any
out: page_main
"""
if team is None:
team = self.config.Dungeon_Team
if use_support is None:
use_support = self.config.Dungeon_Support
if support_character is None:
support_character = self.config.Dungeon_SupportCharacter if use_support == "always_use" or use_support == "when_daily" and is_daily else None
if support_character is None and self.config.DungeonSupport_Use == 'always_use':
support_character = self.config.DungeonSupport_Character
# UI switches
switched = self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
if not switched:
# Nav must at top, reset nav states
self.ui_goto_main()
logger.hr('Dungeon run', level=1)
logger.info(f'Dungeon: {dungeon}, team={team}, wave_limit={wave_limit}, support_character={support_character}')
if not skip_ui_switch:
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(dungeon)
# Check double events
if self.config.Dungeon_NameAtDoubleCalyx != 'do_not_participate' and self.has_double_calyx_event():
calyx = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
self._dungeon_nav_goto(calyx)
if remain := self.get_double_event_remain():
self.dungeon_goto(calyx)
if self.combat(team, wave_limit=remain, support_character=support_character):
self.delay_dungeon_task(calyx)
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
if self.config.Dungeon_NameAtDoubleRelic != 'do_not_participate' and self.has_double_relic_event():
calyx = DungeonList.find(self.config.Dungeon_NameAtDoubleRelic)
self._dungeon_nav_goto(calyx)
if remain := self.get_double_event_remain():
self.dungeon_goto(calyx)
if self.combat(team, wave_limit=remain, support_character=support_character):
self.delay_dungeon_task(calyx)
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
if dungeon == KEYWORDS_DUNGEON_LIST.Stagnant_Shadow_Blaze:
if self.handle_destructible_around_blaze():
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(dungeon)
# Combat
self.dungeon_goto(dungeon)
count = self.combat(team=team, wave_limit=wave_limit, support_character=support_character)
if dungeon == KEYWORDS_DUNGEON_LIST.Stagnant_Shadow_Blaze:
if self.handle_destructible_around_blaze():
# Update quest states
if dungeon.is_Calyx_Golden \
and KEYWORDS_DAILY_QUEST.Clear_Calyx_Golden_1_times in self.daily_quests:
logger.info('Achieved daily quest Clear_Calyx_Golden_1_times')
self.achieved_daily_quest = True
if dungeon.is_Calyx_Crimson \
and KEYWORDS_DAILY_QUEST.Complete_Calyx_Crimson_1_time in self.daily_quests:
logger.info('Achieve daily quest Complete_Calyx_Crimson_1_time')
self.achieved_daily_quest = True
if dungeon.is_Stagnant_Shadow \
and KEYWORDS_DAILY_QUEST.Clear_Stagnant_Shadow_1_times in self.daily_quests:
logger.info('Achieve daily quest Clear_Stagnant_Shadow_1_times')
self.achieved_daily_quest = True
if dungeon.is_Cavern_of_Corrosion \
and KEYWORDS_DAILY_QUEST.Clear_Cavern_of_Corrosion_1_times in self.daily_quests:
logger.info('Achieve daily quest Clear_Cavern_of_Corrosion_1_times')
self.achieved_daily_quest = True
if support_character is not None:
self.called_daily_support = True
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_support_characters_1_time:
logger.info('Achieve daily quest Obtain_victory_in_combat_with_support_characters_1_time')
self.achieved_daily_quest = True
# Check stamina, this may stop current task
if self.is_stamina_exhausted():
self.delay_dungeon_task(dungeon)
return count
def dungeon_run(
self, dungeon: DungeonList, team: int = None, wave_limit: int = 0, support_character: str = None):
"""
Run dungeon, and handle daily support
Args:
dungeon:
team: 1 to 6.
wave_limit: Limit combat runs, 0 means no limit.
support_character: Support character name
Returns:
int: Run count
Pages:
in: Any
out: page_main
"""
require = self.require_compulsory_support()
if require:
logger.info('Run once with support')
count = self._dungeon_run(dungeon=dungeon, team=team, wave_limit=1,
support_character=self.config.DungeonSupport_Character)
logger.info('Run the rest waves without compulsory support')
if wave_limit >= 2 or wave_limit == 0:
# Already at page_name with DUNGEON_COMBAT_INTERACT
if wave_limit >= 2:
wave_limit -= 1
count += self._dungeon_run(dungeon=dungeon, team=team, wave_limit=wave_limit,
support_character=support_character, skip_ui_switch=True)
return count
else:
# Normal run
return self._dungeon_run(dungeon=dungeon, team=team, wave_limit=wave_limit,
support_character=support_character)
def run(self):
# Update daily quests
if self.config.stored.DailyActivity.is_expired():
logger.info('Daily activity expired, call task to update')
self.config.task_call('DailyQuest')
self.config.task_stop()
if self.config.stored.DailyQuest.is_expired():
logger.info('Daily quests expired, call task to update')
self.config.task_call('DailyQuest')
self.config.task_stop()
self.called_daily_support = False
self.achieved_daily_quest = False
self.daily_quests = self.config.stored.DailyQuest.load_quests()
# Update double event records
if self.config.stored.DungeonDouble.is_expired():
logger.info('Get dungeon double remains')
# UI switches
switched = self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
if not switched:
# Nav must at top, reset nav states
self.ui_goto_main()
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(dungeon)
# Check remains
calyx = 0
relic = 0
if self.has_double_calyx_event():
self._dungeon_nav_goto(KEYWORDS_DUNGEON_LIST.Calyx_Golden_Treasures)
calyx = self.get_double_event_remain()
if self.has_double_relic_event():
self._dungeon_nav_goto(KEYWORDS_DUNGEON_LIST.Cavern_of_Corrosion_Path_of_Gelid_Wind)
relic = self.get_double_event_remain()
with self.config.multi_set():
self.config.stored.DungeonDouble.calyx = calyx
self.config.stored.DungeonDouble.relic = relic
self.combat(team=team, support_character=support_character)
self.delay_dungeon_task(dungeon)
# Run double events
ran_calyx_golden = False
ran_calyx_crimson = False
ran_cavern_of_corrosion = False
# Double calyx
if self.config.Dungeon_NameAtDoubleCalyx != 'do_not_participate' \
and self.config.stored.DungeonDouble.calyx > 0:
logger.info('Run double calyx')
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.calyx):
if dungeon.is_Calyx_Golden:
ran_calyx_golden = True
if dungeon.is_Calyx_Crimson:
ran_calyx_crimson = True
# Double relic
if self.config.Dungeon_NameAtDoubleRelic != 'do_not_participate' \
and self.config.stored.DungeonDouble.relic > 0:
logger.info('Run double relic')
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleRelic)
if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.relic):
ran_cavern_of_corrosion = True
# Dungeon to clear all trailblaze power
final = DungeonList.find(self.config.Dungeon_Name)
# Run dungeon that required by daily quests
# Calyx_Golden
if KEYWORDS_DAILY_QUEST.Clear_Calyx_Golden_1_times in self.daily_quests \
and self.config.DungeonDaily_CalyxGolden != 'do_not_achieve' \
and not final.is_Calyx_Golden \
and not ran_calyx_golden:
logger.info('Run Calyx_Golden once')
dungeon = DungeonList.find(self.config.DungeonDaily_CalyxGolden)
self.dungeon_run(dungeon=dungeon, wave_limit=1)
# Calyx_Crimson
if KEYWORDS_DAILY_QUEST.Complete_Calyx_Crimson_1_time in self.daily_quests \
and self.config.DungeonDaily_CalyxCrimson != 'do_not_achieve' \
and not final.is_Calyx_Crimson \
and not ran_calyx_crimson:
logger.info('Run Calyx_Crimson once')
dungeon = DungeonList.find(self.config.DungeonDaily_CalyxCrimson)
self.dungeon_run(dungeon=dungeon, wave_limit=1)
# Stagnant_Shadow
if KEYWORDS_DAILY_QUEST.Clear_Stagnant_Shadow_1_times in self.daily_quests \
and self.config.DungeonDaily_StagnantShadow != 'do_not_achieve' \
and not final.is_Stagnant_Shadow:
logger.info('Run Stagnant_Shadow once')
dungeon = DungeonList.find(self.config.DungeonDaily_StagnantShadow)
self.dungeon_run(dungeon=dungeon, wave_limit=1)
# Cavern_of_Corrosion
if KEYWORDS_DAILY_QUEST.Clear_Cavern_of_Corrosion_1_times in self.daily_quests \
and self.config.DungeonDaily_CavernOfCorrosion != 'do_not_achieve' \
and not final.is_Cavern_of_Corrosion \
and not ran_cavern_of_corrosion:
logger.info('Run Cavern_of_Corrosion once')
dungeon = DungeonList.find(self.config.DungeonDaily_CavernOfCorrosion)
self.dungeon_run(dungeon=dungeon, wave_limit=1)
# Combat
self.dungeon_run(final)
self.delay_dungeon_task(final)
def delay_dungeon_task(self, dungeon):
if dungeon.is_Cavern_of_Corrosion:
@ -62,7 +223,11 @@ class Dungeon(DungeonUI, DungeonEvent, Combat):
# Recover 1 trailbaze power each 6 minutes
cover = max(limit - self.state.TrailblazePower, 0) * 6
logger.info(f'Currently has {self.state.TrailblazePower} need {cover} minutes to reach {limit}')
self.config.task_delay(minute=cover)
logger.attr('achieved_daily_quest', self.achieved_daily_quest)
with self.config.multi_set():
if self.achieved_daily_quest:
self.config.task_call('DailyQuest')
self.config.task_delay(minute=cover)
self.config.task_stop()
def handle_destructible_around_blaze(self):
@ -104,3 +269,23 @@ class Dungeon(DungeonUI, DungeonEvent, Combat):
break
return handled
def require_compulsory_support(self) -> bool:
require = False
if not self.config.stored.DailyActivity.is_full():
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_support_characters_1_time \
in self.daily_quests:
require = True
logger.attr('called_daily_support', self.called_daily_support)
if self.called_daily_support:
require = False
# Not required, cause any dungeon run will achieve the quest
logger.attr('DungeonSupport_Use', self.config.DungeonSupport_Use)
if self.config.DungeonSupport_Use == 'always_use':
require = False
logger.attr('Require compulsory support', require)
return require

View File

@ -28,6 +28,10 @@ class DungeonList(Keyword):
def is_Calyx_Crimson(self):
return 'Calyx_Crimson' in self.name
@cached_property
def is_Calyx(self):
return self.is_Calyx_Golden or self.is_Calyx_Crimson
@cached_property
def is_Stagnant_Shadow(self):
return 'Stagnant_Shadow' in self.name