Merge pull request #484 from LmeSzinc/dev
增加角色养成规划 | Add Character Planner
BIN
assets/cn/combat/obtain/MAY_OBTAIN.SEARCH.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/cn/combat/obtain/MAY_OBTAIN.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/en/combat/obtain/MAY_OBTAIN.SEARCH.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/en/combat/obtain/MAY_OBTAIN.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
@ -435,6 +435,13 @@ pre.rich-traceback-code {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
*[style*="--dashboard-bold--"] {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
color: #7a77bb;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
[id^="pywebio-scope-dashboard-row-"] p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
BIN
assets/share/combat/obtain/ITEM_AMOUNT.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/share/combat/obtain/ITEM_CLOSE.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
assets/share/combat/obtain/ITEM_NAME.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/share/combat/obtain/OBTAIN_1.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/share/combat/obtain/OBTAIN_2.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/share/combat/obtain/OBTAIN_3.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/share/combat/obtain/OBTAIN_4.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/share/combat/obtain/OBTAIN_TRAILBLAZE_EXP.SEARCH.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
assets/share/combat/obtain/OBTAIN_TRAILBLAZE_EXP.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
assets/share/item/synthesize/ENTRY_ITEM_FROM.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
assets/share/item/synthesize/ENTRY_ITEM_TO.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
assets/share/item/synthesize/ITEM_NAME.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/share/item/synthesize/SWITCH_RARITY.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
assets/share/item/synthesize/SYNTHESIZE_AMOUNT.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/share/item/synthesize/SYNTHESIZE_MINUS.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
assets/share/item/synthesize/SYNTHESIZE_PLUS.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
assets/share/planner/result/CALCULATE_TITLE.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/share/planner/result/DETAIL_TITLE.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/share/planner/result/MATERIAL_TITLE.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
assets/share/planner/result/OCR_RESULT.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/share/planner/result/RESULT_CHECK.SEARCH.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/share/planner/result/RESULT_CHECK.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
assets/share/planner/result/RESULT_SCROLL.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
@ -46,18 +46,64 @@
|
||||
"Command": "Dungeon",
|
||||
"ServerUpdate": "04:00"
|
||||
},
|
||||
"Planner": {
|
||||
"Item_Credit": {},
|
||||
"Item_Trailblaze_EXP": {},
|
||||
"Item_Traveler_Guide": {},
|
||||
"Item_Refined_Aether": {},
|
||||
"Item_Lost_Crystal": {},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {},
|
||||
"Item_Endotherm_Chitin": {},
|
||||
"Item_Horn_of_Snow": {},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {},
|
||||
"Item_Storm_Eye": {},
|
||||
"Item_Void_Cast_Iron": {},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {},
|
||||
"Item_Netherworld_Token": {},
|
||||
"Item_Searing_Steel_Blade": {},
|
||||
"Item_Gelid_Chitin": {},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {},
|
||||
"Item_Ascendant_Debris": {},
|
||||
"Item_Nail_of_the_Ape": {},
|
||||
"Item_Suppressing_Edict": {},
|
||||
"Item_IPC_Work_Permit": {},
|
||||
"Item_Raging_Heart": {},
|
||||
"Item_Dream_Fridge": {},
|
||||
"Item_Dream_Flamer": {},
|
||||
"Item_Worldbreaker_Blade": {},
|
||||
"Item_Arrow_of_the_Starchaser": {},
|
||||
"Item_Key_of_Wisdom": {},
|
||||
"Item_Safeguard_of_Amber": {},
|
||||
"Item_Obsidian_of_Obsession": {},
|
||||
"Item_Stellaris_Symphony": {},
|
||||
"Item_Flower_of_Eternity": {},
|
||||
"Item_Moon_Madness_Fang": {},
|
||||
"Item_Countertemporal_Shot": {},
|
||||
"Item_Divine_Amber": {},
|
||||
"Item_Heaven_Incinerator": {},
|
||||
"Item_Heavenly_Melody": {},
|
||||
"Item_Myriad_Fruit": {},
|
||||
"Item_Tracks_of_Destiny": {},
|
||||
"Item_Destroyer_Final_Road": {},
|
||||
"Item_Guardian_Lament": {},
|
||||
"Item_Regret_of_Infinite_Ochema": {},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {},
|
||||
"Item_Squirming_Core": {},
|
||||
"Item_Conqueror_Will": {},
|
||||
"Item_Silvermane_Medal": {},
|
||||
"Item_Ancient_Engine": {},
|
||||
"Item_Immortal_Lumintwig": {},
|
||||
"Item_Artifex_Gyreheart": {},
|
||||
"Item_Dream_Making_Engine": {},
|
||||
"Item_Shards_of_Desires": {}
|
||||
},
|
||||
"Dungeon": {
|
||||
"Name": "Calyx_Golden_Treasures_Jarilo_VI",
|
||||
"NameAtDoubleCalyx": "Calyx_Golden_Treasures_Jarilo_VI",
|
||||
"NameAtDoubleRelic": "Cavern_of_Corrosion_Path_of_Providence",
|
||||
"Team": 1
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"CalyxGolden": "Calyx_Golden_Treasures_Jarilo_VI",
|
||||
"CalyxCrimson": "Calyx_Crimson_Destruction_Herta_StorageZone",
|
||||
"StagnantShadow": "Stagnant_Shadow_Quanta",
|
||||
"CavernOfCorrosion": "Cavern_of_Corrosion_Path_of_Providence"
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"Use": "when_daily",
|
||||
"Character": "FirstCharacter"
|
||||
@ -79,9 +125,9 @@
|
||||
},
|
||||
"AchievableQuest": {
|
||||
"Complete_1_Daily_Mission": "not_supported",
|
||||
"Clear_Calyx_Golden_1_times": "achievable",
|
||||
"Clear_Stagnant_Shadow_1_times": "achievable",
|
||||
"Clear_Cavern_of_Corrosion_1_times": "achievable",
|
||||
"Clear_Calyx_Golden_1_times": "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": "achievable",
|
||||
"Inflict_Weakness_Break_5_times": "achievable",
|
||||
"Defeat_a_total_of_20_enemies": "achievable",
|
||||
@ -93,7 +139,7 @@
|
||||
"Log_in_to_the_game": "achievable",
|
||||
"Dispatch_1_assignments": "achievable",
|
||||
"Complete_Simulated_Universe_1_times": "not_set",
|
||||
"Clear_Calyx_Crimson_1_times": "achievable",
|
||||
"Clear_Calyx_Crimson_1_times": "not_set",
|
||||
"Enter_combat_by_attacking_enemie_Weakness_and_win_3_times": "achievable",
|
||||
"Use_Technique_2_times": "achievable",
|
||||
"Destroy_3_destructible_objects": "achievable",
|
||||
@ -221,5 +267,10 @@
|
||||
"Enable": true,
|
||||
"AimClicker": "do_not_click"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"PlannerScan": {
|
||||
"ResultAdd": false
|
||||
}
|
||||
}
|
||||
}
|
@ -3,11 +3,13 @@ import re
|
||||
import typing as t
|
||||
from dataclasses import dataclass
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from tqdm import tqdm
|
||||
|
||||
from module.base.code_generator import CodeGenerator
|
||||
from module.base.utils import SelectedGrids, area_limit, area_pad, get_bbox, get_color, image_size, load_image
|
||||
from module.base.utils import (
|
||||
SelectedGrids, area_center, area_limit, area_pad, corner2area, get_bbox, get_color, image_size, load_image)
|
||||
from module.config.config_manual import ManualConfig as AzurLaneConfig
|
||||
from module.config.server import VALID_LANG
|
||||
from module.config.utils import deep_get, deep_iter, deep_set, iter_folder
|
||||
@ -17,6 +19,44 @@ SHARE_SERVER = 'share'
|
||||
ASSET_SERVER = [SHARE_SERVER] + VALID_LANG
|
||||
|
||||
|
||||
def parse_grid(image):
|
||||
"""
|
||||
Args:
|
||||
image:
|
||||
|
||||
Returns:
|
||||
dict: Key: Grid position (x, y)
|
||||
Value: Area on image
|
||||
"""
|
||||
image = cv2.inRange(image, (127, 127, 127), (255, 255, 255))
|
||||
contours, _ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
dic_rect = {}
|
||||
for corners in contours:
|
||||
area = corner2area(corners.reshape(4, 2)) + (0, 0, 1, 1)
|
||||
center = area_center(area)
|
||||
dic_rect[center] = area
|
||||
# for k, v in dic_rect.items():
|
||||
# print(k, v)
|
||||
|
||||
dic_grid = {}
|
||||
prev_y = -100
|
||||
grid_y = -1
|
||||
stack_center = []
|
||||
for center in sorted(dic_rect.keys(), key=lambda x: x[1]):
|
||||
if center[1] > prev_y + 3:
|
||||
for x, c in enumerate(sorted(stack_center, key=lambda x: x[0])):
|
||||
dic_grid[(x, grid_y)] = tuple(dic_rect[c].astype(int))
|
||||
grid_y += 1
|
||||
stack_center = []
|
||||
stack_center.append(center)
|
||||
prev_y = center[1]
|
||||
for x, c in enumerate(sorted(stack_center, key=lambda x: x[0])):
|
||||
dic_grid[(x, grid_y)] = tuple(dic_rect[c].astype(int))
|
||||
# for k, v in dic_grid.items():
|
||||
# print(k, v)
|
||||
return dic_grid
|
||||
|
||||
|
||||
class AssetsImage:
|
||||
REGEX_ASSETS = re.compile(
|
||||
f'^{AzurLaneConfig.ASSETS_FOLDER}/'
|
||||
@ -24,7 +64,7 @@ class AssetsImage:
|
||||
f'(?P<module>[a-zA-Z0-9_/]+?)/'
|
||||
f'(?P<assets>\w+)'
|
||||
f'(?P<frame>\.\d+)?'
|
||||
f'(?P<attr>\.AREA|\.SEARCH|\.COLOR|\.BUTTON)?'
|
||||
f'(?P<attr>\.AREA|\.SEARCH|\.COLOR|\.BUTTON|\.GRID)?'
|
||||
f'\.png$'
|
||||
)
|
||||
|
||||
@ -46,6 +86,7 @@ class AssetsImage:
|
||||
self.assets = ''
|
||||
self.frame = 1
|
||||
self.attr = ''
|
||||
self.posi = None
|
||||
|
||||
if res:
|
||||
self.valid = True
|
||||
@ -66,6 +107,7 @@ class AssetsImage:
|
||||
|
||||
self.bbox: t.Tuple = ()
|
||||
self.mean: t.Tuple = ()
|
||||
self.grids = {}
|
||||
|
||||
def parse(self):
|
||||
image = load_image(self.file)
|
||||
@ -79,6 +121,10 @@ class AssetsImage:
|
||||
mean = tuple(np.rint(mean).astype(int))
|
||||
self.bbox = bbox
|
||||
self.mean = mean
|
||||
|
||||
if self.attr == 'GRID':
|
||||
self.grids = parse_grid(image)
|
||||
|
||||
return bbox, mean
|
||||
|
||||
def __str__(self):
|
||||
@ -87,6 +133,26 @@ class AssetsImage:
|
||||
else:
|
||||
return f'AssetsImage(file={self.file}, valid={self.valid})'
|
||||
|
||||
@property
|
||||
def is_GRID(self):
|
||||
return self.attr == 'GRID'
|
||||
|
||||
@property
|
||||
def is_base(self):
|
||||
return self.attr == ''
|
||||
|
||||
def iter_grids(self):
|
||||
frame = 0
|
||||
for posi, rect in self.grids.items():
|
||||
frame += 1
|
||||
image = AssetsImage(self.file)
|
||||
image.attr = ''
|
||||
image.bbox = rect
|
||||
image.mean = self.mean
|
||||
image.frame = frame
|
||||
image.posi = posi
|
||||
yield image
|
||||
|
||||
|
||||
def iter_images():
|
||||
for server in ASSET_SERVER:
|
||||
@ -97,6 +163,12 @@ def iter_images():
|
||||
yield AssetsImage(file)
|
||||
|
||||
|
||||
def iter_grids(images):
|
||||
for image in images:
|
||||
for grid in image.iter_grids():
|
||||
yield grid
|
||||
|
||||
|
||||
@dataclass
|
||||
class DataAssets:
|
||||
module: str
|
||||
@ -104,6 +176,7 @@ class DataAssets:
|
||||
server: str
|
||||
frame: int
|
||||
file: str = ''
|
||||
posi = None
|
||||
area: t.Tuple[int, int, int, int] = ()
|
||||
search: t.Tuple[int, int, int, int] = ()
|
||||
color: t.Tuple[int, int, int] = ()
|
||||
@ -126,7 +199,6 @@ class DataAssets:
|
||||
Product DataAssets from AssetsImage with attr=""
|
||||
"""
|
||||
data = cls(module=image.module, assets=image.assets, server=image.server, frame=image.frame, file=image.file)
|
||||
data.load_image(image)
|
||||
return data
|
||||
|
||||
def load_image(self, image: AssetsImage):
|
||||
@ -135,6 +207,7 @@ class DataAssets:
|
||||
self.area = image.bbox
|
||||
self.color = image.mean
|
||||
self.button = image.bbox
|
||||
self.posi = image.posi
|
||||
elif image.attr == 'AREA':
|
||||
self.area = image.bbox
|
||||
self.has_raw_area = True
|
||||
@ -147,6 +220,8 @@ class DataAssets:
|
||||
elif image.attr == 'BUTTON':
|
||||
self.button = image.bbox
|
||||
self.has_raw_button = True
|
||||
elif image.attr == 'GRID':
|
||||
pass
|
||||
else:
|
||||
logger.warning(f'Trying to load an image with unknown attribute: {image}')
|
||||
|
||||
@ -161,17 +236,22 @@ def iter_assets():
|
||||
for image in tqdm(images):
|
||||
image.parse()
|
||||
|
||||
images += list(iter_grids(images))
|
||||
|
||||
# Validate images
|
||||
images = SelectedGrids(images).select(valid=True)
|
||||
images.create_index('module', 'assets', 'server', 'frame', 'attr')
|
||||
for image in images.filter(lambda x: bool(x.attr)):
|
||||
image: AssetsImage = image
|
||||
if not images.indexed_select(image.module, image.assets, image.server, image.frame, ''):
|
||||
logger.warning(f'Attribute assets has no parent assets: {image.file}')
|
||||
image.valid = False
|
||||
if not images.indexed_select(image.module, image.assets, image.server, 1, ''):
|
||||
logger.warning(f'Attribute assets has no first frame: {image.file}')
|
||||
image.valid = False
|
||||
if image.is_GRID:
|
||||
pass
|
||||
else:
|
||||
if not images.indexed_select(image.module, image.assets, image.server, image.frame, ''):
|
||||
logger.warning(f'Attribute assets has no parent assets: {image.file}')
|
||||
image.valid = False
|
||||
if not images.indexed_select(image.module, image.assets, image.server, 1, ''):
|
||||
logger.warning(f'Attribute assets has no first frame: {image.file}')
|
||||
image.valid = False
|
||||
if image.attr == 'SEARCH' and image.frame > 1:
|
||||
logger.warning(f'Attribute SEARCH with frame > 1 is not allowed: {image.file}')
|
||||
image.valid = False
|
||||
@ -180,18 +260,18 @@ def iter_assets():
|
||||
# Convert to DataAssets
|
||||
data = {}
|
||||
for image in images:
|
||||
if image.attr == '':
|
||||
if image.is_base:
|
||||
row = DataAssets.product(image)
|
||||
row.load_image(image)
|
||||
deep_set(data, keys=[image.module, image.assets, image.server, image.frame], value=row)
|
||||
# Load attribute images
|
||||
for image in images:
|
||||
if image.attr != '':
|
||||
if not image.is_base:
|
||||
row = deep_get(data, keys=[image.module, image.assets, image.server, image.frame])
|
||||
row.load_image(image)
|
||||
# Set `search`
|
||||
for path, frames in deep_iter(data, depth=3):
|
||||
print(path, frames)
|
||||
# print(path, frames)
|
||||
for frame in frames.values():
|
||||
# Generate `search` from `area`
|
||||
if not frame.has_raw_search:
|
||||
@ -253,6 +333,8 @@ def generate_code():
|
||||
gen.ObjectAttr(key='search', value=frame.search)
|
||||
gen.ObjectAttr(key='color', value=frame.color)
|
||||
gen.ObjectAttr(key='button', value=frame.button)
|
||||
if frame.posi is not None:
|
||||
gen.ObjectAttr(key='posi', value=frame.posi)
|
||||
elif len(frames) == 1:
|
||||
frame = frames[0]
|
||||
with gen.ObjectAttr(key=server, value=gen.Object(object_class='Button')):
|
||||
@ -261,6 +343,8 @@ def generate_code():
|
||||
gen.ObjectAttr(key='search', value=frame.search)
|
||||
gen.ObjectAttr(key='color', value=frame.color)
|
||||
gen.ObjectAttr(key='button', value=frame.button)
|
||||
if frame.posi is not None:
|
||||
gen.ObjectAttr(key='posi', value=frame.posi)
|
||||
else:
|
||||
gen.ObjectAttr(key=server, value=None)
|
||||
gen.write(os.path.join(output, f'assets_{module.replace("/", "_")}.py'))
|
||||
|
@ -576,6 +576,8 @@ class KeywordExtract:
|
||||
self.load_keywords(['养成材料', '光锥', '遗器', '其他材料', '消耗品', '任务', '贵重物'])
|
||||
self.write_keywords(keyword_class='ItemTab', text_convert=lambda name: name.replace(' ', ''),
|
||||
output_file='./tasks/item/keywords/tab.py')
|
||||
from dev_tools.keywords.item import generate_items
|
||||
generate_items()
|
||||
self.generate_rogue_buff()
|
||||
self.load_keywords(['已强化'])
|
||||
self.write_keywords(keyword_class='RogueEnhancement', output_file='./tasks/rogue/keywords/enhancement.py')
|
||||
|
@ -159,6 +159,7 @@ class GenerateKeyword:
|
||||
base = self.keyword_format.copy()
|
||||
text_id = keyword.pop('text_id')
|
||||
if text_id is None:
|
||||
logger.warning(f'Empty text_id in {keyword}')
|
||||
return
|
||||
# id
|
||||
self.keyword_index += 1
|
||||
@ -191,3 +192,20 @@ class GenerateKeyword:
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
self.generate()
|
||||
|
||||
|
||||
class ShareData(GenerateKeyword):
|
||||
@cached_property
|
||||
def GameplayGuideData(self):
|
||||
return self.read_file('./ExcelOutput/GameplayGuideData.json')
|
||||
|
||||
@cached_property
|
||||
def MappingInfo(self):
|
||||
return self.read_file('./ExcelOutput/MappingInfo.json')
|
||||
|
||||
@cached_property
|
||||
def ItemConfig(self):
|
||||
return self.read_file('./ExcelOutput/ItemConfig.json')
|
||||
|
||||
|
||||
SHARE_DATA = ShareData()
|
||||
|
@ -1,7 +1,7 @@
|
||||
import re
|
||||
import typing as t
|
||||
|
||||
from dev_tools.keywords.base import GenerateKeyword, text_to_variable
|
||||
from dev_tools.keywords.base import GenerateKeyword, SHARE_DATA, text_to_variable
|
||||
from module.base.decorator import cached_property
|
||||
from module.config.utils import deep_get
|
||||
|
||||
@ -26,13 +26,14 @@ class GenerateDungeonList(GenerateKeyword):
|
||||
|
||||
@cached_property
|
||||
def data(self):
|
||||
return self.read_file('./ExcelOutput/GameplayGuideData.json')
|
||||
return SHARE_DATA.GameplayGuideData
|
||||
|
||||
def iter_keywords(self) -> t.Iterable[dict]:
|
||||
for keyword in self.iter_dungeon():
|
||||
if isinstance(keyword, str):
|
||||
yield dict(
|
||||
text_id=self.find_keyword(keyword, lang='cn')[0],
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
else:
|
||||
@ -41,6 +42,7 @@ class GenerateDungeonList(GenerateKeyword):
|
||||
def iter_dungeon(self):
|
||||
temp_save = ""
|
||||
for data in self.data.values():
|
||||
dungeon_id = data.get('ID', 0)
|
||||
text_id = deep_get(data, keys='Name.Hash')
|
||||
plane_id = deep_get(data, 'MapEntranceID', 0)
|
||||
_, name = self.find_keyword(text_id, lang='cn')
|
||||
@ -51,6 +53,7 @@ class GenerateDungeonList(GenerateKeyword):
|
||||
continue
|
||||
yield dict(
|
||||
text_id=text_id,
|
||||
dungeon_id=dungeon_id,
|
||||
plane_id=plane_id,
|
||||
)
|
||||
if temp_save:
|
||||
|
137
dev_tools/keywords/item.py
Normal file
@ -0,0 +1,137 @@
|
||||
import typing as t
|
||||
|
||||
from dev_tools.keywords.base import GenerateKeyword, SHARE_DATA
|
||||
from module.base.decorator import cached_property
|
||||
from module.config.utils import deep_get
|
||||
|
||||
|
||||
class GenerateItemBase(GenerateKeyword):
|
||||
purpose_type = []
|
||||
blacklist = []
|
||||
|
||||
def iter_items(self) -> t.Iterable[dict]:
|
||||
for data in SHARE_DATA.ItemConfig.values():
|
||||
item_id = data.get('ID', 0)
|
||||
text_id = deep_get(data, keys='ItemName.Hash')
|
||||
subtype = data.get('ItemSubType', 0)
|
||||
rarity = data.get('Rarity', 0)
|
||||
purpose = data.get('PurposeType', 0)
|
||||
item_group = data.get('ItemGroup', 0)
|
||||
yield dict(
|
||||
text_id=text_id,
|
||||
rarity=rarity,
|
||||
item_id=item_id,
|
||||
item_group=item_group,
|
||||
dungeon_id=-1,
|
||||
subtype=subtype,
|
||||
purpose=purpose,
|
||||
)
|
||||
|
||||
def iter_keywords(self) -> t.Iterable[dict]:
|
||||
for data in self.iter_items():
|
||||
if data['subtype'] == 'Material' and data['purpose'] in self.purpose_type:
|
||||
if data['item_id'] in self.blacklist:
|
||||
continue
|
||||
data['dungeon_id'] = self.dict_itemid_to_dungeonid.get(data['item_id'], -1)
|
||||
yield data
|
||||
|
||||
def iter_rows(self) -> t.Iterable[dict]:
|
||||
for data in super().iter_rows():
|
||||
data.pop('subtype')
|
||||
data.pop('purpose')
|
||||
yield data
|
||||
|
||||
@cached_property
|
||||
def dict_itemid_to_dungeonid(self):
|
||||
"""
|
||||
MappingInfo is like
|
||||
dungeon_id:
|
||||
dungeon_level:
|
||||
data
|
||||
"""
|
||||
dic = {}
|
||||
for level_data in SHARE_DATA.MappingInfo.values():
|
||||
# Use the highest level
|
||||
# And must contain:
|
||||
# "Type": "FARM_ENTRANCE",
|
||||
# "FarmType": "COCOON",
|
||||
for dungeon_data in level_data.values():
|
||||
if dungeon_data.get('Type') != 'FARM_ENTRANCE':
|
||||
continue
|
||||
# parse
|
||||
dungeon_id = dungeon_data.get('ID', 0)
|
||||
for item_data in dungeon_data.get('DisplayItemList', []):
|
||||
item_id = item_data.get('ItemID', 0)
|
||||
if item_id < 100:
|
||||
continue
|
||||
dic.setdefault(item_id, dungeon_id)
|
||||
|
||||
return dic
|
||||
|
||||
|
||||
class GenerateItemCurrency(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_currency.py'
|
||||
# Leave 'Credit' and `Trailblaze_EXP`
|
||||
whitelist = [2, 22]
|
||||
|
||||
def iter_keywords(self) -> t.Iterable[dict]:
|
||||
for data in self.iter_items():
|
||||
if data['subtype'] == 'Virtual' and data['item_id'] < 100:
|
||||
if data['item_id'] not in self.whitelist:
|
||||
continue
|
||||
yield data
|
||||
|
||||
|
||||
class GenerateItemExp(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_exp.py'
|
||||
purpose_type = [1, 5, 6]
|
||||
# 'Lost_Essence' is not available in game currently
|
||||
blacklist = [234]
|
||||
|
||||
|
||||
class GenerateItemAscension(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_ascension.py'
|
||||
purpose_type = [2]
|
||||
# 'Enigmatic_Ectostella' is not available in game currently
|
||||
blacklist = [110400]
|
||||
|
||||
|
||||
class GenerateItemTrace(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_trace.py'
|
||||
purpose_type = [3]
|
||||
# Can't farm Tears_of_Dreams
|
||||
blacklist = [110101]
|
||||
|
||||
|
||||
class GenerateItemWeekly(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_weekly.py'
|
||||
purpose_type = [4]
|
||||
|
||||
|
||||
class GenerateItemCalyx(GenerateItemBase):
|
||||
output_file = './tasks/planner/keywords/item_calyx.py'
|
||||
purpose_type = [7]
|
||||
|
||||
def iter_keywords(self) -> t.Iterable[dict]:
|
||||
items = list(super().iter_keywords())
|
||||
|
||||
# Copy dungeon_id from green item to all items in group
|
||||
dic_group_to_dungeonid = {}
|
||||
for item in items:
|
||||
dungeon = item['dungeon_id']
|
||||
if dungeon > 0:
|
||||
dic_group_to_dungeonid[item['item_group']] = dungeon
|
||||
for item in items:
|
||||
dungeon = dic_group_to_dungeonid[item['item_group']]
|
||||
item['dungeon_id'] = dungeon
|
||||
|
||||
yield from items
|
||||
|
||||
|
||||
def generate_items():
|
||||
GenerateItemCurrency()()
|
||||
GenerateItemExp()()
|
||||
GenerateItemAscension()()
|
||||
GenerateItemTrace()()
|
||||
GenerateItemWeekly()()
|
||||
GenerateItemCalyx()()
|
@ -6,7 +6,7 @@ from module.exception import ScriptError
|
||||
|
||||
|
||||
class Button(Resource):
|
||||
def __init__(self, file, area, search, color, button):
|
||||
def __init__(self, file, area, search, color, button, posi=None):
|
||||
"""
|
||||
Args:
|
||||
file: Filepath to an assets
|
||||
@ -20,6 +20,7 @@ class Button(Resource):
|
||||
self.search: t.Tuple[int, int, int, int] = search
|
||||
self.color: t.Tuple[int, int, int] = color
|
||||
self._button: t.Tuple[int, int, int, int] = button
|
||||
self.posi: t.Optional[t.Tuple[int, int]] = posi
|
||||
|
||||
self.resource_add(self.file)
|
||||
self._button_offset: t.Tuple[int, int] = (0, 0)
|
||||
|
@ -219,6 +219,308 @@
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"Item_Credit": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"type": "planner",
|
||||
"value": {},
|
||||
"display": "display",
|
||||
"stored": "StoredPlanner"
|
||||
}
|
||||
},
|
||||
"Dungeon": {
|
||||
"Name": {
|
||||
"type": "select",
|
||||
@ -334,93 +636,13 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"CalyxGolden": {
|
||||
"type": "select",
|
||||
"value": "Calyx_Golden_Treasures_Jarilo_VI",
|
||||
"option": [
|
||||
"do_not_achieve",
|
||||
"Calyx_Golden_Memories_Jarilo_VI",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu",
|
||||
"Calyx_Golden_Memories_Penacony",
|
||||
"Calyx_Golden_Aether_Jarilo_VI",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu",
|
||||
"Calyx_Golden_Aether_Penacony",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu",
|
||||
"Calyx_Golden_Treasures_Penacony"
|
||||
]
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"type": "select",
|
||||
"value": "Calyx_Crimson_Destruction_Herta_StorageZone",
|
||||
"option": [
|
||||
"do_not_achieve",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission"
|
||||
]
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"type": "select",
|
||||
"value": "Stagnant_Shadow_Quanta",
|
||||
"option": [
|
||||
"do_not_achieve",
|
||||
"Stagnant_Shadow_Spike",
|
||||
"Stagnant_Shadow_Perdition",
|
||||
"Stagnant_Shadow_Duty",
|
||||
"Stagnant_Shadow_Blaze",
|
||||
"Stagnant_Shadow_Scorch",
|
||||
"Stagnant_Shadow_Ire",
|
||||
"Stagnant_Shadow_Rime",
|
||||
"Stagnant_Shadow_Icicle",
|
||||
"Stagnant_Shadow_Nectar",
|
||||
"Stagnant_Shadow_Fulmination",
|
||||
"Stagnant_Shadow_Doom",
|
||||
"Stagnant_Shadow_Gust",
|
||||
"Stagnant_Shadow_Celestial",
|
||||
"Stagnant_Shadow_Quanta",
|
||||
"Stagnant_Shadow_Abomination",
|
||||
"Stagnant_Shadow_Roast",
|
||||
"Stagnant_Shadow_Mirage",
|
||||
"Stagnant_Shadow_Puppetry"
|
||||
]
|
||||
},
|
||||
"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",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive"
|
||||
]
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"Use": {
|
||||
"type": "select",
|
||||
"value": "when_daily",
|
||||
"option": [
|
||||
"always_use",
|
||||
"when_daily",
|
||||
"do_not_use"
|
||||
"always_use"
|
||||
]
|
||||
},
|
||||
"Character": {
|
||||
@ -1569,5 +1791,13 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"PlannerScan": {
|
||||
"ResultAdd": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -110,20 +110,6 @@ Dungeon:
|
||||
Team:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
||||
DungeonDaily:
|
||||
# Dungeon names will be injected in config updater
|
||||
CalyxGolden:
|
||||
value: Calyx_Golden_Treasures_Jarilo_VI
|
||||
option: [ do_not_achieve, ]
|
||||
CalyxCrimson:
|
||||
value: Calyx_Crimson_Destruction_Herta_StorageZone
|
||||
option: [ do_not_achieve, ]
|
||||
StagnantShadow:
|
||||
value: Stagnant_Shadow_Quanta
|
||||
option: [ do_not_achieve, ]
|
||||
CavernOfCorrosion:
|
||||
value: Cavern_of_Corrosion_Path_of_Providence
|
||||
option: [ do_not_achieve, ]
|
||||
DungeonSupport:
|
||||
Use:
|
||||
value: when_daily
|
||||
@ -151,6 +137,8 @@ DungeonStorage:
|
||||
color: "#8fb5fe"
|
||||
SupportReward:
|
||||
Collect: true
|
||||
Planner: {}
|
||||
# Items will be injected in config updater
|
||||
|
||||
Weekly:
|
||||
Name:
|
||||
@ -305,3 +293,5 @@ Daemon:
|
||||
AimClicker:
|
||||
value: do_not_click
|
||||
option: [ item_enemy, item, enemy, do_not_click ]
|
||||
PlannerScan:
|
||||
ResultAdd: false
|
||||
|
@ -31,7 +31,8 @@
|
||||
"menu": "list",
|
||||
"page": "tool",
|
||||
"tasks": [
|
||||
"Daemon"
|
||||
"Daemon",
|
||||
"PlannerScan"
|
||||
]
|
||||
}
|
||||
}
|
@ -30,6 +30,9 @@ Dungeon:
|
||||
value: true
|
||||
option: [ true, ]
|
||||
option_bold: [ true, ]
|
||||
DungeonSupport:
|
||||
Use:
|
||||
option: [ when_daily, always_use ]
|
||||
DailyQuest:
|
||||
Scheduler:
|
||||
Enable:
|
||||
|
@ -137,6 +137,556 @@
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "Item_Credit",
|
||||
"path": "Dungeon.Planner.Item_Credit",
|
||||
"i18n": "Planner.Item_Credit.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "Item_Trailblaze_EXP",
|
||||
"path": "Dungeon.Planner.Item_Trailblaze_EXP",
|
||||
"i18n": "Planner.Item_Trailblaze_EXP.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "Item_Traveler_Guide",
|
||||
"path": "Dungeon.Planner.Item_Traveler_Guide",
|
||||
"i18n": "Planner.Item_Traveler_Guide.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "Item_Refined_Aether",
|
||||
"path": "Dungeon.Planner.Item_Refined_Aether",
|
||||
"i18n": "Planner.Item_Refined_Aether.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "Item_Lost_Crystal",
|
||||
"path": "Dungeon.Planner.Item_Lost_Crystal",
|
||||
"i18n": "Planner.Item_Lost_Crystal.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "Item_Broken_Teeth_of_Iron_Wolf",
|
||||
"path": "Dungeon.Planner.Item_Broken_Teeth_of_Iron_Wolf",
|
||||
"i18n": "Planner.Item_Broken_Teeth_of_Iron_Wolf.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "Item_Endotherm_Chitin",
|
||||
"path": "Dungeon.Planner.Item_Endotherm_Chitin",
|
||||
"i18n": "Planner.Item_Endotherm_Chitin.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "Item_Horn_of_Snow",
|
||||
"path": "Dungeon.Planner.Item_Horn_of_Snow",
|
||||
"i18n": "Planner.Item_Horn_of_Snow.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "Item_Lightning_Crown_of_the_Past_Shadow",
|
||||
"path": "Dungeon.Planner.Item_Lightning_Crown_of_the_Past_Shadow",
|
||||
"i18n": "Planner.Item_Lightning_Crown_of_the_Past_Shadow.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "Item_Storm_Eye",
|
||||
"path": "Dungeon.Planner.Item_Storm_Eye",
|
||||
"i18n": "Planner.Item_Storm_Eye.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "Item_Void_Cast_Iron",
|
||||
"path": "Dungeon.Planner.Item_Void_Cast_Iron",
|
||||
"i18n": "Planner.Item_Void_Cast_Iron.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "Item_Golden_Crown_of_the_Past_Shadow",
|
||||
"path": "Dungeon.Planner.Item_Golden_Crown_of_the_Past_Shadow",
|
||||
"i18n": "Planner.Item_Golden_Crown_of_the_Past_Shadow.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "Item_Netherworld_Token",
|
||||
"path": "Dungeon.Planner.Item_Netherworld_Token",
|
||||
"i18n": "Planner.Item_Netherworld_Token.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "Item_Searing_Steel_Blade",
|
||||
"path": "Dungeon.Planner.Item_Searing_Steel_Blade",
|
||||
"i18n": "Planner.Item_Searing_Steel_Blade.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "Item_Gelid_Chitin",
|
||||
"path": "Dungeon.Planner.Item_Gelid_Chitin",
|
||||
"i18n": "Planner.Item_Gelid_Chitin.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "Item_Shape_Shifter_Lightning_Staff",
|
||||
"path": "Dungeon.Planner.Item_Shape_Shifter_Lightning_Staff",
|
||||
"i18n": "Planner.Item_Shape_Shifter_Lightning_Staff.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "Item_Ascendant_Debris",
|
||||
"path": "Dungeon.Planner.Item_Ascendant_Debris",
|
||||
"i18n": "Planner.Item_Ascendant_Debris.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "Item_Nail_of_the_Ape",
|
||||
"path": "Dungeon.Planner.Item_Nail_of_the_Ape",
|
||||
"i18n": "Planner.Item_Nail_of_the_Ape.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "Item_Suppressing_Edict",
|
||||
"path": "Dungeon.Planner.Item_Suppressing_Edict",
|
||||
"i18n": "Planner.Item_Suppressing_Edict.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "Item_IPC_Work_Permit",
|
||||
"path": "Dungeon.Planner.Item_IPC_Work_Permit",
|
||||
"i18n": "Planner.Item_IPC_Work_Permit.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "Item_Raging_Heart",
|
||||
"path": "Dungeon.Planner.Item_Raging_Heart",
|
||||
"i18n": "Planner.Item_Raging_Heart.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "Item_Dream_Fridge",
|
||||
"path": "Dungeon.Planner.Item_Dream_Fridge",
|
||||
"i18n": "Planner.Item_Dream_Fridge.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "Item_Dream_Flamer",
|
||||
"path": "Dungeon.Planner.Item_Dream_Flamer",
|
||||
"i18n": "Planner.Item_Dream_Flamer.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "Item_Worldbreaker_Blade",
|
||||
"path": "Dungeon.Planner.Item_Worldbreaker_Blade",
|
||||
"i18n": "Planner.Item_Worldbreaker_Blade.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "Item_Arrow_of_the_Starchaser",
|
||||
"path": "Dungeon.Planner.Item_Arrow_of_the_Starchaser",
|
||||
"i18n": "Planner.Item_Arrow_of_the_Starchaser.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "Item_Key_of_Wisdom",
|
||||
"path": "Dungeon.Planner.Item_Key_of_Wisdom",
|
||||
"i18n": "Planner.Item_Key_of_Wisdom.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "Item_Safeguard_of_Amber",
|
||||
"path": "Dungeon.Planner.Item_Safeguard_of_Amber",
|
||||
"i18n": "Planner.Item_Safeguard_of_Amber.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "Item_Obsidian_of_Obsession",
|
||||
"path": "Dungeon.Planner.Item_Obsidian_of_Obsession",
|
||||
"i18n": "Planner.Item_Obsidian_of_Obsession.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "Item_Stellaris_Symphony",
|
||||
"path": "Dungeon.Planner.Item_Stellaris_Symphony",
|
||||
"i18n": "Planner.Item_Stellaris_Symphony.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "Item_Flower_of_Eternity",
|
||||
"path": "Dungeon.Planner.Item_Flower_of_Eternity",
|
||||
"i18n": "Planner.Item_Flower_of_Eternity.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "Item_Moon_Madness_Fang",
|
||||
"path": "Dungeon.Planner.Item_Moon_Madness_Fang",
|
||||
"i18n": "Planner.Item_Moon_Madness_Fang.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "Item_Countertemporal_Shot",
|
||||
"path": "Dungeon.Planner.Item_Countertemporal_Shot",
|
||||
"i18n": "Planner.Item_Countertemporal_Shot.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "Item_Divine_Amber",
|
||||
"path": "Dungeon.Planner.Item_Divine_Amber",
|
||||
"i18n": "Planner.Item_Divine_Amber.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "Item_Heaven_Incinerator",
|
||||
"path": "Dungeon.Planner.Item_Heaven_Incinerator",
|
||||
"i18n": "Planner.Item_Heaven_Incinerator.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "Item_Heavenly_Melody",
|
||||
"path": "Dungeon.Planner.Item_Heavenly_Melody",
|
||||
"i18n": "Planner.Item_Heavenly_Melody.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "Item_Myriad_Fruit",
|
||||
"path": "Dungeon.Planner.Item_Myriad_Fruit",
|
||||
"i18n": "Planner.Item_Myriad_Fruit.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "Item_Tracks_of_Destiny",
|
||||
"path": "Dungeon.Planner.Item_Tracks_of_Destiny",
|
||||
"i18n": "Planner.Item_Tracks_of_Destiny.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "Item_Destroyer_Final_Road",
|
||||
"path": "Dungeon.Planner.Item_Destroyer_Final_Road",
|
||||
"i18n": "Planner.Item_Destroyer_Final_Road.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "Item_Guardian_Lament",
|
||||
"path": "Dungeon.Planner.Item_Guardian_Lament",
|
||||
"i18n": "Planner.Item_Guardian_Lament.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "Item_Regret_of_Infinite_Ochema",
|
||||
"path": "Dungeon.Planner.Item_Regret_of_Infinite_Ochema",
|
||||
"i18n": "Planner.Item_Regret_of_Infinite_Ochema.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "Item_Past_Evils_of_the_Borehole_Planet_Disaster",
|
||||
"path": "Dungeon.Planner.Item_Past_Evils_of_the_Borehole_Planet_Disaster",
|
||||
"i18n": "Planner.Item_Past_Evils_of_the_Borehole_Planet_Disaster.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "Item_Lost_Echo_of_the_Shared_Wish",
|
||||
"path": "Dungeon.Planner.Item_Lost_Echo_of_the_Shared_Wish",
|
||||
"i18n": "Planner.Item_Lost_Echo_of_the_Shared_Wish.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "Item_Squirming_Core",
|
||||
"path": "Dungeon.Planner.Item_Squirming_Core",
|
||||
"i18n": "Planner.Item_Squirming_Core.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "Item_Conqueror_Will",
|
||||
"path": "Dungeon.Planner.Item_Conqueror_Will",
|
||||
"i18n": "Planner.Item_Conqueror_Will.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "Item_Silvermane_Medal",
|
||||
"path": "Dungeon.Planner.Item_Silvermane_Medal",
|
||||
"i18n": "Planner.Item_Silvermane_Medal.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "Item_Ancient_Engine",
|
||||
"path": "Dungeon.Planner.Item_Ancient_Engine",
|
||||
"i18n": "Planner.Item_Ancient_Engine.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "Item_Immortal_Lumintwig",
|
||||
"path": "Dungeon.Planner.Item_Immortal_Lumintwig",
|
||||
"i18n": "Planner.Item_Immortal_Lumintwig.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "Item_Artifex_Gyreheart",
|
||||
"path": "Dungeon.Planner.Item_Artifex_Gyreheart",
|
||||
"i18n": "Planner.Item_Artifex_Gyreheart.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "Item_Dream_Making_Engine",
|
||||
"path": "Dungeon.Planner.Item_Dream_Making_Engine",
|
||||
"i18n": "Planner.Item_Dream_Making_Engine.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "Item_Shards_of_Desires",
|
||||
"path": "Dungeon.Planner.Item_Shards_of_Desires",
|
||||
"i18n": "Planner.Item_Shards_of_Desires.name",
|
||||
"stored": "StoredPlanner",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00"
|
||||
},
|
||||
"order": 0,
|
||||
"color": "#777777"
|
||||
},
|
||||
"Immersifier": {
|
||||
"name": "Immersifier",
|
||||
"path": "Dungeon.DungeonStorage.Immersifier",
|
||||
|
@ -25,8 +25,8 @@ Daily:
|
||||
tasks:
|
||||
Dungeon:
|
||||
- Scheduler
|
||||
- Planner
|
||||
- Dungeon
|
||||
- DungeonDaily
|
||||
- DungeonSupport
|
||||
- DungeonStorage
|
||||
DailyQuest:
|
||||
@ -70,3 +70,5 @@ Tool:
|
||||
tasks:
|
||||
Daemon:
|
||||
- Daemon
|
||||
PlannerScan:
|
||||
- PlannerScan
|
||||
|
@ -51,12 +51,6 @@ class GeneratedConfig:
|
||||
Dungeon_NameAtDoubleRelic = 'Cavern_of_Corrosion_Path_of_Providence' # 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, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
|
||||
Dungeon_Team = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
|
||||
# Group `DungeonDaily`
|
||||
DungeonDaily_CalyxGolden = 'Calyx_Golden_Treasures_Jarilo_VI' # do_not_achieve, Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony
|
||||
DungeonDaily_CalyxCrimson = 'Calyx_Crimson_Destruction_Herta_StorageZone' # do_not_achieve, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Abundance_Luofu_FyxestrollGarden, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission
|
||||
DungeonDaily_StagnantShadow = 'Stagnant_Shadow_Quanta' # do_not_achieve, Stagnant_Shadow_Spike, Stagnant_Shadow_Perdition, Stagnant_Shadow_Duty, Stagnant_Shadow_Blaze, Stagnant_Shadow_Scorch, Stagnant_Shadow_Ire, Stagnant_Shadow_Rime, Stagnant_Shadow_Icicle, Stagnant_Shadow_Nectar, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Doom, Stagnant_Shadow_Gust, Stagnant_Shadow_Celestial, Stagnant_Shadow_Quanta, Stagnant_Shadow_Abomination, Stagnant_Shadow_Roast, Stagnant_Shadow_Mirage, Stagnant_Shadow_Puppetry
|
||||
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, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
|
||||
|
||||
# Group `DungeonSupport`
|
||||
DungeonSupport_Use = 'when_daily' # always_use, when_daily, do_not_use
|
||||
DungeonSupport_Character = 'FirstCharacter' # FirstCharacter, Acheron, Argenti, Arlan, Asta, Aventurine, Bailu, BlackSwan, Blade, Bronya, Clara, DanHeng, DanHengImbibitorLunae, DrRatio, FuXuan, Gallagher, Gepard, Guinaifen, Hanya, Herta, Himeko, Hook, Huohuo, JingYuan, Jingliu, Kafka, Luka, Luocha, Lynx, March7th, Misha, Natasha, Pela, Qingque, Robin, RuanMei, Sampo, Seele, Serval, SilverWolf, Sparkle, Sushang, Tingyun, TopazNumby, TrailblazerDestruction, TrailblazerPreservation, Welt, Xueyi, Yanqing, Yukong
|
||||
@ -71,6 +65,58 @@ class GeneratedConfig:
|
||||
# Group `SupportReward`
|
||||
SupportReward_Collect = True
|
||||
|
||||
# Group `Planner`
|
||||
Planner_Item_Credit = {}
|
||||
Planner_Item_Trailblaze_EXP = {}
|
||||
Planner_Item_Traveler_Guide = {}
|
||||
Planner_Item_Refined_Aether = {}
|
||||
Planner_Item_Lost_Crystal = {}
|
||||
Planner_Item_Broken_Teeth_of_Iron_Wolf = {}
|
||||
Planner_Item_Endotherm_Chitin = {}
|
||||
Planner_Item_Horn_of_Snow = {}
|
||||
Planner_Item_Lightning_Crown_of_the_Past_Shadow = {}
|
||||
Planner_Item_Storm_Eye = {}
|
||||
Planner_Item_Void_Cast_Iron = {}
|
||||
Planner_Item_Golden_Crown_of_the_Past_Shadow = {}
|
||||
Planner_Item_Netherworld_Token = {}
|
||||
Planner_Item_Searing_Steel_Blade = {}
|
||||
Planner_Item_Gelid_Chitin = {}
|
||||
Planner_Item_Shape_Shifter_Lightning_Staff = {}
|
||||
Planner_Item_Ascendant_Debris = {}
|
||||
Planner_Item_Nail_of_the_Ape = {}
|
||||
Planner_Item_Suppressing_Edict = {}
|
||||
Planner_Item_IPC_Work_Permit = {}
|
||||
Planner_Item_Raging_Heart = {}
|
||||
Planner_Item_Dream_Fridge = {}
|
||||
Planner_Item_Dream_Flamer = {}
|
||||
Planner_Item_Worldbreaker_Blade = {}
|
||||
Planner_Item_Arrow_of_the_Starchaser = {}
|
||||
Planner_Item_Key_of_Wisdom = {}
|
||||
Planner_Item_Safeguard_of_Amber = {}
|
||||
Planner_Item_Obsidian_of_Obsession = {}
|
||||
Planner_Item_Stellaris_Symphony = {}
|
||||
Planner_Item_Flower_of_Eternity = {}
|
||||
Planner_Item_Moon_Madness_Fang = {}
|
||||
Planner_Item_Countertemporal_Shot = {}
|
||||
Planner_Item_Divine_Amber = {}
|
||||
Planner_Item_Heaven_Incinerator = {}
|
||||
Planner_Item_Heavenly_Melody = {}
|
||||
Planner_Item_Myriad_Fruit = {}
|
||||
Planner_Item_Tracks_of_Destiny = {}
|
||||
Planner_Item_Destroyer_Final_Road = {}
|
||||
Planner_Item_Guardian_Lament = {}
|
||||
Planner_Item_Regret_of_Infinite_Ochema = {}
|
||||
Planner_Item_Past_Evils_of_the_Borehole_Planet_Disaster = {}
|
||||
Planner_Item_Lost_Echo_of_the_Shared_Wish = {}
|
||||
Planner_Item_Squirming_Core = {}
|
||||
Planner_Item_Conqueror_Will = {}
|
||||
Planner_Item_Silvermane_Medal = {}
|
||||
Planner_Item_Ancient_Engine = {}
|
||||
Planner_Item_Immortal_Lumintwig = {}
|
||||
Planner_Item_Artifex_Gyreheart = {}
|
||||
Planner_Item_Dream_Making_Engine = {}
|
||||
Planner_Item_Shards_of_Desires = {}
|
||||
|
||||
# Group `Weekly`
|
||||
Weekly_Name = 'Echo_of_War_Divine_Seed' # Echo_of_War_Destruction_Beginning, Echo_of_War_End_of_the_Eternal_Freeze, Echo_of_War_Divine_Seed, Echo_of_War_Borehole_Planet_Old_Crater, Echo_of_War_Salutations_of_Ashen_Dreams
|
||||
Weekly_Team = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
@ -157,3 +203,6 @@ class GeneratedConfig:
|
||||
# Group `Daemon`
|
||||
Daemon_Enable = True # True
|
||||
Daemon_AimClicker = 'do_not_click' # item_enemy, item, enemy, do_not_click
|
||||
|
||||
# Group `PlannerScan`
|
||||
PlannerScan_ResultAdd = False
|
||||
|
@ -66,8 +66,9 @@ class ConfigGenerator:
|
||||
# Insert dungeons
|
||||
from tasks.dungeon.keywords import DungeonList
|
||||
calyx_golden = [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Golden_Memories] \
|
||||
+ [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Golden_Aether] \
|
||||
+ [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Golden_Treasures]
|
||||
+ [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Calyx_Golden_Aether] \
|
||||
+ [dungeon.name for dungeon in DungeonList.instances.values() if
|
||||
dungeon.is_Calyx_Golden_Treasures]
|
||||
# calyx_crimson
|
||||
from tasks.rogue.keywords import KEYWORDS_ROGUE_PATH as Path
|
||||
order = [Path.Destruction, Path.Preservation, Path.The_Hunt, Path.Abundance,
|
||||
@ -82,7 +83,8 @@ class ConfigGenerator:
|
||||
for type_ in CombatType.instances.values():
|
||||
stagnant_shadow += [dungeon.name for dungeon in DungeonList.instances.values()
|
||||
if dungeon.Stagnant_Shadow_Combat_Type == type_]
|
||||
cavern_of_corrosion = [dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Cavern_of_Corrosion]
|
||||
cavern_of_corrosion = [dungeon.name for dungeon in DungeonList.instances.values() if
|
||||
dungeon.is_Cavern_of_Corrosion]
|
||||
option_add(
|
||||
keys='Dungeon.Name.option',
|
||||
options=calyx_golden + calyx_crimson + stagnant_shadow + cavern_of_corrosion
|
||||
@ -90,11 +92,6 @@ class ConfigGenerator:
|
||||
# Double events
|
||||
option_add(keys='Dungeon.NameAtDoubleCalyx.option', options=calyx_golden + calyx_crimson)
|
||||
option_add(keys='Dungeon.NameAtDoubleRelic.option', options=cavern_of_corrosion)
|
||||
# Dungeon daily
|
||||
option_add(keys='DungeonDaily.CalyxGolden.option', options=calyx_golden)
|
||||
option_add(keys='DungeonDaily.CalyxCrimson.option', options=calyx_crimson)
|
||||
option_add(keys='DungeonDaily.StagnantShadow.option', options=stagnant_shadow)
|
||||
option_add(keys='DungeonDaily.CavernOfCorrosion.option', options=cavern_of_corrosion)
|
||||
option_add(
|
||||
keys='Weekly.Name.option',
|
||||
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Echo_of_War])
|
||||
@ -120,6 +117,15 @@ class ConfigGenerator:
|
||||
assignments = [entry.name for entry in AssignmentEntry.instances.values()]
|
||||
for i in range(4):
|
||||
option_add(keys=f'Assignment.Name_{i + 1}.option', options=assignments)
|
||||
# Insert planner items
|
||||
from tasks.planner.keywords.classes import ItemBase
|
||||
for item in ItemBase.instances.values():
|
||||
base = item.group_base
|
||||
deep_set(raw, keys=['Planner', f'Item_{base.name}'], value={
|
||||
'stored': 'StoredPlanner',
|
||||
'display': 'display',
|
||||
'type': 'planner',
|
||||
})
|
||||
|
||||
# Load
|
||||
for path, value in deep_iter(raw, depth=2):
|
||||
@ -131,7 +137,7 @@ class ConfigGenerator:
|
||||
if not isinstance(value, dict):
|
||||
value = {'value': value}
|
||||
arg['type'] = data_to_type(value, arg=path[1])
|
||||
if arg['type'] == 'stored':
|
||||
if arg['type'] in ['stored', 'planner']:
|
||||
value['value'] = {}
|
||||
arg['display'] = 'hide' # Hide `stored` by default
|
||||
if isinstance(value['value'], datetime):
|
||||
@ -381,7 +387,7 @@ class ConfigGenerator:
|
||||
i18n_aether = {
|
||||
'cn': '材料:武器经验({dungeon})',
|
||||
'cht': '材料:武器經驗({dungeon})',
|
||||
'jp': '素材:武器経験({dungeon}):',
|
||||
'jp': '素材:武器経験({dungeon})',
|
||||
'en': 'Material: Light Cone EXP ({dungeon})',
|
||||
'es': 'Material: EXP de conos de luz ({dungeon})',
|
||||
}
|
||||
@ -449,10 +455,6 @@ class ConfigGenerator:
|
||||
|
||||
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
|
||||
@ -497,6 +499,37 @@ class ConfigGenerator:
|
||||
name = deep_get(new, keys=['RogueWorld', 'World', dungeon.name], default=None)
|
||||
if name:
|
||||
deep_set(new, keys=['RogueWorld', 'World', dungeon.name], value=dungeon.__getattribute__(ingame_lang))
|
||||
# Planner items
|
||||
from tasks.planner.keywords.classes import ItemBase
|
||||
for item in ItemBase.instances.values():
|
||||
item: ItemBase = item
|
||||
name = f'Item_{item.name}'
|
||||
if item.is_ItemCurrency or item.name == 'Tracks_of_Destiny':
|
||||
i18n = item.__getattribute__(ingame_lang)
|
||||
elif item.is_ItemExp and item.is_group_base:
|
||||
dungeon = item.dungeon
|
||||
if dungeon is None:
|
||||
i18n = item.__getattribute__(ingame_lang)
|
||||
elif dungeon.is_Calyx_Golden_Memories:
|
||||
i18n = i18n_memories[ingame_lang]
|
||||
elif dungeon.is_Calyx_Golden_Aether:
|
||||
i18n = i18n_aether[ingame_lang]
|
||||
else:
|
||||
continue
|
||||
if res := re.search(r'[::](.*)[((]', i18n):
|
||||
i18n = res.group(1).strip()
|
||||
elif item.is_ItemAscension or (item.is_ItemTrace and item.is_group_base):
|
||||
dungeon = item.group_base.dungeon.name
|
||||
i18n = deep_get(new, keys=['Dungeon', 'Name', dungeon], default='Unknown_Dungeon_Come_From')
|
||||
elif item.is_ItemWeekly:
|
||||
dungeon = item.dungeon.name
|
||||
i18n = deep_get(new, keys=['Weekly', 'Name', dungeon], default='Unknown_Dungeon_Come_From')
|
||||
elif item.is_ItemCalyx and item.is_group_base:
|
||||
i18n = item.__getattribute__(ingame_lang)
|
||||
else:
|
||||
continue
|
||||
deep_set(new, keys=['Planner', name, 'name'], value=i18n)
|
||||
deep_set(new, keys=['Planner', name, 'help'], value='')
|
||||
|
||||
# GUI i18n
|
||||
for path, _ in deep_iter(self.gui, depth=2):
|
||||
@ -555,7 +588,7 @@ class ConfigGenerator:
|
||||
import module.config.stored.classes as classes
|
||||
data = {}
|
||||
for path, value in deep_iter(self.args, depth=3):
|
||||
if value.get('type') != 'stored':
|
||||
if value.get('type') not in ['stored', 'planner']:
|
||||
continue
|
||||
name = path[-1]
|
||||
stored = value.get('stored')
|
||||
@ -752,14 +785,10 @@ class ConfigUpdater:
|
||||
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('Clear_Calyx_Crimson_1_times',
|
||||
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')
|
||||
set_daily('Clear_Calyx_Golden_1_times', 'not_set')
|
||||
set_daily('Clear_Calyx_Crimson_1_times', 'not_set')
|
||||
set_daily('Clear_Stagnant_Shadow_1_times', 'not_set')
|
||||
set_daily('Clear_Cavern_of_Corrosion_1_times', 'not_set')
|
||||
# Combat requirements
|
||||
set_daily('In_a_single_battle_inflict_3_Weakness_Break_of_different_Types', 'achievable')
|
||||
set_daily('Inflict_Weakness_Break_5_times', 'achievable')
|
||||
@ -822,22 +851,10 @@ class ConfigUpdater:
|
||||
if key.endswith('Name'):
|
||||
if dungeon.is_Calyx_Golden:
|
||||
yield 'Dungeon.Dungeon.NameAtDoubleCalyx', value
|
||||
yield 'Dungeon.DungeonDaily.CalyxGolden', value
|
||||
elif dungeon.is_Calyx_Crimson:
|
||||
yield 'Dungeon.Dungeon.NameAtDoubleCalyx', value
|
||||
yield 'Dungeon.DungeonDaily.CalyxCrimson', value
|
||||
elif dungeon.is_Stagnant_Shadow:
|
||||
yield 'Dungeon.DungeonDaily.StagnantShadow', value
|
||||
elif dungeon.is_Cavern_of_Corrosion:
|
||||
yield 'Dungeon.Dungeon.NameAtDoubleRelic', value
|
||||
yield 'Dungeon.DungeonDaily.CavernOfCorrosion', value
|
||||
elif key.endswith('NameAtDoubleCalyx'):
|
||||
if dungeon.is_Calyx_Golden:
|
||||
yield 'Dungeon.DungeonDaily.CalyxGolden', value
|
||||
elif dungeon.is_Calyx_Crimson:
|
||||
yield 'Dungeon.DungeonDaily.CalyxCrimson', value
|
||||
elif key.endswith('NameAtDoubleRelic'):
|
||||
yield 'Dungeon.DungeonDaily.CavernOfCorrosion', value
|
||||
elif key.endswith('CavernOfCorrosion'):
|
||||
yield 'Dungeon.Dungeon.NameAtDoubleRelic', value
|
||||
elif key == 'Rogue.RogueWorld.UseImmersifier' and value is False:
|
||||
|
@ -61,6 +61,10 @@
|
||||
"Daemon": {
|
||||
"name": "Dialogue Clicker",
|
||||
"help": ""
|
||||
},
|
||||
"PlannerScan": {
|
||||
"name": "Character Planner",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Scheduler": {
|
||||
@ -351,81 +355,6 @@
|
||||
"9": "9"
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"_info": {
|
||||
"name": "Daily Quest Settings",
|
||||
"help": "Clear required dungeon once to achieve daily quests"
|
||||
},
|
||||
"CalyxGolden": {
|
||||
"name": "Clear Calyx Golden 1 times",
|
||||
"help": "",
|
||||
"do_not_achieve": "Don't Do This Quest",
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "Material: Character EXP (Bud of Memories (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "Material: Character EXP (Bud of Memories (The Xianzhou Luofu))",
|
||||
"Calyx_Golden_Memories_Penacony": "Material: Character EXP (Bud of Memories (Penacony))",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "Material: Light Cone EXP (Bud of Aether (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "Material: Light Cone EXP (Bud of Aether (The Xianzhou Luofu))",
|
||||
"Calyx_Golden_Aether_Penacony": "Material: Light Cone EXP (Bud of Aether (Penacony))",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "Material: Credit (Bud of Treasures (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "Material: Credit (Bud of Treasures (The Xianzhou Luofu))",
|
||||
"Calyx_Golden_Treasures_Penacony": "Material: Credit (Bud of Treasures (Penacony))"
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"name": "Clear Calyx Crimson 1 times",
|
||||
"help": "",
|
||||
"do_not_achieve": "Don't Do This Quest",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone": "Trace: Destruction (Storage Zone)",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Trace: Destruction (Scalegorge Waterscape)",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Trace: Preservation (Supply Zone)",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Trace: Preservation (Clock Studios Theme Park)",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Trace: The Hunt (Outlying Snow Plains)",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue": "Trace: The Hunt (SoulGlad Scorchsand Audition Venue)",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Trace: Abundance (Backwater Pass)",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Trace: Abundance (Fyxestroll Garden)",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Trace: Erudition (Rivet Town)",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Trace: The Harmony (Robot Settlement)",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Trace: The Harmony (The Reverie (Dreamscape))",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine": "Trace: Nihility (Great Mine)",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission": "Trace: Nihility (Alchemy Commission)"
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"name": "Clear Stagnant Shadow 1 times",
|
||||
"help": "",
|
||||
"do_not_achieve": "Don't Do This Quest",
|
||||
"Stagnant_Shadow_Spike": "Ascension: Physical (Natasha / Clara / Luka / Sushang)",
|
||||
"Stagnant_Shadow_Perdition": "Ascension: Physical (Hanya / Argenti)",
|
||||
"Stagnant_Shadow_Duty": "Ascension: Physical (Boothill / Robin)",
|
||||
"Stagnant_Shadow_Blaze": "Ascension: Fire (Himeko / Asta / Hook)",
|
||||
"Stagnant_Shadow_Scorch": "Ascension: Fire (Guinaifen / Topaz & Numby)",
|
||||
"Stagnant_Shadow_Ire": "Ascension: Fire (Gallagher)",
|
||||
"Stagnant_Shadow_Rime": "Ascension: Ice (March 7th / Herta / Gepard / Pela)",
|
||||
"Stagnant_Shadow_Icicle": "Ascension: Ice (Yanqing / Jingliu / Ruan Mei)",
|
||||
"Stagnant_Shadow_Nectar": "Ascension: Ice (Misha)",
|
||||
"Stagnant_Shadow_Fulmination": "Ascension: Lightning (Arlan / Serval / Tingyun / Bailu)",
|
||||
"Stagnant_Shadow_Doom": "Ascension: Lightning (Kafka / Jing Yuan / Acheron)",
|
||||
"Stagnant_Shadow_Gust": "Ascension: Wind (Dan Heng / Bronya / Sampo)",
|
||||
"Stagnant_Shadow_Celestial": "Ascension: Wind (Blade / Huohuo / Black Swan)",
|
||||
"Stagnant_Shadow_Quanta": "Ascension: Quantum (Silver Wolf / Seele / Qingque)",
|
||||
"Stagnant_Shadow_Abomination": "Ascension: Quantum (Lynx / Fu Xuan / Xueyi)",
|
||||
"Stagnant_Shadow_Roast": "Ascension: Quantum (Sparkle)",
|
||||
"Stagnant_Shadow_Mirage": "Ascension: Imaginary (Welt / Luocha / Yukong)",
|
||||
"Stagnant_Shadow_Puppetry": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Aventurine / Dr. Ratio)"
|
||||
},
|
||||
"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)",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness": "Relics: Pursuit Set & Dot Set (Path of Darkness)",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive": "Relics: Debuff Set & Break Effect Set (Path of Dreamdive)"
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"_info": {
|
||||
"name": "Support Settings",
|
||||
@ -529,6 +458,212 @@
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"_info": {
|
||||
"name": "Character Planner Progress",
|
||||
"help": "Character planner is prioritized. After completed, \"Dungeon Settings\" will be executed."
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "Credit",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "Trailblaze EXP",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "Character EXP",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "Light Cone EXP",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "Lost Crystal",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "Ascension: Physical (Natasha / Clara / Luka / Sushang)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "Ascension: Fire (Himeko / Asta / Hook)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "Ascension: Ice (March 7th / Herta / Gepard / Pela)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "Ascension: Lightning (Arlan / Serval / Tingyun / Bailu)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "Ascension: Wind (Dan Heng / Bronya / Sampo)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "Ascension: Quantum (Silver Wolf / Seele / Qingque)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "Ascension: Imaginary (Welt / Luocha / Yukong)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "Ascension: Physical (Hanya / Argenti)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "Ascension: Fire (Guinaifen / Topaz & Numby)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "Ascension: Ice (Yanqing / Jingliu / Ruan Mei)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "Ascension: Lightning (Kafka / Jing Yuan / Acheron)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "Ascension: Wind (Blade / Huohuo / Black Swan)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "Ascension: Quantum (Lynx / Fu Xuan / Xueyi)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Aventurine / Dr. Ratio)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "Ascension: Physical (Boothill / Robin)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "Ascension: Fire (Gallagher)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "Ascension: Ice (Misha)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "Ascension: Quantum (Sparkle)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "Trace: Destruction (Storage Zone)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "Trace: The Hunt (Outlying Snow Plains)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "Trace: Erudition (Rivet Town)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "Trace: Preservation (Supply Zone)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "Trace: Nihility (Great Mine)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "Trace: The Harmony (Robot Settlement)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "Trace: Abundance (Backwater Pass)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "Trace: Destruction (Scalegorge Waterscape)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "Trace: The Hunt (SoulGlad Scorchsand Audition Venue)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "Trace: Preservation (Clock Studios Theme Park)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "Trace: Nihility (Alchemy Commission)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "Trace: The Harmony (The Reverie (Dreamscape))",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "Trace: Abundance (Fyxestroll Garden)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "Tracks of Destiny",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "Destruction's Beginning (Herta Space Station)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "End of the Eternal Freeze (Jarilo-VI)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "Divine Seed (The Xianzhou Luofu)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "Borehole Planet's Old Crater (Herta Space Station)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "Salutations of Ashen Dreams (Penacony)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "Squirming Core",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "Conqueror's Will",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "Silvermane Medal",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "Ancient Engine",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "Immortal Lumintwig",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "Artifex's Gyreheart",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "Dream Making Engine",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "Shards of Desires",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Weekly": {
|
||||
"_info": {
|
||||
"name": "Echo of War Settings",
|
||||
@ -1063,6 +1198,16 @@
|
||||
"do_not_click": "Don't click"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"_info": {
|
||||
"name": "Scan Character Planner Results",
|
||||
"help": "Tools need to stop the scheduler and then run independently\nBefore use, set planner goal in the in-game planner, calculate the results, and start scanning from the result page. Detailed usage see: https://github.com/LmeSzinc/StarRailCopilot/wiki/Planner_cn"
|
||||
},
|
||||
"ResultAdd": {
|
||||
"name": "Accumulate multiple scan results",
|
||||
"help": "Turn on when planning multiple characters, will raise multiple characters all together\nTurn off when planning one character, planning goal will be refreshed at every scan"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
"Aside": {
|
||||
"Install": "Install",
|
||||
|
@ -61,6 +61,10 @@
|
||||
"Daemon": {
|
||||
"name": "Clic de diálogo",
|
||||
"help": ""
|
||||
},
|
||||
"PlannerScan": {
|
||||
"name": "Planificador de personajes",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Scheduler": {
|
||||
@ -351,81 +355,6 @@
|
||||
"9": "9"
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"_info": {
|
||||
"name": "Ajustes de Entrenamiento diario",
|
||||
"help": "Se limpiará la mazmorra requerida una vez para completar la misión diaria."
|
||||
},
|
||||
"CalyxGolden": {
|
||||
"name": "Completar Cáliz (oro) 1 vez",
|
||||
"help": "",
|
||||
"do_not_achieve": "No hacer esta misión",
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "Material: EXP de personaje (Flor de los recuerdos (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "Material: EXP de personaje (Flor de los recuerdos (El Luofu de Xianzhou))",
|
||||
"Calyx_Golden_Memories_Penacony": "Material: EXP de personaje (Flor de los recuerdos (Colonipenal))",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "Material: EXP de conos de luz (Flor de éter (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "Material: EXP de conos de luz (Flor de éter (El Luofu de Xianzhou))",
|
||||
"Calyx_Golden_Aether_Penacony": "Material: EXP de conos de luz (Flor de éter (Colonipenal))",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "Material: Créditos (Flor de tesoros (Jarilo-Ⅵ))",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "Material: Créditos (Flor de tesoros (El Luofu de Xianzhou))",
|
||||
"Calyx_Golden_Treasures_Penacony": "Material: Créditos (Flor de tesoros (Colonipenal))"
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"name": "Completar Cáliz (carmesí) 1 vez",
|
||||
"help": "",
|
||||
"do_not_achieve": "No hacer esta misión",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone": "Rastros: Destrucción (Zona de almacenamiento)",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Rastros: Destrucción (Desfiladero de Escamas)",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Rastros: Conservación (Zona de suministros)",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Rastros: Conservación (Parque temático de los Estudios Reloj)",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Rastros: Cacería (Llanuras nevadas de las afueras)",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue": "Rastros: Cacería (Recinto de las Audiciones FelizAlma en la Arena Ardiente)",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Rastros: Abundancia (Paso del Remanso)",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Rastros: Abundancia (Jardín del Sosiego)",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Rastros: Erudición (Villarremache)",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Rastros: Armonía (Asentamiento robot)",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Rastros: Armonía (Hotel Fantasía (paisaje onírico))",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine": "Rastros: Nihilidad (Mina principal)",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission": "Rastros: Nihilidad (Comisión de Alquimia)"
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"name": "Completar Sombra paralizada 1 vez",
|
||||
"help": "",
|
||||
"do_not_achieve": "No hacer esta misión",
|
||||
"Stagnant_Shadow_Spike": "Ascension: Físico (Natasha / Clara / Luka / Sushang)",
|
||||
"Stagnant_Shadow_Perdition": "Ascension: Físico (Hanya / Argenti)",
|
||||
"Stagnant_Shadow_Duty": "Ascension: Físico (Boothill / Robin)",
|
||||
"Stagnant_Shadow_Blaze": "Ascension: Fuego (Himeko / Asta / Hook)",
|
||||
"Stagnant_Shadow_Scorch": "Ascension: Fuego (Guinaifen / Topaz y Conti)",
|
||||
"Stagnant_Shadow_Ire": "Ascension: Fuego (Gallagher)",
|
||||
"Stagnant_Shadow_Rime": "Ascension: Hielo (Siete de Marzo / Herta / Gepard / Pela)",
|
||||
"Stagnant_Shadow_Icicle": "Ascension: Hielo (Yanqing / Jingliu / Ruan Mei)",
|
||||
"Stagnant_Shadow_Nectar": "Ascension: Hielo (Misha)",
|
||||
"Stagnant_Shadow_Fulmination": "Ascension: Rayo (Arlan / Serval / Tingyun / Bailu)",
|
||||
"Stagnant_Shadow_Doom": "Ascension: Rayo (Kafka / Jing Yuan / Acheron)",
|
||||
"Stagnant_Shadow_Gust": "Ascension: Viento (Dan Heng / Bronya / Sampo)",
|
||||
"Stagnant_Shadow_Celestial": "Ascension: Viento (Blade / Huohuo / Cisne Negro)",
|
||||
"Stagnant_Shadow_Quanta": "Ascension: Cuántico (Silver Wolf / Seele / Qingque)",
|
||||
"Stagnant_Shadow_Abomination": "Ascension: Cuántico (Lynx / Fu Xuan / Xueyi)",
|
||||
"Stagnant_Shadow_Roast": "Ascension: Cuántico (Sparkle)",
|
||||
"Stagnant_Shadow_Mirage": "Ascension: Imaginario (Welt / Luocha / Yukong)",
|
||||
"Stagnant_Shadow_Puppetry": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Aventurino / Dr. Ratio)"
|
||||
},
|
||||
"CavernOfCorrosion": {
|
||||
"name": "Completar Caverna de la corrosión 1 vez",
|
||||
"help": "",
|
||||
"do_not_achieve": "No hacer esta misión",
|
||||
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Artefactos: Hielo y Viento (Senda del viento gélido)",
|
||||
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Artefactos: Físico y Efecto de Ruptura (Senda de los puños rápidos)",
|
||||
"Cavern_of_Corrosion_Path_of_Drifting": "Artefactos: Curación y Pistolera de la espiga silvestre (Senda de la deriva)",
|
||||
"Cavern_of_Corrosion_Path_of_Providence": "Artefactos: Guardia de la nieve y Cuántico (Senda de al providencia) (Senda de la providencia)",
|
||||
"Cavern_of_Corrosion_Path_of_Holy_Hymn": "Artefactos: Defensa y Trueno (Senda del himno sagrado)",
|
||||
"Cavern_of_Corrosion_Path_of_Conflagration": "Artefactos: Fuego e Imaginario (Senda de la conflagración)",
|
||||
"Cavern_of_Corrosion_Path_of_Elixir_Seekers": "Artefactos: HP y SPD (Senda de los elixires)",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness": "Artefactos: Persecución y Dot (Senda de la oscuridad)",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive": "Artefactos: Debuff y Efecto de Ruptura (Senda de los sueños)"
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"_info": {
|
||||
"name": "Ajustes de Apoyo",
|
||||
@ -529,6 +458,212 @@
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"_info": {
|
||||
"name": "Progreso del planificador de personajes",
|
||||
"help": "Se prioriza el planificador de personajes. Una vez completado, se ejecutará la \"Ajustes de Mazmorra\"."
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "Crédito",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "EXP trazacaminos",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "EXP de personaje",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "EXP de conos de luz",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "Cristal perdido",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "Ascension: Físico (Natasha / Clara / Luka / Sushang)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "Ascension: Fuego (Himeko / Asta / Hook)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "Ascension: Hielo (Siete de Marzo / Herta / Gepard / Pela)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "Ascension: Rayo (Arlan / Serval / Tingyun / Bailu)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "Ascension: Viento (Dan Heng / Bronya / Sampo)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "Ascension: Cuántico (Silver Wolf / Seele / Qingque)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "Ascension: Imaginario (Welt / Luocha / Yukong)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "Ascension: Físico (Hanya / Argenti)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "Ascension: Fuego (Guinaifen / Topaz y Conti)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "Ascension: Hielo (Yanqing / Jingliu / Ruan Mei)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "Ascension: Rayo (Kafka / Jing Yuan / Acheron)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "Ascension: Viento (Blade / Huohuo / Cisne Negro)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "Ascension: Cuántico (Lynx / Fu Xuan / Xueyi)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Aventurino / Dr. Ratio)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "Ascension: Físico (Boothill / Robin)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "Ascension: Fuego (Gallagher)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "Ascension: Hielo (Misha)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "Ascension: Cuántico (Sparkle)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "Rastros: Destrucción (Zona de almacenamiento)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "Rastros: Cacería (Llanuras nevadas de las afueras)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "Rastros: Erudición (Villarremache)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "Rastros: Conservación (Zona de suministros)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "Rastros: Nihilidad (Mina principal)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "Rastros: Armonía (Asentamiento robot)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "Rastros: Abundancia (Paso del Remanso)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "Rastros: Destrucción (Desfiladero de Escamas)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "Rastros: Cacería (Recinto de las Audiciones FelizAlma en la Arena Ardiente)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "Rastros: Conservación (Parque temático de los Estudios Reloj)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "Rastros: Nihilidad (Comisión de Alquimia)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "Rastros: Armonía (Hotel Fantasía (paisaje onírico))",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "Rastros: Abundancia (Jardín del Sosiego)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "Huellas del destino",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "El principio de la Destrucción (Estación Espacial Herta)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "El fin del Hielo Eterno (Jarilo-VI)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "Semilla divina (El Luofu de Xianzhou)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "Cráter del planeta devorado (Estación Espacial Herta)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "Ecos de la guerra: Tributo del sueño ceniciento (Colonipenal)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "Núcleo serpenteante",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "Voluntad de conquista",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "Medalla del guardia",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "Motor antiguo",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "Rama gloriosa inmortal",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "Corazón armonioso mecánico",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "Motor creasueños",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "Fragmento de deseos",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Weekly": {
|
||||
"_info": {
|
||||
"name": "Ajustes de Ecos de la guerra",
|
||||
@ -1063,6 +1198,16 @@
|
||||
"do_not_click": "No hacer clic"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"_info": {
|
||||
"name": "Escanear resultados del planificador de caracteres",
|
||||
"help": "Las herramientas deben detener el programador y luego ejecutarse de forma independiente\nAntes de usarlo, establezca el objetivo del planificador en el planificador del juego, calcule los resultados y comience a escanear desde la página de resultados. Para uso detallado, consulte: https://github .com/LmeSzinc/StarRailCopilot/wiki/Planner_cn"
|
||||
},
|
||||
"ResultAdd": {
|
||||
"name": "Acumular múltiples resultados de escaneo",
|
||||
"help": "Activar cuando se planifican varios personajes, generará varios personajes todos juntos\nDesactivar cuando se planifica un personaje, el objetivo de planificación se actualizará en cada escaneo"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
"Aside": {
|
||||
"Install": "Instalar",
|
||||
|
@ -61,6 +61,10 @@
|
||||
"Daemon": {
|
||||
"name": "Task.Daemon.name",
|
||||
"help": "Task.Daemon.help"
|
||||
},
|
||||
"PlannerScan": {
|
||||
"name": "Task.PlannerScan.name",
|
||||
"help": "Task.PlannerScan.help"
|
||||
}
|
||||
},
|
||||
"Scheduler": {
|
||||
@ -251,9 +255,9 @@
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "素材:役割経験(回憶の蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "素材:役割経験(回憶の蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Memories_Penacony": "素材:役割経験(回憶の蕾・ピノコニー):",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "素材:武器経験(エーテルの蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "素材:武器経験(エーテルの蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Aether_Penacony": "素材:武器経験(エーテルの蕾・ピノコニー):",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "素材:武器経験(エーテルの蕾・ヤリーロ-Ⅵ)",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "素材:武器経験(エーテルの蕾・仙舟羅浮)",
|
||||
"Calyx_Golden_Aether_Penacony": "素材:武器経験(エーテルの蕾・ピノコニー)",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "素材:クレジット(秘蔵の蕾・ヤリーロ-Ⅵ)",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "素材:クレジット(秘蔵の蕾・仙舟羅浮)",
|
||||
"Calyx_Golden_Treasures_Penacony": "素材:クレジット(秘蔵の蕾・ピノコニー)",
|
||||
@ -304,9 +308,9 @@
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "素材:役割経験(回憶の蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "素材:役割経験(回憶の蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Memories_Penacony": "素材:役割経験(回憶の蕾・ピノコニー):",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "素材:武器経験(エーテルの蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "素材:武器経験(エーテルの蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Aether_Penacony": "素材:武器経験(エーテルの蕾・ピノコニー):",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "素材:武器経験(エーテルの蕾・ヤリーロ-Ⅵ)",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "素材:武器経験(エーテルの蕾・仙舟羅浮)",
|
||||
"Calyx_Golden_Aether_Penacony": "素材:武器経験(エーテルの蕾・ピノコニー)",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "素材:クレジット(秘蔵の蕾・ヤリーロ-Ⅵ)",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "素材:クレジット(秘蔵の蕾・仙舟羅浮)",
|
||||
"Calyx_Golden_Treasures_Penacony": "素材:クレジット(秘蔵の蕾・ピノコニー)",
|
||||
@ -351,81 +355,6 @@
|
||||
"9": "9"
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"_info": {
|
||||
"name": "DungeonDaily._info.name",
|
||||
"help": "DungeonDaily._info.help"
|
||||
},
|
||||
"CalyxGolden": {
|
||||
"name": "DungeonDaily.CalyxGolden.name",
|
||||
"help": "DungeonDaily.CalyxGolden.help",
|
||||
"do_not_achieve": "do_not_achieve",
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "素材:役割経験(回憶の蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "素材:役割経験(回憶の蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Memories_Penacony": "素材:役割経験(回憶の蕾・ピノコニー):",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "素材:武器経験(エーテルの蕾・ヤリーロ-Ⅵ):",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "素材:武器経験(エーテルの蕾・仙舟羅浮):",
|
||||
"Calyx_Golden_Aether_Penacony": "素材:武器経験(エーテルの蕾・ピノコニー):",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "素材:クレジット(秘蔵の蕾・ヤリーロ-Ⅵ)",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "素材:クレジット(秘蔵の蕾・仙舟羅浮)",
|
||||
"Calyx_Golden_Treasures_Penacony": "素材:クレジット(秘蔵の蕾・ピノコニー)"
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"name": "DungeonDaily.CalyxCrimson.name",
|
||||
"help": "DungeonDaily.CalyxCrimson.help",
|
||||
"do_not_achieve": "do_not_achieve",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone": "軌跡素材:壊滅(収容部分)",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "軌跡素材:壊滅(鱗淵境)",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone": "軌跡素材:存護(サポート部分)",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "軌跡素材:存護(クラークフィルムランド)",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "軌跡素材:巡狩(郊外雪原)",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue": "軌跡素材:巡狩(スラーダ熱砂オーディション会場)",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "軌跡素材:豊穣(外縁通路)",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "軌跡素材:豊穣(綏園)",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "軌跡素材:知恵(リベットタウン)",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "軌跡素材:調和(機械集落)",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "軌跡素材:調和(ホテル・レバリー-夢境)",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine": "軌跡素材:虚無(大鉱区)",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission": "軌跡素材:虚無(丹鼎司)"
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"name": "DungeonDaily.StagnantShadow.name",
|
||||
"help": "DungeonDaily.StagnantShadow.help",
|
||||
"do_not_achieve": "do_not_achieve",
|
||||
"Stagnant_Shadow_Spike": "キャラクター昇格素材:物理(ナターシャ / クラーラ / ルカ / 素裳)",
|
||||
"Stagnant_Shadow_Perdition": "キャラクター昇格素材:物理(寒鴉 / アルジェンティ)",
|
||||
"Stagnant_Shadow_Duty": "キャラクター昇格素材:物理(ブートヒル / ロビン)",
|
||||
"Stagnant_Shadow_Blaze": "キャラクター昇格素材:炎(姫子 / アスター / フック)",
|
||||
"Stagnant_Shadow_Scorch": "キャラクター昇格素材:炎(桂乃芬 / トパーズ&カブ)",
|
||||
"Stagnant_Shadow_Ire": "キャラクター昇格素材:炎(ギャラガー)",
|
||||
"Stagnant_Shadow_Rime": "キャラクター昇格素材:氷(三月なのか / ヘルタ / ジェパード / ペラ)",
|
||||
"Stagnant_Shadow_Icicle": "キャラクター昇格素材:氷(彦卿 / 鏡流 / ルアン・メェイ)",
|
||||
"Stagnant_Shadow_Nectar": "キャラクター昇格素材:氷(ミーシャ)",
|
||||
"Stagnant_Shadow_Fulmination": "キャラクター昇格素材:雷(アーラン / セーバル / 停雲 / 白露)",
|
||||
"Stagnant_Shadow_Doom": "キャラクター昇格素材:雷(カフカ / 景元 / 黄泉)",
|
||||
"Stagnant_Shadow_Gust": "キャラクター昇格素材:風(丹恒 / ブローニャ / サンポ)",
|
||||
"Stagnant_Shadow_Celestial": "キャラクター昇格素材:風(刃 / フォフォ / ブラックスワン)",
|
||||
"Stagnant_Shadow_Quanta": "キャラクター昇格素材:量子(銀狼 / ゼーレ / 青雀)",
|
||||
"Stagnant_Shadow_Abomination": "キャラクター昇格素材:量子(リンクス / 符玄 / 雪衣)",
|
||||
"Stagnant_Shadow_Roast": "キャラクター昇格素材:量子(花火)",
|
||||
"Stagnant_Shadow_Mirage": "キャラクター昇格素材:虚数(ヴェルト / 羅刹 / 御空)",
|
||||
"Stagnant_Shadow_Puppetry": "キャラクター昇格素材:虚数(丹恒・飲月 / アベンチュリン / Dr.レイシオ)"
|
||||
},
|
||||
"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": "侵蝕トンネル・薬使の路(侵蝕トンネル・薬使の路)",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness": "侵蝕トンネル・幽冥の路(侵蝕トンネル・幽冥の路)",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive": "侵蝕トンネル・夢潜の路(侵蝕トンネル・夢潜の路)"
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"_info": {
|
||||
"name": "DungeonSupport._info.name",
|
||||
@ -529,6 +458,212 @@
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"_info": {
|
||||
"name": "Planner._info.name",
|
||||
"help": "Planner._info.help"
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "信用ポイント",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "マイレージ",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "役割経験",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "武器経験",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "遺失晶塊",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "キャラクター昇格素材:物理(ナターシャ / クラーラ / ルカ / 素裳)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "キャラクター昇格素材:炎(姫子 / アスター / フック)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "キャラクター昇格素材:氷(三月なのか / ヘルタ / ジェパード / ペラ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "キャラクター昇格素材:雷(アーラン / セーバル / 停雲 / 白露)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "キャラクター昇格素材:風(丹恒 / ブローニャ / サンポ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "キャラクター昇格素材:量子(銀狼 / ゼーレ / 青雀)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "キャラクター昇格素材:虚数(ヴェルト / 羅刹 / 御空)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "キャラクター昇格素材:物理(寒鴉 / アルジェンティ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "キャラクター昇格素材:炎(桂乃芬 / トパーズ&カブ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "キャラクター昇格素材:氷(彦卿 / 鏡流 / ルアン・メェイ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "キャラクター昇格素材:雷(カフカ / 景元 / 黄泉)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "キャラクター昇格素材:風(刃 / フォフォ / ブラックスワン)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "キャラクター昇格素材:量子(リンクス / 符玄 / 雪衣)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "キャラクター昇格素材:虚数(丹恒・飲月 / アベンチュリン / Dr.レイシオ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "キャラクター昇格素材:物理(ブートヒル / ロビン)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "キャラクター昇格素材:炎(ギャラガー)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "キャラクター昇格素材:氷(ミーシャ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "キャラクター昇格素材:量子(花火)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "軌跡素材:壊滅(収容部分)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "軌跡素材:巡狩(郊外雪原)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "軌跡素材:知恵(リベットタウン)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "軌跡素材:存護(サポート部分)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "軌跡素材:虚無(大鉱区)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "軌跡素材:調和(機械集落)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "軌跡素材:豊穣(外縁通路)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "軌跡素材:壊滅(鱗淵境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "軌跡素材:巡狩(スラーダ熱砂オーディション会場)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "軌跡素材:存護(クラークフィルムランド)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "軌跡素材:虚無(丹鼎司)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "軌跡素材:調和(ホテル・レバリー-夢境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "軌跡素材:豊穣(綏園)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "運命の足跡",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "歴戦余韻・壊滅の始まり (宇宙ステーション「ヘルタ」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "歴戦余韻・寒波の幕切れ (ヤリーロ-VI)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "歴戦余韻・不死の神実 (仙舟「羅浮」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "歴戦余韻・星を蝕む往日の面影 (宇宙ステーション「ヘルタ」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "歴戦余韻・現世の夢の礼賛 (ピノコニー)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "脈動する原核",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "踏みにじる意志",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "シルバーメインの勲章",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "古代エンジン",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "永寿の栄枝",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "工造渾心",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "ドリームメイキングモーター",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "砕けた欲望の鏡",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Weekly": {
|
||||
"_info": {
|
||||
"name": "Weekly._info.name",
|
||||
@ -1063,6 +1198,16 @@
|
||||
"do_not_click": "do_not_click"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"_info": {
|
||||
"name": "PlannerScan._info.name",
|
||||
"help": "PlannerScan._info.help"
|
||||
},
|
||||
"ResultAdd": {
|
||||
"name": "PlannerScan.ResultAdd.name",
|
||||
"help": "PlannerScan.ResultAdd.help"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
"Aside": {
|
||||
"Install": "インストール",
|
||||
|
@ -61,6 +61,10 @@
|
||||
"Daemon": {
|
||||
"name": "剧情连点器",
|
||||
"help": ""
|
||||
},
|
||||
"PlannerScan": {
|
||||
"name": "角色养成规划",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Scheduler": {
|
||||
@ -351,81 +355,6 @@
|
||||
"9": "9"
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"_info": {
|
||||
"name": "每日任务设置",
|
||||
"help": "打一次特定的本,以满足每日任务的要求"
|
||||
},
|
||||
"CalyxGolden": {
|
||||
"name": "完成1次拟造花萼(金)",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成这个任务",
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "材料:角色经验(回忆之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "材料:角色经验(回忆之蕾•仙舟罗浮)",
|
||||
"Calyx_Golden_Memories_Penacony": "材料:角色经验(回忆之蕾•匹诺康尼)",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "材料:武器经验(以太之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "材料:武器经验(以太之蕾•仙舟罗浮)",
|
||||
"Calyx_Golden_Aether_Penacony": "材料:武器经验(以太之蕾•匹诺康尼)",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "材料:信用点(藏珍之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "材料:信用点(藏珍之蕾•仙舟罗浮)",
|
||||
"Calyx_Golden_Treasures_Penacony": "材料:信用点(藏珍之蕾•匹诺康尼)"
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"name": "完成1次拟造花萼(赤)",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成这个任务",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone": "行迹材料:毁灭(收容舱段)",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行迹材料:毁灭(鳞渊境)",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行迹材料:存护(支援舱段)",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行迹材料:存护(克劳克影视乐园)",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行迹材料:巡猎(城郊雪原)",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue": "行迹材料:巡猎(苏乐达热砂海选会场)",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行迹材料:丰饶(边缘通路)",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行迹材料:丰饶(绥园)",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行迹材料:智识(铆钉镇)",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行迹材料:同谐(机械聚落)",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行迹材料:同谐(白日梦酒店-梦境)",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine": "行迹材料:虚无(大矿区)",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission": "行迹材料:虚无(丹鼎司)"
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"name": "完成1次凝滞虚影",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成这个任务",
|
||||
"Stagnant_Shadow_Spike": "角色晋阶材料:物理(娜塔莎 / 克拉拉 / 卢卡 / 素裳)",
|
||||
"Stagnant_Shadow_Perdition": "角色晋阶材料:物理(寒鸦 / 银枝)",
|
||||
"Stagnant_Shadow_Duty": "角色晋阶材料:物理(波提欧 / 知更鸟)",
|
||||
"Stagnant_Shadow_Blaze": "角色晋阶材料:火(姬子 / 艾丝妲 / 虎克)",
|
||||
"Stagnant_Shadow_Scorch": "角色晋阶材料:火(桂乃芬 / 托帕&账账)",
|
||||
"Stagnant_Shadow_Ire": "角色晋阶材料:火(加拉赫)",
|
||||
"Stagnant_Shadow_Rime": "角色晋阶材料:冰(三月七 / 黑塔 / 杰帕德 / 佩拉)",
|
||||
"Stagnant_Shadow_Icicle": "角色晋阶材料:冰(彦卿 / 镜流 / 阮•梅)",
|
||||
"Stagnant_Shadow_Nectar": "角色晋阶材料:冰(米沙)",
|
||||
"Stagnant_Shadow_Fulmination": "角色晋阶材料:雷(阿兰 / 希露瓦 / 停云 / 白露)",
|
||||
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(卡芙卡 / 景元 / 黄泉)",
|
||||
"Stagnant_Shadow_Gust": "角色晋阶材料:风(丹恒 / 布洛妮娅 / 桑博)",
|
||||
"Stagnant_Shadow_Celestial": "角色晋阶材料:风(刃 / 藿藿 / 黑天鹅)",
|
||||
"Stagnant_Shadow_Quanta": "角色晋阶材料:量子(银狼 / 希儿 / 青雀)",
|
||||
"Stagnant_Shadow_Abomination": "角色晋阶材料:量子(玲可 / 符玄 / 雪衣)",
|
||||
"Stagnant_Shadow_Roast": "角色晋阶材料:量子(花火)",
|
||||
"Stagnant_Shadow_Mirage": "角色晋阶材料:虚数(瓦尔特 / 罗刹 / 驭空)",
|
||||
"Stagnant_Shadow_Puppetry": "角色晋阶材料:虚数(丹恒•饮月 / 砂金 / 真理医生)"
|
||||
},
|
||||
"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": "遗器:生命套+速度套(药使之径•侵蚀隧洞)",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness": "遗器:追击套+dot套(幽冥之径•侵蚀隧洞)",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive": "遗器:负面套+击破套(梦潜之径•侵蚀隧洞)"
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"_info": {
|
||||
"name": "支援设置",
|
||||
@ -529,6 +458,212 @@
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"_info": {
|
||||
"name": "养成规划进度",
|
||||
"help": "优先执行养成规划,养成规划完成后,执行 \"每日副本设置\""
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "信用点",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "里程",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "角色经验",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "武器经验",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "遗失晶块",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "角色晋阶材料:物理(娜塔莎 / 克拉拉 / 卢卡 / 素裳)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "角色晋阶材料:火(姬子 / 艾丝妲 / 虎克)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "角色晋阶材料:冰(三月七 / 黑塔 / 杰帕德 / 佩拉)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "角色晋阶材料:雷(阿兰 / 希露瓦 / 停云 / 白露)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "角色晋阶材料:风(丹恒 / 布洛妮娅 / 桑博)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "角色晋阶材料:量子(银狼 / 希儿 / 青雀)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "角色晋阶材料:虚数(瓦尔特 / 罗刹 / 驭空)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "角色晋阶材料:物理(寒鸦 / 银枝)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "角色晋阶材料:火(桂乃芬 / 托帕&账账)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "角色晋阶材料:冰(彦卿 / 镜流 / 阮•梅)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "角色晋阶材料:雷(卡芙卡 / 景元 / 黄泉)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "角色晋阶材料:风(刃 / 藿藿 / 黑天鹅)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "角色晋阶材料:量子(玲可 / 符玄 / 雪衣)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "角色晋阶材料:虚数(丹恒•饮月 / 砂金 / 真理医生)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "角色晋阶材料:物理(波提欧 / 知更鸟)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "角色晋阶材料:火(加拉赫)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "角色晋阶材料:冰(米沙)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "角色晋阶材料:量子(花火)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "行迹材料:毁灭(收容舱段)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "行迹材料:巡猎(城郊雪原)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "行迹材料:智识(铆钉镇)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "行迹材料:存护(支援舱段)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "行迹材料:虚无(大矿区)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "行迹材料:同谐(机械聚落)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "行迹材料:丰饶(边缘通路)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "行迹材料:毁灭(鳞渊境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "行迹材料:巡猎(苏乐达热砂海选会场)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "行迹材料:存护(克劳克影视乐园)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "行迹材料:虚无(丹鼎司)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "行迹材料:同谐(白日梦酒店-梦境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "行迹材料:丰饶(绥园)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "命运的足迹",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "毁灭的开端•历战余响 (空间站「黑塔」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "寒潮的落幕•历战余响 (雅利洛-Ⅵ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "不死的神实•历战余响 (仙舟「罗浮」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "蛀星的旧靥•历战余响 (空间站「黑塔」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "尘梦的赞礼•历战余响 (匹诺康尼)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "蠢动原核",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "践踏的意志",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "铁卫勋章",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "古代引擎",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "永寿荣枝",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "工造浑心",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "造梦马达",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "欲念碎镜",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Weekly": {
|
||||
"_info": {
|
||||
"name": "历战余响设置",
|
||||
@ -1063,6 +1198,16 @@
|
||||
"do_not_click": "不点击"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"_info": {
|
||||
"name": "识别角色养成规划计算结果",
|
||||
"help": "工具需要停止调度器再单独运行\n使用前需要在游戏内养成计算器中设定养成目标,并计算出结果,在计算结果页面启动养成规划识别。详细使用教程见:\nhttps://github.com/LmeSzinc/StarRailCopilot/wiki/Planner_cn"
|
||||
},
|
||||
"ResultAdd": {
|
||||
"name": "累加多次扫描结果",
|
||||
"help": "需要养成多个角色时勾选,同时养成多个角色\n仅养成一个角色不勾选,每次扫描时刷新养成目标"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
"Aside": {
|
||||
"Install": "安装",
|
||||
|
@ -61,6 +61,10 @@
|
||||
"Daemon": {
|
||||
"name": "劇情連點器",
|
||||
"help": ""
|
||||
},
|
||||
"PlannerScan": {
|
||||
"name": "角色養成規劃",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Scheduler": {
|
||||
@ -351,81 +355,6 @@
|
||||
"9": "9"
|
||||
}
|
||||
},
|
||||
"DungeonDaily": {
|
||||
"_info": {
|
||||
"name": "每日任務設定",
|
||||
"help": "打一次特定的本,以滿足每日任務的要求"
|
||||
},
|
||||
"CalyxGolden": {
|
||||
"name": "完成1次擬造花萼(金)",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成這個任務",
|
||||
"Calyx_Golden_Memories_Jarilo_VI": "材料:角色經驗(回憶之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "材料:角色經驗(回憶之蕾•仙舟羅浮)",
|
||||
"Calyx_Golden_Memories_Penacony": "材料:角色經驗(回憶之蕾•匹諾康尼)",
|
||||
"Calyx_Golden_Aether_Jarilo_VI": "材料:武器經驗(乙太之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Aether_The_Xianzhou_Luofu": "材料:武器經驗(乙太之蕾•仙舟羅浮)",
|
||||
"Calyx_Golden_Aether_Penacony": "材料:武器經驗(乙太之蕾•匹諾康尼)",
|
||||
"Calyx_Golden_Treasures_Jarilo_VI": "材料:信用點(藏珍之蕾•雅利洛-Ⅵ)",
|
||||
"Calyx_Golden_Treasures_The_Xianzhou_Luofu": "材料:信用點(藏珍之蕾•仙舟羅浮)",
|
||||
"Calyx_Golden_Treasures_Penacony": "材料:信用點(藏珍之蕾•匹諾康尼)"
|
||||
},
|
||||
"CalyxCrimson": {
|
||||
"name": "完成1次擬造花萼(赤)",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成這個任務",
|
||||
"Calyx_Crimson_Destruction_Herta_StorageZone": "行跡材料:毀滅(收容艙段)",
|
||||
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行跡材料:毀滅(鱗淵境)",
|
||||
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行跡材料:存護(支援艙段)",
|
||||
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行跡材料:存護(克勞克影視樂園)",
|
||||
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行跡材料:巡獵(城郊雪原)",
|
||||
"Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue": "行跡材料:巡獵(蘇樂達熱砂海選會場)",
|
||||
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行跡材料:豐饒(邊緣通道)",
|
||||
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行跡材料:豐饒(綏園)",
|
||||
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行跡材料:智識(鉚釘鎮)",
|
||||
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行跡材料:同諧(機械聚落)",
|
||||
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行跡材料:同諧(白日夢飯店-夢境)",
|
||||
"Calyx_Crimson_Nihility_Jarilo_GreatMine": "行跡材料:虛無(大礦區)",
|
||||
"Calyx_Crimson_Nihility_Luofu_AlchemyCommission": "行跡材料:虛無(丹鼎司)"
|
||||
},
|
||||
"StagnantShadow": {
|
||||
"name": "完成1次凝滯虛影",
|
||||
"help": "",
|
||||
"do_not_achieve": "不完成這個任務",
|
||||
"Stagnant_Shadow_Spike": "角色晉階材料:物理(娜塔莎 / 克拉拉 / 盧卡 / 素裳)",
|
||||
"Stagnant_Shadow_Perdition": "角色晉階材料:物理(寒鴉 / 銀枝)",
|
||||
"Stagnant_Shadow_Duty": "角色晉階材料:物理(波提歐 / 知更鳥)",
|
||||
"Stagnant_Shadow_Blaze": "角色晉階材料:火(姬子 / 艾絲妲 / 虎克)",
|
||||
"Stagnant_Shadow_Scorch": "角色晉階材料:火(桂乃芬 / 托帕&帳帳)",
|
||||
"Stagnant_Shadow_Ire": "角色晉階材料:火(加拉赫)",
|
||||
"Stagnant_Shadow_Rime": "角色晉階材料:冰(三月七 / 黑塔 / 傑帕德 / 佩拉)",
|
||||
"Stagnant_Shadow_Icicle": "角色晉階材料:冰(彥卿 / 鏡流 / 阮•梅)",
|
||||
"Stagnant_Shadow_Nectar": "角色晉階材料:冰(米沙)",
|
||||
"Stagnant_Shadow_Fulmination": "角色晉階材料:雷(阿蘭 / 希露瓦 / 停雲 / 白露)",
|
||||
"Stagnant_Shadow_Doom": "角色晉階材料:雷(卡芙卡 / 景元 / 黃泉)",
|
||||
"Stagnant_Shadow_Gust": "角色晉階材料:風(丹恆 / 布洛妮婭 / 桑博)",
|
||||
"Stagnant_Shadow_Celestial": "角色晉階材料:風(刃 / 藿藿 / 黑天鵝)",
|
||||
"Stagnant_Shadow_Quanta": "角色晉階材料:量子(銀狼 / 希兒 / 青雀)",
|
||||
"Stagnant_Shadow_Abomination": "角色晉階材料:量子(玲可 / 符玄 / 雪衣)",
|
||||
"Stagnant_Shadow_Roast": "角色晉階材料:量子(花火)",
|
||||
"Stagnant_Shadow_Mirage": "角色晉階材料:虛數(瓦爾特 / 羅剎 / 馭空)",
|
||||
"Stagnant_Shadow_Puppetry": "角色晉階材料:虛數(丹恆•飲月 / 砂金 / 真理醫生)"
|
||||
},
|
||||
"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": "遺器:生命套+速度套(藥使之徑•侵蝕隧洞)",
|
||||
"Cavern_of_Corrosion_Path_of_Darkness": "遺器:追擊套+dot套(幽冥之徑•侵蝕隧洞)",
|
||||
"Cavern_of_Corrosion_Path_of_Dreamdive": "遺器:負面套+擊破套(夢潛之徑•侵蝕隧洞)"
|
||||
}
|
||||
},
|
||||
"DungeonSupport": {
|
||||
"_info": {
|
||||
"name": "支援設定",
|
||||
@ -529,6 +458,212 @@
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Planner": {
|
||||
"_info": {
|
||||
"name": "養成規劃進度",
|
||||
"help": "優先執行養成規劃,養成規劃完成後,執行 \"每日副本設定\""
|
||||
},
|
||||
"Item_Credit": {
|
||||
"name": "信用點",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Trailblaze_EXP": {
|
||||
"name": "里程",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Traveler_Guide": {
|
||||
"name": "角色經驗",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Refined_Aether": {
|
||||
"name": "武器經驗",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Crystal": {
|
||||
"name": "遺失晶塊",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Broken_Teeth_of_Iron_Wolf": {
|
||||
"name": "角色晉階材料:物理(娜塔莎 / 克拉拉 / 盧卡 / 素裳)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Endotherm_Chitin": {
|
||||
"name": "角色晉階材料:火(姬子 / 艾絲妲 / 虎克)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Horn_of_Snow": {
|
||||
"name": "角色晉階材料:冰(三月七 / 黑塔 / 傑帕德 / 佩拉)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lightning_Crown_of_the_Past_Shadow": {
|
||||
"name": "角色晉階材料:雷(阿蘭 / 希露瓦 / 停雲 / 白露)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Storm_Eye": {
|
||||
"name": "角色晉階材料:風(丹恆 / 布洛妮婭 / 桑博)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Void_Cast_Iron": {
|
||||
"name": "角色晉階材料:量子(銀狼 / 希兒 / 青雀)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Golden_Crown_of_the_Past_Shadow": {
|
||||
"name": "角色晉階材料:虛數(瓦爾特 / 羅剎 / 馭空)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Netherworld_Token": {
|
||||
"name": "角色晉階材料:物理(寒鴉 / 銀枝)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Searing_Steel_Blade": {
|
||||
"name": "角色晉階材料:火(桂乃芬 / 托帕&帳帳)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Gelid_Chitin": {
|
||||
"name": "角色晉階材料:冰(彥卿 / 鏡流 / 阮•梅)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shape_Shifter_Lightning_Staff": {
|
||||
"name": "角色晉階材料:雷(卡芙卡 / 景元 / 黃泉)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ascendant_Debris": {
|
||||
"name": "角色晉階材料:風(刃 / 藿藿 / 黑天鵝)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Nail_of_the_Ape": {
|
||||
"name": "角色晉階材料:量子(玲可 / 符玄 / 雪衣)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Suppressing_Edict": {
|
||||
"name": "角色晉階材料:虛數(丹恆•飲月 / 砂金 / 真理醫生)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_IPC_Work_Permit": {
|
||||
"name": "角色晉階材料:物理(波提歐 / 知更鳥)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Raging_Heart": {
|
||||
"name": "角色晉階材料:火(加拉赫)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Fridge": {
|
||||
"name": "角色晉階材料:冰(米沙)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Flamer": {
|
||||
"name": "角色晉階材料:量子(花火)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Worldbreaker_Blade": {
|
||||
"name": "行跡材料:毀滅(收容艙段)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Arrow_of_the_Starchaser": {
|
||||
"name": "行跡材料:巡獵(城郊雪原)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Key_of_Wisdom": {
|
||||
"name": "行跡材料:智識(鉚釘鎮)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Safeguard_of_Amber": {
|
||||
"name": "行跡材料:存護(支援艙段)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Obsidian_of_Obsession": {
|
||||
"name": "行跡材料:虛無(大礦區)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Stellaris_Symphony": {
|
||||
"name": "行跡材料:同諧(機械聚落)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Flower_of_Eternity": {
|
||||
"name": "行跡材料:豐饒(邊緣通道)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Moon_Madness_Fang": {
|
||||
"name": "行跡材料:毀滅(鱗淵境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Countertemporal_Shot": {
|
||||
"name": "行跡材料:巡獵(蘇樂達熱砂海選會場)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Divine_Amber": {
|
||||
"name": "行跡材料:存護(克勞克影視樂園)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heaven_Incinerator": {
|
||||
"name": "行跡材料:虛無(丹鼎司)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Heavenly_Melody": {
|
||||
"name": "行跡材料:同諧(白日夢飯店-夢境)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Myriad_Fruit": {
|
||||
"name": "行跡材料:豐饒(綏園)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Tracks_of_Destiny": {
|
||||
"name": "命運的足跡",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Destroyer_Final_Road": {
|
||||
"name": "毀滅的開端•歷戰餘響 (太空站「黑塔」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Guardian_Lament": {
|
||||
"name": "寒潮的落幕•歷戰餘響 (雅利洛-Ⅵ)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Regret_of_Infinite_Ochema": {
|
||||
"name": "不死的神實•歷戰餘響 (仙舟「羅浮」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Past_Evils_of_the_Borehole_Planet_Disaster": {
|
||||
"name": "蛀星的舊靨•歷戰餘響 (太空站「黑塔」)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Lost_Echo_of_the_Shared_Wish": {
|
||||
"name": "塵夢的讚禮•歷戰餘響 (匹諾康尼)",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Squirming_Core": {
|
||||
"name": "蠢動原核",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Conqueror_Will": {
|
||||
"name": "踐踏的意志",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Silvermane_Medal": {
|
||||
"name": "鐵衛勳章",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Ancient_Engine": {
|
||||
"name": "古代引擎",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Immortal_Lumintwig": {
|
||||
"name": "永壽榮枝",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Artifex_Gyreheart": {
|
||||
"name": "工造渾心",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Dream_Making_Engine": {
|
||||
"name": "造夢馬達",
|
||||
"help": ""
|
||||
},
|
||||
"Item_Shards_of_Desires": {
|
||||
"name": "欲念碎鏡",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Weekly": {
|
||||
"_info": {
|
||||
"name": "歷戰餘響設定",
|
||||
@ -1063,6 +1198,16 @@
|
||||
"do_not_click": "不點擊"
|
||||
}
|
||||
},
|
||||
"PlannerScan": {
|
||||
"_info": {
|
||||
"name": "辨識角色養成規劃計算結果",
|
||||
"help": "工具需要停止調度器再單獨運行\n使用前需要在遊戲內養成計算器中設定養成目標,併計算出結果,在計算結果頁面啟動養成規劃識別。詳細使用教程 請參閱:\nhttps://github.com/LmeSzinc/StarRailCopilot/wiki/Planner_cn"
|
||||
},
|
||||
"ResultAdd": {
|
||||
"name": "累加多次掃描結果",
|
||||
"help": "需要養成多個角色時勾選,同時養成多個角色\n只養成一個角色不勾選,每次掃描時刷新養成目標"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
"Aside": {
|
||||
"Install": "安裝",
|
||||
|
@ -398,3 +398,9 @@ class StoredBattlePassQuestCavernOfCorrosion(StoredCounter):
|
||||
class StoredBattlePassQuestTrailblazePower(StoredCounter):
|
||||
# Dynamic total from 100 to 1400
|
||||
LIST_TOTAL = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400]
|
||||
|
||||
|
||||
class StoredPlanner(StoredBase):
|
||||
value: int
|
||||
total: int
|
||||
synthesize: int
|
||||
|
@ -19,6 +19,7 @@ from module.config.stored.classes import (
|
||||
StoredExpiredAtMonday0400,
|
||||
StoredImmersifier,
|
||||
StoredInt,
|
||||
StoredPlanner,
|
||||
StoredSimulatedUniverse,
|
||||
StoredSimulatedUniverseElite,
|
||||
StoredTrailblazePower,
|
||||
@ -32,6 +33,56 @@ class StoredGenerated:
|
||||
CloudRemainSeasonPass = StoredInt("Alas.CloudStorage.CloudRemainSeasonPass")
|
||||
CloudRemainPaid = StoredInt("Alas.CloudStorage.CloudRemainPaid")
|
||||
CloudRemainFree = StoredInt("Alas.CloudStorage.CloudRemainFree")
|
||||
Item_Credit = StoredPlanner("Dungeon.Planner.Item_Credit")
|
||||
Item_Trailblaze_EXP = StoredPlanner("Dungeon.Planner.Item_Trailblaze_EXP")
|
||||
Item_Traveler_Guide = StoredPlanner("Dungeon.Planner.Item_Traveler_Guide")
|
||||
Item_Refined_Aether = StoredPlanner("Dungeon.Planner.Item_Refined_Aether")
|
||||
Item_Lost_Crystal = StoredPlanner("Dungeon.Planner.Item_Lost_Crystal")
|
||||
Item_Broken_Teeth_of_Iron_Wolf = StoredPlanner("Dungeon.Planner.Item_Broken_Teeth_of_Iron_Wolf")
|
||||
Item_Endotherm_Chitin = StoredPlanner("Dungeon.Planner.Item_Endotherm_Chitin")
|
||||
Item_Horn_of_Snow = StoredPlanner("Dungeon.Planner.Item_Horn_of_Snow")
|
||||
Item_Lightning_Crown_of_the_Past_Shadow = StoredPlanner("Dungeon.Planner.Item_Lightning_Crown_of_the_Past_Shadow")
|
||||
Item_Storm_Eye = StoredPlanner("Dungeon.Planner.Item_Storm_Eye")
|
||||
Item_Void_Cast_Iron = StoredPlanner("Dungeon.Planner.Item_Void_Cast_Iron")
|
||||
Item_Golden_Crown_of_the_Past_Shadow = StoredPlanner("Dungeon.Planner.Item_Golden_Crown_of_the_Past_Shadow")
|
||||
Item_Netherworld_Token = StoredPlanner("Dungeon.Planner.Item_Netherworld_Token")
|
||||
Item_Searing_Steel_Blade = StoredPlanner("Dungeon.Planner.Item_Searing_Steel_Blade")
|
||||
Item_Gelid_Chitin = StoredPlanner("Dungeon.Planner.Item_Gelid_Chitin")
|
||||
Item_Shape_Shifter_Lightning_Staff = StoredPlanner("Dungeon.Planner.Item_Shape_Shifter_Lightning_Staff")
|
||||
Item_Ascendant_Debris = StoredPlanner("Dungeon.Planner.Item_Ascendant_Debris")
|
||||
Item_Nail_of_the_Ape = StoredPlanner("Dungeon.Planner.Item_Nail_of_the_Ape")
|
||||
Item_Suppressing_Edict = StoredPlanner("Dungeon.Planner.Item_Suppressing_Edict")
|
||||
Item_IPC_Work_Permit = StoredPlanner("Dungeon.Planner.Item_IPC_Work_Permit")
|
||||
Item_Raging_Heart = StoredPlanner("Dungeon.Planner.Item_Raging_Heart")
|
||||
Item_Dream_Fridge = StoredPlanner("Dungeon.Planner.Item_Dream_Fridge")
|
||||
Item_Dream_Flamer = StoredPlanner("Dungeon.Planner.Item_Dream_Flamer")
|
||||
Item_Worldbreaker_Blade = StoredPlanner("Dungeon.Planner.Item_Worldbreaker_Blade")
|
||||
Item_Arrow_of_the_Starchaser = StoredPlanner("Dungeon.Planner.Item_Arrow_of_the_Starchaser")
|
||||
Item_Key_of_Wisdom = StoredPlanner("Dungeon.Planner.Item_Key_of_Wisdom")
|
||||
Item_Safeguard_of_Amber = StoredPlanner("Dungeon.Planner.Item_Safeguard_of_Amber")
|
||||
Item_Obsidian_of_Obsession = StoredPlanner("Dungeon.Planner.Item_Obsidian_of_Obsession")
|
||||
Item_Stellaris_Symphony = StoredPlanner("Dungeon.Planner.Item_Stellaris_Symphony")
|
||||
Item_Flower_of_Eternity = StoredPlanner("Dungeon.Planner.Item_Flower_of_Eternity")
|
||||
Item_Moon_Madness_Fang = StoredPlanner("Dungeon.Planner.Item_Moon_Madness_Fang")
|
||||
Item_Countertemporal_Shot = StoredPlanner("Dungeon.Planner.Item_Countertemporal_Shot")
|
||||
Item_Divine_Amber = StoredPlanner("Dungeon.Planner.Item_Divine_Amber")
|
||||
Item_Heaven_Incinerator = StoredPlanner("Dungeon.Planner.Item_Heaven_Incinerator")
|
||||
Item_Heavenly_Melody = StoredPlanner("Dungeon.Planner.Item_Heavenly_Melody")
|
||||
Item_Myriad_Fruit = StoredPlanner("Dungeon.Planner.Item_Myriad_Fruit")
|
||||
Item_Tracks_of_Destiny = StoredPlanner("Dungeon.Planner.Item_Tracks_of_Destiny")
|
||||
Item_Destroyer_Final_Road = StoredPlanner("Dungeon.Planner.Item_Destroyer_Final_Road")
|
||||
Item_Guardian_Lament = StoredPlanner("Dungeon.Planner.Item_Guardian_Lament")
|
||||
Item_Regret_of_Infinite_Ochema = StoredPlanner("Dungeon.Planner.Item_Regret_of_Infinite_Ochema")
|
||||
Item_Past_Evils_of_the_Borehole_Planet_Disaster = StoredPlanner("Dungeon.Planner.Item_Past_Evils_of_the_Borehole_Planet_Disaster")
|
||||
Item_Lost_Echo_of_the_Shared_Wish = StoredPlanner("Dungeon.Planner.Item_Lost_Echo_of_the_Shared_Wish")
|
||||
Item_Squirming_Core = StoredPlanner("Dungeon.Planner.Item_Squirming_Core")
|
||||
Item_Conqueror_Will = StoredPlanner("Dungeon.Planner.Item_Conqueror_Will")
|
||||
Item_Silvermane_Medal = StoredPlanner("Dungeon.Planner.Item_Silvermane_Medal")
|
||||
Item_Ancient_Engine = StoredPlanner("Dungeon.Planner.Item_Ancient_Engine")
|
||||
Item_Immortal_Lumintwig = StoredPlanner("Dungeon.Planner.Item_Immortal_Lumintwig")
|
||||
Item_Artifex_Gyreheart = StoredPlanner("Dungeon.Planner.Item_Artifex_Gyreheart")
|
||||
Item_Dream_Making_Engine = StoredPlanner("Dungeon.Planner.Item_Dream_Making_Engine")
|
||||
Item_Shards_of_Desires = StoredPlanner("Dungeon.Planner.Item_Shards_of_Desires")
|
||||
TrailblazePower = StoredTrailblazePower("Dungeon.DungeonStorage.TrailblazePower")
|
||||
Immersifier = StoredImmersifier("Dungeon.DungeonStorage.Immersifier")
|
||||
DungeonDouble = StoredDungeonDouble("Dungeon.DungeonStorage.DungeonDouble")
|
||||
|
@ -1,15 +1,13 @@
|
||||
import re
|
||||
import time
|
||||
from datetime import timedelta
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from pponnxcr.predict_system import BoxedResult
|
||||
|
||||
import module.config.server as server
|
||||
from module.base.button import ButtonWrapper
|
||||
from module.base.decorator import cached_property
|
||||
from module.base.utils import area_pad, corner2area, crop, extract_white_letters, float2str
|
||||
from module.base.utils import *
|
||||
from module.exception import ScriptError
|
||||
from module.logger import logger
|
||||
from module.ocr.models import OCR_MODEL, TextSystem
|
||||
@ -325,7 +323,7 @@ class Ocr:
|
||||
|
||||
|
||||
class Digit(Ocr):
|
||||
def __init__(self, button: ButtonWrapper, lang='en', name=None):
|
||||
def __init__(self, button: ButtonWrapper, lang=None, name=None):
|
||||
super().__init__(button, lang=lang, name=name)
|
||||
|
||||
def format_result(self, result) -> int:
|
||||
@ -345,7 +343,7 @@ class Digit(Ocr):
|
||||
|
||||
|
||||
class DigitCounter(Ocr):
|
||||
def __init__(self, button: ButtonWrapper, lang='en', name=None):
|
||||
def __init__(self, button: ButtonWrapper, lang=None, name=None):
|
||||
super().__init__(button, lang=lang, name=name)
|
||||
|
||||
@classmethod
|
||||
@ -423,6 +421,12 @@ class Duration(Ocr):
|
||||
|
||||
class OcrWhiteLetterOnComplexBackground(Ocr):
|
||||
white_preprocess = True
|
||||
# 0.6 by default, 0.2 for lower
|
||||
box_thresh = 0.2
|
||||
# (x, y) Enlarge detected boxes to `min_boxes`
|
||||
# So standalone digits can be better detected
|
||||
# Note that min_box should be 4px larger than the actual letter
|
||||
min_box = None
|
||||
|
||||
def pre_process(self, image):
|
||||
if self.white_preprocess:
|
||||
@ -430,12 +434,46 @@ class OcrWhiteLetterOnComplexBackground(Ocr):
|
||||
image = cv2.merge([image, image, image])
|
||||
return image
|
||||
|
||||
@staticmethod
|
||||
def enlarge_box(box, min_box):
|
||||
area = corner2area(box)
|
||||
center = (int(x) for x in area_center(area))
|
||||
size_x, size_y = area_size(area)
|
||||
min_x, min_y = min_box
|
||||
if size_x < min_x or size_y < min_y:
|
||||
size_x = max(size_x, min_x) // 2
|
||||
size_y = max(size_y, min_y) // 2
|
||||
area = area_offset((-size_x, -size_y, size_x, size_y), center)
|
||||
box = area2corner(area)
|
||||
box = np.array([box[0], box[1], box[3], box[2]]).astype(np.float32)
|
||||
return box
|
||||
else:
|
||||
return box
|
||||
|
||||
def enlarge_boxes(self, boxes):
|
||||
if self.min_box is None:
|
||||
return boxes
|
||||
|
||||
boxes = [self.enlarge_box(box, self.min_box) for box in boxes]
|
||||
boxes = np.array(boxes)
|
||||
return boxes
|
||||
|
||||
def detect_and_ocr(self, *args, **kwargs):
|
||||
# Try hard to lower TextSystem.box_thresh
|
||||
backup = self.model.text_detector.box_thresh
|
||||
self.model.text_detector.box_thresh = 0.2
|
||||
# Patch TextDetector
|
||||
text_detector = self.model.text_detector
|
||||
|
||||
result = super().detect_and_ocr(*args, **kwargs)
|
||||
def text_detector_with_min_box(*args, **kwargs):
|
||||
dt_boxes, elapse = text_detector(*args, **kwargs)
|
||||
dt_boxes = self.enlarge_boxes(dt_boxes)
|
||||
return dt_boxes, elapse
|
||||
|
||||
self.model.text_detector.box_thresh = backup
|
||||
self.model.text_detector = text_detector_with_min_box
|
||||
try:
|
||||
result = super().detect_and_ocr(*args, **kwargs)
|
||||
finally:
|
||||
self.model.text_detector.box_thresh = backup
|
||||
self.model.text_detector = text_detector
|
||||
return result
|
||||
|
@ -218,7 +218,7 @@ class AdaptiveScroll(Scroll):
|
||||
"""
|
||||
Args:
|
||||
area (Button, tuple): A button or area of the whole scroll.
|
||||
prominence (dict): Parameters passing to scipy.find_peaks
|
||||
parameters (dict): Parameters passing to scipy.find_peaks
|
||||
background (int):
|
||||
is_vertical (bool): True if vertical, false if horizontal.
|
||||
name (str):
|
||||
|
@ -151,6 +151,10 @@ class ProcessManager:
|
||||
from tasks.base.daemon import Daemon
|
||||
|
||||
Daemon(config=config_name, task="Daemon").run()
|
||||
elif func == "PlannerScan":
|
||||
from tasks.planner.scan import PlannerScan
|
||||
|
||||
PlannerScan(config=config_name, task="PlannerScan").run()
|
||||
else:
|
||||
logger.critical(f"No function matched: {func}")
|
||||
logger.info(f"[{config_name}] exited. Reason: Finish\n")
|
||||
|
@ -340,7 +340,7 @@ def product_stored_row(key, value):
|
||||
|
||||
def put_arg_stored(kwargs: T_Output_Kwargs) -> Output:
|
||||
name: str = kwargs["name"]
|
||||
kwargs["disabled"] = True
|
||||
# kwargs["disabled"] = True
|
||||
|
||||
values = kwargs.pop("value", {})
|
||||
value = values.pop("value", "")
|
||||
@ -348,22 +348,26 @@ def put_arg_stored(kwargs: T_Output_Kwargs) -> Output:
|
||||
time_ = values.pop("time", "")
|
||||
|
||||
if value != "" and total != "":
|
||||
# 0 / 100
|
||||
rows = [put_scope(f"dashboard-value-{name}", [
|
||||
put_text(value).style("--dashboard-value--"),
|
||||
put_text(f" / {total}").style("--dashboard-time--"),
|
||||
])]
|
||||
elif value != "":
|
||||
# 100
|
||||
rows = [put_scope(f"dashboard-value-{name}", [
|
||||
put_text(value).style("--dashboard-value--")
|
||||
])]
|
||||
else:
|
||||
# Empty
|
||||
rows = []
|
||||
# Add other key-value in stored
|
||||
if values:
|
||||
rows += [
|
||||
put_scope(f"dashboard-value-{name}-{key}", product_stored_row(key, value))
|
||||
for key, value in values.items() if value != ""
|
||||
]
|
||||
|
||||
# Add time
|
||||
if time_:
|
||||
rows.append(
|
||||
put_text(time_).style("--dashboard-time--")
|
||||
@ -380,6 +384,36 @@ def put_arg_stored(kwargs: T_Output_Kwargs) -> Output:
|
||||
]
|
||||
)
|
||||
|
||||
def put_arg_planner(kwargs: T_Output_Kwargs) -> Output | None:
|
||||
name: str = kwargs["name"]
|
||||
|
||||
values = kwargs.pop("value", {})
|
||||
try:
|
||||
progress = values["progress"]
|
||||
except KeyError:
|
||||
# Hide items not needed by the planner
|
||||
return None
|
||||
|
||||
value = values.pop('value', 0)
|
||||
if isinstance(value, dict):
|
||||
value = tuple(value.values())
|
||||
total = values.pop('total', 0)
|
||||
if isinstance(total, dict):
|
||||
total = tuple(total.values())
|
||||
|
||||
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||
put_text(f"{progress:.2f}%").style("--dashboard-bold--"),
|
||||
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||
])
|
||||
|
||||
return put_scope(
|
||||
f"arg_container-planner-{name}",
|
||||
[
|
||||
get_title_help(kwargs),
|
||||
row,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def put_arg_select(kwargs: T_Output_Kwargs) -> Output:
|
||||
name: str = kwargs["name"]
|
||||
@ -528,6 +562,7 @@ _widget_type_to_func: Dict[str, Callable] = {
|
||||
"storage": put_arg_storage,
|
||||
"state": put_arg_state,
|
||||
"stored": put_arg_stored,
|
||||
"planner": put_arg_planner,
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from module.config.stored.classes import now
|
||||
from module.config.utils import get_server_next_update
|
||||
from module.logger import logger
|
||||
from tasks.assignment.claim import AssignmentClaim
|
||||
from tasks.assignment.keywords import (KEYWORDS_ASSIGNMENT_GROUP,
|
||||
@ -76,6 +78,12 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
||||
# ValueError: min() arg is an empty sequence
|
||||
logger.error('Empty dispatched list, delay 2 hours instead')
|
||||
self.config.task_delay(minute=120)
|
||||
# Check future daily
|
||||
if now() > get_server_next_update(self.config.Scheduler_ServerUpdate) - timedelta(minutes=110) \
|
||||
and KEYWORDS_DAILY_QUEST.Dispatch_1_assignments in quests:
|
||||
logger.error(
|
||||
"Assigment is scheduled tomorrow but today's assignment daily haven't been finished yet")
|
||||
self.config.task_call('DailyQuest')
|
||||
|
||||
def _check_inlist(self, assignments: list[AssignmentEntry], duration: int):
|
||||
"""
|
||||
|
102
tasks/combat/assets/assets_combat_obtain.py
Normal file
@ -0,0 +1,102 @@
|
||||
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 ```
|
||||
|
||||
ITEM_AMOUNT = ButtonWrapper(
|
||||
name='ITEM_AMOUNT',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/ITEM_AMOUNT.png',
|
||||
area=(190, 521, 490, 539),
|
||||
search=(170, 501, 510, 559),
|
||||
color=(195, 190, 188),
|
||||
button=(190, 521, 490, 539),
|
||||
),
|
||||
)
|
||||
ITEM_CLOSE = ButtonWrapper(
|
||||
name='ITEM_CLOSE',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/ITEM_CLOSE.png',
|
||||
area=(1043, 185, 1073, 215),
|
||||
search=(1023, 165, 1093, 235),
|
||||
color=(170, 170, 170),
|
||||
button=(1043, 185, 1073, 215),
|
||||
),
|
||||
)
|
||||
ITEM_NAME = ButtonWrapper(
|
||||
name='ITEM_NAME',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/ITEM_NAME.png',
|
||||
area=(495, 187, 855, 211),
|
||||
search=(475, 167, 875, 231),
|
||||
color=(176, 177, 179),
|
||||
button=(495, 187, 855, 211),
|
||||
),
|
||||
)
|
||||
MAY_OBTAIN = ButtonWrapper(
|
||||
name='MAY_OBTAIN',
|
||||
cn=Button(
|
||||
file='./assets/cn/combat/obtain/MAY_OBTAIN.png',
|
||||
area=(813, 379, 893, 397),
|
||||
search=(812, 373, 895, 468),
|
||||
color=(63, 71, 87),
|
||||
button=(813, 379, 893, 397),
|
||||
),
|
||||
en=Button(
|
||||
file='./assets/en/combat/obtain/MAY_OBTAIN.png',
|
||||
area=(813, 379, 922, 397),
|
||||
search=(813, 373, 923, 468),
|
||||
color=(53, 61, 78),
|
||||
button=(813, 379, 922, 397),
|
||||
),
|
||||
)
|
||||
OBTAIN_1 = ButtonWrapper(
|
||||
name='OBTAIN_1',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/OBTAIN_1.png',
|
||||
area=(813, 414, 877, 478),
|
||||
search=(793, 394, 897, 498),
|
||||
color=(118, 96, 131),
|
||||
button=(813, 414, 877, 478),
|
||||
),
|
||||
)
|
||||
OBTAIN_2 = ButtonWrapper(
|
||||
name='OBTAIN_2',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/OBTAIN_2.png',
|
||||
area=(889, 414, 953, 478),
|
||||
search=(869, 394, 973, 498),
|
||||
color=(71, 96, 145),
|
||||
button=(889, 414, 953, 478),
|
||||
),
|
||||
)
|
||||
OBTAIN_3 = ButtonWrapper(
|
||||
name='OBTAIN_3',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/OBTAIN_3.png',
|
||||
area=(965, 414, 1029, 478),
|
||||
search=(945, 394, 1049, 498),
|
||||
color=(76, 101, 109),
|
||||
button=(965, 414, 1029, 478),
|
||||
),
|
||||
)
|
||||
OBTAIN_4 = ButtonWrapper(
|
||||
name='OBTAIN_4',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/OBTAIN_4.png',
|
||||
area=(1041, 414, 1105, 478),
|
||||
search=(1021, 394, 1125, 498),
|
||||
color=(76, 101, 109),
|
||||
button=(1041, 414, 1105, 478),
|
||||
),
|
||||
)
|
||||
OBTAIN_TRAILBLAZE_EXP = ButtonWrapper(
|
||||
name='OBTAIN_TRAILBLAZE_EXP',
|
||||
share=Button(
|
||||
file='./assets/share/combat/obtain/OBTAIN_TRAILBLAZE_EXP.png',
|
||||
area=(827, 425, 860, 451),
|
||||
search=(813, 349, 877, 589),
|
||||
color=(167, 173, 194),
|
||||
button=(827, 425, 860, 451),
|
||||
),
|
||||
)
|
@ -5,15 +5,20 @@ 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
|
||||
from tasks.combat.interact import CombatInteract
|
||||
from tasks.combat.obtain import CombatObtain
|
||||
from tasks.combat.prepare import CombatPrepare
|
||||
from tasks.combat.skill import CombatSkill
|
||||
from tasks.combat.state import CombatState
|
||||
from tasks.combat.support import CombatSupport
|
||||
from tasks.combat.team import CombatTeam
|
||||
from tasks.dungeon.keywords import DungeonList
|
||||
from tasks.map.control.joystick import MapControlJoystick
|
||||
|
||||
|
||||
class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, MapControlJoystick):
|
||||
class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, CombatObtain,
|
||||
MapControlJoystick):
|
||||
dungeon: DungeonList | None = None
|
||||
|
||||
def handle_combat_prepare(self):
|
||||
"""
|
||||
Returns:
|
||||
@ -120,6 +125,10 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
||||
self.interval_reset(COMBAT_PREPARE)
|
||||
self.map_A_timer.reset()
|
||||
if self.appear(COMBAT_PREPARE, interval=2):
|
||||
if self.obtained_is_full(self.dungeon, wave_done=self.combat_wave_done):
|
||||
# Update stamina so task can be delayed if both obtained_is_full and stamina exhausted
|
||||
self.combat_get_trailblaze_power()
|
||||
return False
|
||||
if not self.handle_combat_prepare():
|
||||
return False
|
||||
self.device.click(COMBAT_PREPARE)
|
||||
@ -185,13 +194,17 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
||||
in: COMBAT_AGAIN
|
||||
"""
|
||||
current = self.combat_get_trailblaze_power(expect_reduce=self.combat_wave_cost > 0)
|
||||
# Planner
|
||||
logger.attr('obtain_frequent_check', self.obtain_frequent_check)
|
||||
if self.obtain_frequent_check:
|
||||
logger.info('Exit combat to check obtained items')
|
||||
return False
|
||||
# Wave limit
|
||||
if self.combat_wave_limit:
|
||||
if self.combat_wave_done + self.combat_waves > self.combat_wave_limit:
|
||||
logger.info(f'Combat wave limit: {self.combat_wave_done}/{self.combat_wave_limit}, '
|
||||
f'can not run again')
|
||||
return False
|
||||
|
||||
# Cost limit
|
||||
if self.combat_wave_cost == 10:
|
||||
if current >= self.combat_wave_cost * self.combat_waves:
|
||||
@ -216,6 +229,19 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
||||
Returns:
|
||||
bool: True to re-enter combat and run with another wave settings
|
||||
"""
|
||||
# Planner
|
||||
logger.attr('obtain_frequent_check', self.obtain_frequent_check)
|
||||
if self.obtain_frequent_check:
|
||||
if self.config.stored.TrailblazePower.value >= self.combat_wave_cost \
|
||||
and (self.combat_wave_limit and self.combat_wave_done < self.combat_wave_limit):
|
||||
logger.info(f'Stall having some trailblaze power '
|
||||
f'but wave limit reached {self.combat_wave_done}/{self.combat_wave_limit}, '
|
||||
f'ignore obtain_frequent_check cause will reenter later')
|
||||
return False
|
||||
else:
|
||||
logger.info('Re-enter combat to check obtained items')
|
||||
return True
|
||||
# Stamina
|
||||
if self.config.stored.TrailblazePower.value < self.combat_wave_cost:
|
||||
logger.info('Current trailblaze power is not enough for next run')
|
||||
return False
|
||||
|
304
tasks/combat/obtain.py
Normal file
@ -0,0 +1,304 @@
|
||||
import re
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.exception import ScriptError
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Digit
|
||||
from tasks.combat.assets.assets_combat_obtain import *
|
||||
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
|
||||
from tasks.dungeon.keywords import DungeonList
|
||||
from tasks.planner.keywords import ITEM_CLASSES, KEYWORDS_ITEM_CURRENCY
|
||||
from tasks.planner.model import ObtainedAmmount, PlannerMixin
|
||||
from tasks.planner.scan import OcrItemName
|
||||
|
||||
|
||||
class OcrItemAmount(Digit):
|
||||
def format_result(self, result):
|
||||
res = re.split(r'[::;;]', result)
|
||||
result = res[-1]
|
||||
return super().format_result(result)
|
||||
|
||||
|
||||
class CombatObtain(PlannerMixin):
|
||||
"""
|
||||
Parse items that can be obtained from dungeon
|
||||
|
||||
Pages:
|
||||
in: COMBAT_PREPARE
|
||||
"""
|
||||
# False to click again when combat ends
|
||||
# True to exit and reenter to get obtained items
|
||||
obtain_frequent_check = False
|
||||
|
||||
def _obtain_enter(self, entry, appear_button, skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
entry: Item entry
|
||||
appear_button:
|
||||
skip_first_screenshot:
|
||||
|
||||
Pages:
|
||||
in: COMBAT_PREPARE
|
||||
out: ITEM_CLOSE
|
||||
"""
|
||||
logger.info(f'Obtain enter {entry}')
|
||||
self.interval_clear(appear_button)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(ITEM_CLOSE):
|
||||
break
|
||||
if self.appear(appear_button, interval=2):
|
||||
self.device.click(entry)
|
||||
self.interval_reset(appear_button)
|
||||
continue
|
||||
|
||||
# Wait animation
|
||||
timeout = Timer(1.4, count=7).start()
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.image_color_count(ITEM_NAME, color=(0, 0, 0), threshold=221, count=50):
|
||||
break
|
||||
if timeout.reached():
|
||||
logger.warning('Wait obtain item timeout')
|
||||
break
|
||||
|
||||
def _obtain_close(self, check_button, skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
check_button:
|
||||
skip_first_screenshot:
|
||||
|
||||
Pages:
|
||||
in: ITEM_CLOSE
|
||||
out: COMBAT_PREPARE
|
||||
"""
|
||||
logger.info(f'Obtain close')
|
||||
self.interval_clear(ITEM_CLOSE)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if not self.appear(ITEM_CLOSE):
|
||||
if callable(check_button):
|
||||
if check_button():
|
||||
break
|
||||
else:
|
||||
if self.appear(check_button):
|
||||
break
|
||||
if self.appear_then_click(ITEM_CLOSE, interval=2):
|
||||
continue
|
||||
|
||||
@staticmethod
|
||||
def _obtain_get_entry(dungeon: DungeonList, index: int = 1, prev: ObtainedAmmount = None, start: int = 0):
|
||||
"""
|
||||
Args:
|
||||
dungeon: Current dungeon
|
||||
index: 1 to 3, index to check
|
||||
prev: Previous item checked
|
||||
|
||||
Returns:
|
||||
int: Item entry index, or None if no more check needed
|
||||
"""
|
||||
if (index > 1 and prev is None) or (index <= 1 and prev is not None):
|
||||
raise ScriptError(f'_obtain_get_entry: index and prev must be set together, index={index}, prev={prev}')
|
||||
|
||||
if index > 3:
|
||||
return None
|
||||
|
||||
def may_obtain_one():
|
||||
if prev is None:
|
||||
if start:
|
||||
return 1 + start
|
||||
else:
|
||||
return 1
|
||||
else:
|
||||
return None
|
||||
|
||||
def may_obtain_multi():
|
||||
if prev is None:
|
||||
if start:
|
||||
return 1 + start
|
||||
else:
|
||||
return 1
|
||||
# End at the item with the lowest rarity
|
||||
if prev.item.is_rarity_green:
|
||||
return None
|
||||
# End at credict
|
||||
if prev.item == KEYWORDS_ITEM_CURRENCY.Credit:
|
||||
return None
|
||||
if start:
|
||||
return index + start
|
||||
else:
|
||||
return index
|
||||
|
||||
if dungeon is None:
|
||||
return may_obtain_multi()
|
||||
if dungeon.is_Echo_of_War:
|
||||
return may_obtain_one()
|
||||
if dungeon.is_Cavern_of_Corrosion:
|
||||
return None
|
||||
if dungeon.is_Stagnant_Shadow:
|
||||
return may_obtain_one()
|
||||
if dungeon.is_Calyx_Golden:
|
||||
if dungeon.is_Calyx_Golden_Treasures:
|
||||
return may_obtain_one()
|
||||
else:
|
||||
return may_obtain_multi()
|
||||
if dungeon.is_Calyx_Crimson:
|
||||
return may_obtain_multi()
|
||||
|
||||
raise ScriptError(f'_obtain_get_entry: Cannot get entry from {dungeon}')
|
||||
|
||||
def _obtain_parse(self) -> ObtainedAmmount | None:
|
||||
"""
|
||||
Pages:
|
||||
in: ITEM_CLOSE
|
||||
"""
|
||||
ocr = OcrItemName(ITEM_NAME)
|
||||
item = ocr.matched_single_line(self.device.image, keyword_classes=ITEM_CLASSES)
|
||||
ocr = OcrItemAmount(ITEM_AMOUNT)
|
||||
amount = ocr.ocr_single_line(self.device.image)
|
||||
|
||||
if item is None:
|
||||
logger.warning('_obtain_parse: Unknown item name')
|
||||
return None
|
||||
|
||||
# logger.info(f'ObtainedAmmount: item={item}, value={amount}')
|
||||
return ObtainedAmmount(
|
||||
item=item,
|
||||
value=amount,
|
||||
)
|
||||
|
||||
def obtain_get(self, dungeon=None, skip_first_screenshot=True) -> list[ObtainedAmmount]:
|
||||
"""
|
||||
Args:
|
||||
dungeon: Current dungeon,
|
||||
or None for no early stop optimization
|
||||
skip_first_screenshot:
|
||||
|
||||
Returns:
|
||||
list[ObtainedAmmount]:
|
||||
|
||||
Pages:
|
||||
in: COMBAT_PREPARE
|
||||
out: COMBAT_PREPARE
|
||||
"""
|
||||
logger.hr('Obtain get', level=2)
|
||||
if not skip_first_screenshot:
|
||||
self.device.screenshot()
|
||||
|
||||
index = 1
|
||||
prev = None
|
||||
items = []
|
||||
dic_entry = {
|
||||
1: OBTAIN_1,
|
||||
2: OBTAIN_2,
|
||||
3: OBTAIN_3,
|
||||
4: OBTAIN_4,
|
||||
}
|
||||
|
||||
self._find_may_obtain()
|
||||
|
||||
trailblaze_exp = False
|
||||
for _ in range(5):
|
||||
if not trailblaze_exp and self.appear(OBTAIN_TRAILBLAZE_EXP):
|
||||
trailblaze_exp = True
|
||||
logger.attr('trailblaze_exp', trailblaze_exp)
|
||||
|
||||
entry_index = self._obtain_get_entry(dungeon, index=index, prev=prev, start=int(trailblaze_exp))
|
||||
if entry_index is None:
|
||||
logger.info('Obtain get end')
|
||||
break
|
||||
try:
|
||||
entry = dic_entry[entry_index]
|
||||
except KeyError:
|
||||
logger.error(f'No obtain entry for {entry_index}')
|
||||
break
|
||||
|
||||
self._obtain_enter(entry, appear_button=COMBAT_PREPARE)
|
||||
item = self._obtain_parse()
|
||||
if item.item == KEYWORDS_ITEM_CURRENCY.Trailblaze_EXP:
|
||||
logger.warning('Trailblaze_EXP is in obtain list, OBTAIN_TRAILBLAZE_EXP may need to verify')
|
||||
index += 1
|
||||
prev = item
|
||||
elif item is not None:
|
||||
items.append(item)
|
||||
index += 1
|
||||
prev = item
|
||||
self._obtain_close(check_button=MAY_OBTAIN)
|
||||
|
||||
logger.hr('Obtained Result')
|
||||
for item in items:
|
||||
# Pretend everything is full
|
||||
# item.value += 1000
|
||||
logger.info(f'Obtained item: {item.item.name}, {item.value}')
|
||||
"""
|
||||
<<< OBTAIN GET RESULT >>>
|
||||
ItemAmount: Arrow_of_the_Starchaser, 15
|
||||
ItemAmount: Arrow_of_the_Demon_Slayer, 68
|
||||
ItemAmount: Arrow_of_the_Beast_Hunter, 85
|
||||
"""
|
||||
self.planner.load_obtained_amount(items)
|
||||
self.planner_write()
|
||||
return items
|
||||
|
||||
def obtained_is_full(self, dungeon: DungeonList | None, wave_done=0) -> bool:
|
||||
if dungeon is None:
|
||||
self.obtain_frequent_check = False
|
||||
return False
|
||||
row = self.planner.row_come_from_dungeon(dungeon)
|
||||
if row is None:
|
||||
self.obtain_frequent_check = False
|
||||
return False
|
||||
|
||||
# Update
|
||||
self.obtain_get(dungeon)
|
||||
|
||||
# Check progress
|
||||
row = self.planner.row_come_from_dungeon(dungeon)
|
||||
if row is None:
|
||||
logger.error(f'obtained_is_full: Row disappeared after obtain_get')
|
||||
self.obtain_frequent_check = False
|
||||
return False
|
||||
if not row.need_farm():
|
||||
logger.info('Planner row full')
|
||||
self.obtain_frequent_check = False
|
||||
return True
|
||||
|
||||
# obtain_frequent_check
|
||||
approaching = row.is_approaching_total(wave_done)
|
||||
logger.attr('is_approaching_total', approaching)
|
||||
self.obtain_frequent_check = approaching
|
||||
return False
|
||||
|
||||
def _find_may_obtain(self, skip_first_screenshot=True):
|
||||
logger.info('Find may obtain')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if MAY_OBTAIN.match_template(self.device.image):
|
||||
OBTAIN_1.load_offset(MAY_OBTAIN)
|
||||
OBTAIN_2.load_offset(MAY_OBTAIN)
|
||||
OBTAIN_3.load_offset(MAY_OBTAIN)
|
||||
OBTAIN_4.load_offset(MAY_OBTAIN)
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
self = CombatObtain('src')
|
||||
self.device.screenshot()
|
||||
self.obtain_get()
|
@ -1,8 +1,11 @@
|
||||
from datetime import timedelta
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import crop
|
||||
from module.config.utils import DEFAULT_TIME, get_server_next_update
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Ocr, OcrResultButton
|
||||
from module.ocr.utils import split_and_pair_buttons
|
||||
@ -165,6 +168,7 @@ class DailyQuestUI(DungeonUI, RouteLoader):
|
||||
"""
|
||||
self.claimed_point_reward will be set if claimed any point reward
|
||||
"""
|
||||
|
||||
def get_active():
|
||||
for b in [
|
||||
ACTIVE_POINTS_1_UNLOCK,
|
||||
@ -244,7 +248,7 @@ class DailyQuestUI(DungeonUI, RouteLoader):
|
||||
int: Number of quests done
|
||||
"""
|
||||
logger.hr('Recognize quests', level=1)
|
||||
quests = self.daily_quests_recognition()
|
||||
quests = self.config.stored.DailyQuest.load_quests()
|
||||
|
||||
done = 0
|
||||
logger.hr('Do quests', level=1)
|
||||
@ -313,6 +317,62 @@ class DailyQuestUI(DungeonUI, RouteLoader):
|
||||
|
||||
return done
|
||||
|
||||
def check_future_achieve(self):
|
||||
"""
|
||||
Returns:
|
||||
bool: True if daily activity will full, skip doing normal quests
|
||||
False if daily activity will not full, do normal quests
|
||||
"""
|
||||
point = self.config.stored.DailyActivity.value
|
||||
if point >= self.config.stored.DailyActivity.FIXED_TOTAL:
|
||||
logger.warning('DailyActivity full, no need to check future')
|
||||
return True
|
||||
quests = self.config.stored.DailyQuest.load_quests()
|
||||
if not len(quests):
|
||||
logger.warning('DailyQuest empty, cannot check future')
|
||||
return True
|
||||
|
||||
# Get task schedule
|
||||
assignment = self.config.cross_get('Assignment.Scheduler.NextRun', default=DEFAULT_TIME)
|
||||
dungeon = self.config.cross_get('Dungeon.Scheduler.NextRun', default=DEFAULT_TIME)
|
||||
reset = get_server_next_update(self.config.Scheduler_ServerUpdate)
|
||||
logger.info(f'Assignment next run: {assignment}')
|
||||
logger.info(f'Dungeon next run: {dungeon}')
|
||||
logger.info(f'Daily reset: {reset}')
|
||||
|
||||
# Calculate quests to be done in the future
|
||||
future = 0
|
||||
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_Support_Characters_1_times in quests:
|
||||
# 10min in advance to do quests
|
||||
if dungeon < reset - timedelta(minutes=10):
|
||||
logger.info('Daily support can be achieved in the future')
|
||||
future += 200
|
||||
else:
|
||||
logger.info('Daily support cannot achieved, dungeon task is scheduled tomorrow')
|
||||
if KEYWORDS_DAILY_QUEST.Consume_120_Trailblaze_Power in quests:
|
||||
# 12h10min in advance, waiting for stamina
|
||||
if dungeon < reset - timedelta(hours=12, minutes=10):
|
||||
logger.info('Stamina consume can be achieved in the future')
|
||||
future += 200
|
||||
else:
|
||||
logger.info('Stamina consume cannot achieved, dungeon task is scheduled tomorrow')
|
||||
if KEYWORDS_DAILY_QUEST.Dispatch_1_assignments in quests:
|
||||
# 10min in advance to do quests
|
||||
if assignment < reset - timedelta(minutes=10):
|
||||
logger.info('Assignment can be achieved in the future')
|
||||
future += 100
|
||||
else:
|
||||
logger.info('Assignment cannot achieved, assignment task is scheduled tomorrow')
|
||||
|
||||
# Check
|
||||
logger.attr('Future daily activity', future)
|
||||
if point + future >= self.config.stored.DailyActivity.FIXED_TOTAL:
|
||||
logger.info('Daily activity will full, skip doing normal quests')
|
||||
return True
|
||||
else:
|
||||
logger.info('Daily activity will not full, do normal quests')
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
self.config.update_battle_pass_quests()
|
||||
self.claimed_point_reward = False
|
||||
@ -322,6 +382,10 @@ class DailyQuestUI(DungeonUI, RouteLoader):
|
||||
got = self.get_daily_rewards()
|
||||
if got:
|
||||
break
|
||||
self.daily_quests_recognition()
|
||||
future = self.check_future_achieve()
|
||||
if future:
|
||||
break
|
||||
done = self.do_daily_quests()
|
||||
if not done:
|
||||
logger.info('No more quests able to do')
|
||||
|
@ -75,7 +75,9 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
if relic == 0:
|
||||
return 0
|
||||
# Combat
|
||||
self.dungeon = dungeon
|
||||
count = self.combat(team=team, wave_limit=wave_limit, support_character=support_character)
|
||||
self.dungeon = None
|
||||
|
||||
# Update quest states
|
||||
with self.config.multi_set():
|
||||
@ -131,7 +133,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
# Support quest
|
||||
if support_character is not None:
|
||||
self.called_daily_support = True
|
||||
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_Support_Characters_1_times:
|
||||
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_Support_Characters_1_times in self.daily_quests:
|
||||
logger.info('Achieve daily quest Obtain_victory_in_combat_with_Support_Characters_1_times')
|
||||
self.achieved_daily_quest = True
|
||||
# Stamina quest
|
||||
@ -222,26 +224,21 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
self.config.stored.DungeonDouble.rogue = rogue
|
||||
|
||||
# Run double events
|
||||
ran_calyx_golden = False
|
||||
ran_calyx_crimson = False
|
||||
ran_cavern_of_corrosion = False
|
||||
planner = self.planner.get_dungeon(double_calyx=True)
|
||||
# Double calyx
|
||||
if self.config.stored.DungeonDouble.calyx > 0:
|
||||
logger.info('Run double calyx')
|
||||
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
|
||||
if planner is not None:
|
||||
dungeon = planner
|
||||
self.running_double = True
|
||||
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
|
||||
self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.calyx)
|
||||
# Double relic
|
||||
if self.config.stored.DungeonDouble.relic > 0:
|
||||
logger.info('Run double relic')
|
||||
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleRelic)
|
||||
self.running_double = True
|
||||
if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.relic):
|
||||
ran_cavern_of_corrosion = True
|
||||
self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.relic)
|
||||
self.running_double = False
|
||||
|
||||
# Dungeon to clear all trailblaze power
|
||||
@ -254,43 +251,11 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
and self.config.stored.DungeonDouble.rogue > 0:
|
||||
logger.info('Going to use stamina in double rogue event')
|
||||
do_rogue = True
|
||||
if do_rogue:
|
||||
final = KEYWORDS_DUNGEON_LIST.Simulated_Universe_World_1
|
||||
else:
|
||||
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.Clear_Calyx_Crimson_1_times 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)
|
||||
final = DungeonList.find(self.config.Dungeon_Name)
|
||||
# Planner
|
||||
planner = self.planner.get_dungeon()
|
||||
if planner is not None:
|
||||
final = planner
|
||||
|
||||
# Check daily
|
||||
if self.achieved_daily_quest:
|
||||
@ -301,11 +266,11 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
self.config.task_stop()
|
||||
|
||||
# Use all stamina
|
||||
if final.is_Simulated_Universe:
|
||||
if do_rogue:
|
||||
# Use support if prioritize rogue
|
||||
if self.require_compulsory_support():
|
||||
logger.info('Run dungeon with support once as stamina is rogue prioritized')
|
||||
self.dungeon_run(dungeon=DungeonList.find(self.config.Dungeon_Name), wave_limit=1)
|
||||
self.dungeon_run(dungeon=final, wave_limit=1)
|
||||
# Store immersifiers
|
||||
logger.info('Prioritize stamina for simulated universe, skip dungeon')
|
||||
amount = 0
|
||||
@ -337,6 +302,12 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
||||
# Check daily
|
||||
if self.achieved_daily_quest:
|
||||
self.config.task_call('DailyQuest')
|
||||
else:
|
||||
# Check future daily
|
||||
if KEYWORDS_DAILY_QUEST.Obtain_victory_in_combat_with_Support_Characters_1_times in self.daily_quests:
|
||||
logger.error("Dungeon ran but support daily haven't been finished yet")
|
||||
self.config.task_call('DailyQuest')
|
||||
|
||||
# Delay tasks
|
||||
self.dungeon_stamina_delay(dungeon)
|
||||
|
||||
|
@ -20,6 +20,7 @@ class DungeonTab(Keyword):
|
||||
class DungeonList(Keyword):
|
||||
instances: ClassVar = {}
|
||||
|
||||
dungeon_id: int
|
||||
plane_id: int
|
||||
|
||||
@cached_property
|
||||
@ -183,6 +184,20 @@ class DungeonList(Keyword):
|
||||
else:
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def find_dungeon_id(cls, dungeon_id):
|
||||
"""
|
||||
Args:
|
||||
dungeon_id:
|
||||
|
||||
Returns:
|
||||
DungeonList: DungeonList object or None
|
||||
"""
|
||||
for instance in cls.instances.values():
|
||||
if instance.dungeon_id == dungeon_id:
|
||||
return instance
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def find_dungeon_by_string(cls, cn='', en='', **kwargs):
|
||||
"""
|
||||
@ -225,7 +240,6 @@ class DungeonList(Keyword):
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class DungeonEntrance(Keyword):
|
||||
instances: ClassVar = {}
|
||||
|
@ -11,6 +11,7 @@ Calyx_Golden_Memories_Jarilo_VI = DungeonList(
|
||||
en='Bud of Memories (Jarilo-Ⅵ)',
|
||||
jp='回憶の蕾・ヤリーロ-Ⅵ',
|
||||
es='Flor de los recuerdos (Jarilo-Ⅵ)',
|
||||
dungeon_id=1001,
|
||||
plane_id=2010101,
|
||||
)
|
||||
Calyx_Golden_Aether_Jarilo_VI = DungeonList(
|
||||
@ -21,6 +22,7 @@ Calyx_Golden_Aether_Jarilo_VI = DungeonList(
|
||||
en='Bud of Aether (Jarilo-Ⅵ)',
|
||||
jp='エーテルの蕾・ヤリーロ-Ⅵ',
|
||||
es='Flor de éter (Jarilo-Ⅵ)',
|
||||
dungeon_id=1002,
|
||||
plane_id=2011101,
|
||||
)
|
||||
Calyx_Golden_Treasures_Jarilo_VI = DungeonList(
|
||||
@ -31,6 +33,7 @@ Calyx_Golden_Treasures_Jarilo_VI = DungeonList(
|
||||
en='Bud of Treasures (Jarilo-Ⅵ)',
|
||||
jp='秘蔵の蕾・ヤリーロ-Ⅵ',
|
||||
es='Flor de tesoros (Jarilo-Ⅵ)',
|
||||
dungeon_id=1003,
|
||||
plane_id=2012101,
|
||||
)
|
||||
Calyx_Golden_Memories_The_Xianzhou_Luofu = DungeonList(
|
||||
@ -41,6 +44,7 @@ Calyx_Golden_Memories_The_Xianzhou_Luofu = DungeonList(
|
||||
en='Bud of Memories (The Xianzhou Luofu)',
|
||||
jp='回憶の蕾・仙舟「羅浮」',
|
||||
es='Flor de los recuerdos (El Luofu de Xianzhou)',
|
||||
dungeon_id=1011,
|
||||
plane_id=2021101,
|
||||
)
|
||||
Calyx_Golden_Aether_The_Xianzhou_Luofu = DungeonList(
|
||||
@ -51,6 +55,7 @@ Calyx_Golden_Aether_The_Xianzhou_Luofu = DungeonList(
|
||||
en='Bud of Aether (The Xianzhou Luofu)',
|
||||
jp='エーテルの蕾・仙舟「羅浮」',
|
||||
es='Flor de éter (El Luofu de Xianzhou)',
|
||||
dungeon_id=1012,
|
||||
plane_id=2022101,
|
||||
)
|
||||
Calyx_Golden_Treasures_The_Xianzhou_Luofu = DungeonList(
|
||||
@ -61,6 +66,7 @@ Calyx_Golden_Treasures_The_Xianzhou_Luofu = DungeonList(
|
||||
en='Bud of Treasures (The Xianzhou Luofu)',
|
||||
jp='秘蔵の蕾・仙舟「羅浮」',
|
||||
es='Flor de tesoros (El Luofu de Xianzhou)',
|
||||
dungeon_id=1013,
|
||||
plane_id=2022201,
|
||||
)
|
||||
Calyx_Golden_Memories_Penacony = DungeonList(
|
||||
@ -71,6 +77,7 @@ Calyx_Golden_Memories_Penacony = DungeonList(
|
||||
en='Bud of Memories (Penacony)',
|
||||
jp='回憶の蕾・ピノコニー',
|
||||
es='Flor de los recuerdos (Colonipenal)',
|
||||
dungeon_id=1014,
|
||||
plane_id=2031301,
|
||||
)
|
||||
Calyx_Golden_Aether_Penacony = DungeonList(
|
||||
@ -81,6 +88,7 @@ Calyx_Golden_Aether_Penacony = DungeonList(
|
||||
en='Bud of Aether (Penacony)',
|
||||
jp='エーテルの蕾・ピノコニー',
|
||||
es='Flor de éter (Colonipenal)',
|
||||
dungeon_id=1015,
|
||||
plane_id=2031201,
|
||||
)
|
||||
Calyx_Golden_Treasures_Penacony = DungeonList(
|
||||
@ -91,6 +99,7 @@ Calyx_Golden_Treasures_Penacony = DungeonList(
|
||||
en='Bud of Treasures (Penacony)',
|
||||
jp='秘蔵の蕾・ピノコニー',
|
||||
es='Flor de tesoros (Colonipenal)',
|
||||
dungeon_id=1016,
|
||||
plane_id=2031101,
|
||||
)
|
||||
Calyx_Crimson_Destruction_Herta_StorageZone = DungeonList(
|
||||
@ -101,6 +110,7 @@ Calyx_Crimson_Destruction_Herta_StorageZone = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Destruction',
|
||||
jp='疑似花萼(赤)・壊滅の蕾',
|
||||
es='Flor de la Destrucción',
|
||||
dungeon_id=1004,
|
||||
plane_id=2000201,
|
||||
)
|
||||
Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape = DungeonList(
|
||||
@ -111,6 +121,7 @@ Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Destruction',
|
||||
jp='疑似花萼(赤)・壊滅の蕾',
|
||||
es='Flor de la Destrucción',
|
||||
dungeon_id=1018,
|
||||
plane_id=2023201,
|
||||
)
|
||||
Calyx_Crimson_Preservation_Herta_SupplyZone = DungeonList(
|
||||
@ -121,6 +132,7 @@ Calyx_Crimson_Preservation_Herta_SupplyZone = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Preservation',
|
||||
jp='疑似花萼(赤)・存護の蕾',
|
||||
es='Flor de la Conservación',
|
||||
dungeon_id=1005,
|
||||
plane_id=2000301,
|
||||
)
|
||||
Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark = DungeonList(
|
||||
@ -131,6 +143,7 @@ Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Preservation',
|
||||
jp='疑似花萼(赤)・存護の蕾',
|
||||
es='Flor de la Conservación',
|
||||
dungeon_id=1020,
|
||||
plane_id=2032101,
|
||||
)
|
||||
Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains = DungeonList(
|
||||
@ -141,6 +154,7 @@ Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains = DungeonList(
|
||||
en='Calyx (Crimson): Bud of The Hunt',
|
||||
jp='疑似花萼(赤)・巡狩の蕾',
|
||||
es='Flor de la Cacería',
|
||||
dungeon_id=1006,
|
||||
plane_id=2010101,
|
||||
)
|
||||
Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue = DungeonList(
|
||||
@ -151,6 +165,7 @@ Calyx_Crimson_The_Hunt_Penacony_SoulGladScorchsandAuditionVenue = DungeonList(
|
||||
en='Calyx (Crimson): Bud of The Hunt',
|
||||
jp='疑似花萼(赤)・巡狩の蕾',
|
||||
es='Cáliz (carmesí): Flor de la Cacería',
|
||||
dungeon_id=1022,
|
||||
plane_id=2033101,
|
||||
)
|
||||
Calyx_Crimson_Abundance_Jarilo_BackwaterPass = DungeonList(
|
||||
@ -161,6 +176,7 @@ Calyx_Crimson_Abundance_Jarilo_BackwaterPass = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Abundance',
|
||||
jp='疑似花萼(赤)・豊穣の蕾',
|
||||
es='Flor de la Abundancia',
|
||||
dungeon_id=1007,
|
||||
plane_id=2011101,
|
||||
)
|
||||
Calyx_Crimson_Abundance_Luofu_FyxestrollGarden = DungeonList(
|
||||
@ -171,6 +187,7 @@ Calyx_Crimson_Abundance_Luofu_FyxestrollGarden = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Abundance',
|
||||
jp='疑似花萼(赤)・豊穣の蕾',
|
||||
es='Flor de la Abundancia',
|
||||
dungeon_id=1021,
|
||||
plane_id=2022301,
|
||||
)
|
||||
Calyx_Crimson_Erudition_Jarilo_RivetTown = DungeonList(
|
||||
@ -181,6 +198,7 @@ Calyx_Crimson_Erudition_Jarilo_RivetTown = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Erudition',
|
||||
jp='疑似花萼(赤)・知恵の蕾',
|
||||
es='Flor de la Erudición',
|
||||
dungeon_id=1008,
|
||||
plane_id=2012201,
|
||||
)
|
||||
Calyx_Crimson_Harmony_Jarilo_RobotSettlement = DungeonList(
|
||||
@ -191,6 +209,7 @@ Calyx_Crimson_Harmony_Jarilo_RobotSettlement = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Harmony',
|
||||
jp='疑似花萼(赤)・調和の蕾',
|
||||
es='Flor de la Armonía',
|
||||
dungeon_id=1009,
|
||||
plane_id=2012301,
|
||||
)
|
||||
Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape = DungeonList(
|
||||
@ -201,6 +220,7 @@ Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Harmony',
|
||||
jp='疑似花萼(赤)・調和の蕾',
|
||||
es='Flor de la Armonía',
|
||||
dungeon_id=1019,
|
||||
plane_id=2031101,
|
||||
)
|
||||
Calyx_Crimson_Nihility_Jarilo_GreatMine = DungeonList(
|
||||
@ -211,6 +231,7 @@ Calyx_Crimson_Nihility_Jarilo_GreatMine = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Nihility',
|
||||
jp='疑似花萼(赤)・虚無の蕾',
|
||||
es='Flor de la Nihilidad',
|
||||
dungeon_id=1010,
|
||||
plane_id=2012101,
|
||||
)
|
||||
Calyx_Crimson_Nihility_Luofu_AlchemyCommission = DungeonList(
|
||||
@ -221,6 +242,7 @@ Calyx_Crimson_Nihility_Luofu_AlchemyCommission = DungeonList(
|
||||
en='Calyx (Crimson): Bud of Nihility',
|
||||
jp='疑似花萼(赤)・虚無の蕾',
|
||||
es='Flor de la Nihilidad',
|
||||
dungeon_id=1017,
|
||||
plane_id=2023101,
|
||||
)
|
||||
Stagnant_Shadow_Quanta = DungeonList(
|
||||
@ -231,6 +253,7 @@ Stagnant_Shadow_Quanta = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Quanta',
|
||||
jp='凝結虚影・虚海の形',
|
||||
es='Forma del cuanto',
|
||||
dungeon_id=1101,
|
||||
plane_id=2000101,
|
||||
)
|
||||
Stagnant_Shadow_Gust = DungeonList(
|
||||
@ -241,6 +264,7 @@ Stagnant_Shadow_Gust = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Gust',
|
||||
jp='凝結虚影・薫風の形',
|
||||
es='Forma del aire',
|
||||
dungeon_id=1102,
|
||||
plane_id=2012201,
|
||||
)
|
||||
Stagnant_Shadow_Fulmination = DungeonList(
|
||||
@ -251,6 +275,7 @@ Stagnant_Shadow_Fulmination = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Fulmination',
|
||||
jp='凝結虚影・鳴雷の形',
|
||||
es='Forma del trueno',
|
||||
dungeon_id=1103,
|
||||
plane_id=2013201,
|
||||
)
|
||||
Stagnant_Shadow_Blaze = DungeonList(
|
||||
@ -261,6 +286,7 @@ Stagnant_Shadow_Blaze = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Blaze',
|
||||
jp='凝結虚影・炎華の形',
|
||||
es='Forma de las llamas',
|
||||
dungeon_id=1104,
|
||||
plane_id=2013101,
|
||||
)
|
||||
Stagnant_Shadow_Spike = DungeonList(
|
||||
@ -271,6 +297,7 @@ Stagnant_Shadow_Spike = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Spike',
|
||||
jp='凝結虚影・切先の形',
|
||||
es='Forma afilada',
|
||||
dungeon_id=1105,
|
||||
plane_id=2012101,
|
||||
)
|
||||
Stagnant_Shadow_Rime = DungeonList(
|
||||
@ -281,6 +308,7 @@ Stagnant_Shadow_Rime = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Rime',
|
||||
jp='凝結虚影・霜晶の形',
|
||||
es='Forma de la escarcha',
|
||||
dungeon_id=1106,
|
||||
plane_id=2013201,
|
||||
)
|
||||
Stagnant_Shadow_Mirage = DungeonList(
|
||||
@ -291,6 +319,7 @@ Stagnant_Shadow_Mirage = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Mirage',
|
||||
jp='凝結虚影・幻光の形',
|
||||
es='Forma del espejismo',
|
||||
dungeon_id=1107,
|
||||
plane_id=2011101,
|
||||
)
|
||||
Stagnant_Shadow_Icicle = DungeonList(
|
||||
@ -301,6 +330,7 @@ Stagnant_Shadow_Icicle = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Icicle',
|
||||
jp='凝結虚影・氷柱の形',
|
||||
es='Forma del témpano',
|
||||
dungeon_id=1108,
|
||||
plane_id=2021101,
|
||||
)
|
||||
Stagnant_Shadow_Doom = DungeonList(
|
||||
@ -311,6 +341,7 @@ Stagnant_Shadow_Doom = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Doom',
|
||||
jp='凝結虚影・震厄の形',
|
||||
es='Forma de la perdición',
|
||||
dungeon_id=1109,
|
||||
plane_id=2021201,
|
||||
)
|
||||
Stagnant_Shadow_Puppetry = DungeonList(
|
||||
@ -321,6 +352,7 @@ Stagnant_Shadow_Puppetry = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Puppetry',
|
||||
jp='凝結虚影・傀儡の形',
|
||||
es='Forma de las marionetas',
|
||||
dungeon_id=1110,
|
||||
plane_id=2022201,
|
||||
)
|
||||
Stagnant_Shadow_Abomination = DungeonList(
|
||||
@ -331,6 +363,7 @@ Stagnant_Shadow_Abomination = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Abomination',
|
||||
jp='凝結虚影・厄獣の形',
|
||||
es='Forma de la abominación',
|
||||
dungeon_id=1111,
|
||||
plane_id=2023201,
|
||||
)
|
||||
Stagnant_Shadow_Scorch = DungeonList(
|
||||
@ -341,6 +374,7 @@ Stagnant_Shadow_Scorch = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Scorch',
|
||||
jp='凝結虚影・燔灼の形',
|
||||
es='Forma abrasada',
|
||||
dungeon_id=1112,
|
||||
plane_id=2012101,
|
||||
)
|
||||
Stagnant_Shadow_Celestial = DungeonList(
|
||||
@ -351,6 +385,7 @@ Stagnant_Shadow_Celestial = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Celestial',
|
||||
jp='凝結虚影・天人の形',
|
||||
es='Forma de lo celestial',
|
||||
dungeon_id=1113,
|
||||
plane_id=2023101,
|
||||
)
|
||||
Stagnant_Shadow_Perdition = DungeonList(
|
||||
@ -361,6 +396,7 @@ Stagnant_Shadow_Perdition = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Perdition',
|
||||
jp='凝結虚影・幽府の形',
|
||||
es='Forma del aislamiento',
|
||||
dungeon_id=1114,
|
||||
plane_id=2022301,
|
||||
)
|
||||
Stagnant_Shadow_Nectar = DungeonList(
|
||||
@ -371,6 +407,7 @@ Stagnant_Shadow_Nectar = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Nectar',
|
||||
jp='凝結虚影・氷醸の形',
|
||||
es='Forma del néctar',
|
||||
dungeon_id=1115,
|
||||
plane_id=2031101,
|
||||
)
|
||||
Stagnant_Shadow_Roast = DungeonList(
|
||||
@ -381,6 +418,7 @@ Stagnant_Shadow_Roast = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Roast',
|
||||
jp='凝結虚影・焦灼の形',
|
||||
es='Forma del agostamiento',
|
||||
dungeon_id=1116,
|
||||
plane_id=2031301,
|
||||
)
|
||||
Stagnant_Shadow_Ire = DungeonList(
|
||||
@ -391,6 +429,7 @@ Stagnant_Shadow_Ire = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Ire',
|
||||
jp='凝結虚影・憤怒の形',
|
||||
es='Forma de la ira',
|
||||
dungeon_id=1117,
|
||||
plane_id=2032201,
|
||||
)
|
||||
Stagnant_Shadow_Duty = DungeonList(
|
||||
@ -401,6 +440,7 @@ Stagnant_Shadow_Duty = DungeonList(
|
||||
en='Stagnant Shadow: Shape of Duty',
|
||||
jp='凝結虚影・職掌の形',
|
||||
es='Sombra paralizada: Forma del deber',
|
||||
dungeon_id=1118,
|
||||
plane_id=2032101,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Gelid_Wind = DungeonList(
|
||||
@ -411,6 +451,7 @@ Cavern_of_Corrosion_Path_of_Gelid_Wind = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Gelid Wind',
|
||||
jp='侵蝕トンネル・霜風の路',
|
||||
es='Senda del viento gélido',
|
||||
dungeon_id=1201,
|
||||
plane_id=2000201,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Jabbing_Punch = DungeonList(
|
||||
@ -421,6 +462,7 @@ Cavern_of_Corrosion_Path_of_Jabbing_Punch = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Jabbing Punch',
|
||||
jp='侵蝕トンネル・迅拳の路',
|
||||
es='Senda de los puños rápidos',
|
||||
dungeon_id=1202,
|
||||
plane_id=2013101,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Drifting = DungeonList(
|
||||
@ -431,6 +473,7 @@ Cavern_of_Corrosion_Path_of_Drifting = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Drifting',
|
||||
jp='侵蝕トンネル・漂泊の路',
|
||||
es='Senda de la deriva',
|
||||
dungeon_id=1203,
|
||||
plane_id=2013201,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Providence = DungeonList(
|
||||
@ -441,6 +484,7 @@ Cavern_of_Corrosion_Path_of_Providence = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Providence',
|
||||
jp='侵蝕トンネル・睿治の路',
|
||||
es='Senda de la providencia',
|
||||
dungeon_id=1204,
|
||||
plane_id=2013401,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Holy_Hymn = DungeonList(
|
||||
@ -451,6 +495,7 @@ Cavern_of_Corrosion_Path_of_Holy_Hymn = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Holy Hymn',
|
||||
jp='侵蝕トンネル・聖頌の路',
|
||||
es='Senda del himno sagrado',
|
||||
dungeon_id=1205,
|
||||
plane_id=2021101,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Conflagration = DungeonList(
|
||||
@ -461,6 +506,7 @@ Cavern_of_Corrosion_Path_of_Conflagration = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Conflagration',
|
||||
jp='侵蝕トンネル・野焔の路',
|
||||
es='Senda de la conflagración',
|
||||
dungeon_id=1206,
|
||||
plane_id=2021201,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Elixir_Seekers = DungeonList(
|
||||
@ -471,6 +517,7 @@ Cavern_of_Corrosion_Path_of_Elixir_Seekers = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Elixir Seekers',
|
||||
jp='侵蝕トンネル・薬使の路',
|
||||
es='Senda de los elixires',
|
||||
dungeon_id=1207,
|
||||
plane_id=2023101,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Darkness = DungeonList(
|
||||
@ -481,6 +528,7 @@ Cavern_of_Corrosion_Path_of_Darkness = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Darkness',
|
||||
jp='侵蝕トンネル・幽冥の路',
|
||||
es='Senda de la oscuridad',
|
||||
dungeon_id=1208,
|
||||
plane_id=2022301,
|
||||
)
|
||||
Cavern_of_Corrosion_Path_of_Dreamdive = DungeonList(
|
||||
@ -491,6 +539,7 @@ Cavern_of_Corrosion_Path_of_Dreamdive = DungeonList(
|
||||
en='Cavern of Corrosion: Path of Dreamdive',
|
||||
jp='侵蝕トンネル・夢潜の路',
|
||||
es='Senda de los sueños',
|
||||
dungeon_id=1209,
|
||||
plane_id=2031101,
|
||||
)
|
||||
Echo_of_War_Destruction_Beginning = DungeonList(
|
||||
@ -501,6 +550,7 @@ Echo_of_War_Destruction_Beginning = DungeonList(
|
||||
en="Echo of War: Destruction's Beginning",
|
||||
jp='歴戦余韻・壊滅の始まり',
|
||||
es='El principio de la Destrucción',
|
||||
dungeon_id=1301,
|
||||
plane_id=2000301,
|
||||
)
|
||||
Echo_of_War_End_of_the_Eternal_Freeze = DungeonList(
|
||||
@ -511,6 +561,7 @@ Echo_of_War_End_of_the_Eternal_Freeze = DungeonList(
|
||||
en='Echo of War: End of the Eternal Freeze',
|
||||
jp='歴戦余韻・寒波の幕切れ',
|
||||
es='El fin del Hielo Eterno',
|
||||
dungeon_id=1302,
|
||||
plane_id=2013401,
|
||||
)
|
||||
Echo_of_War_Divine_Seed = DungeonList(
|
||||
@ -521,6 +572,7 @@ Echo_of_War_Divine_Seed = DungeonList(
|
||||
en='Echo of War: Divine Seed',
|
||||
jp='歴戦余韻・不死の神実',
|
||||
es='Semilla divina',
|
||||
dungeon_id=1303,
|
||||
plane_id=2023201,
|
||||
)
|
||||
Echo_of_War_Borehole_Planet_Old_Crater = DungeonList(
|
||||
@ -531,6 +583,7 @@ Echo_of_War_Borehole_Planet_Old_Crater = DungeonList(
|
||||
en="Echo of War: Borehole Planet's Old Crater",
|
||||
jp='歴戦余韻・星を蝕む往日の面影',
|
||||
es='Cráter del planeta devorado',
|
||||
dungeon_id=1304,
|
||||
plane_id=2000401,
|
||||
)
|
||||
Echo_of_War_Salutations_of_Ashen_Dreams = DungeonList(
|
||||
@ -541,6 +594,7 @@ Echo_of_War_Salutations_of_Ashen_Dreams = DungeonList(
|
||||
en='Echo of War: Salutations of Ashen Dreams',
|
||||
jp='歴戦余韻・現世の夢の礼賛',
|
||||
es='Ecos de la guerra: Tributo del sueño ceniciento',
|
||||
dungeon_id=1305,
|
||||
plane_id=2033201,
|
||||
)
|
||||
Simulated_Universe_World_1 = DungeonList(
|
||||
@ -551,6 +605,7 @@ Simulated_Universe_World_1 = DungeonList(
|
||||
en='Simulated Universe: World 1',
|
||||
jp='第一世界・模擬宇宙',
|
||||
es='Mundo 1',
|
||||
dungeon_id=110,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_3 = DungeonList(
|
||||
@ -561,6 +616,7 @@ Simulated_Universe_World_3 = DungeonList(
|
||||
en='Simulated Universe: World 3',
|
||||
jp='第三世界・模擬宇宙',
|
||||
es='Mundo 3',
|
||||
dungeon_id=130,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_4 = DungeonList(
|
||||
@ -571,6 +627,7 @@ Simulated_Universe_World_4 = DungeonList(
|
||||
en='Simulated Universe: World 4',
|
||||
jp='第四世界・模擬宇宙',
|
||||
es='Mundo 4',
|
||||
dungeon_id=140,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_5 = DungeonList(
|
||||
@ -581,6 +638,7 @@ Simulated_Universe_World_5 = DungeonList(
|
||||
en='Simulated Universe: World 5',
|
||||
jp='第五世界・模擬宇宙',
|
||||
es='Mundo 5',
|
||||
dungeon_id=150,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_6 = DungeonList(
|
||||
@ -591,6 +649,7 @@ Simulated_Universe_World_6 = DungeonList(
|
||||
en='Simulated Universe: World 6',
|
||||
jp='第六世界・模擬宇宙',
|
||||
es='Mundo 6',
|
||||
dungeon_id=160,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_7 = DungeonList(
|
||||
@ -601,6 +660,7 @@ Simulated_Universe_World_7 = DungeonList(
|
||||
en='Simulated Universe: World 7',
|
||||
jp='第七世界・模擬宇宙',
|
||||
es='Mundo 7',
|
||||
dungeon_id=170,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_8 = DungeonList(
|
||||
@ -611,6 +671,7 @@ Simulated_Universe_World_8 = DungeonList(
|
||||
en='Simulated Universe: World 8',
|
||||
jp='第八世界・模擬宇宙',
|
||||
es='Mundo 8',
|
||||
dungeon_id=180,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_World_9 = DungeonList(
|
||||
@ -621,6 +682,7 @@ Simulated_Universe_World_9 = DungeonList(
|
||||
en='Simulated Universe: World 9',
|
||||
jp='第九世界・模擬宇宙',
|
||||
es='Mundo 9',
|
||||
dungeon_id=190,
|
||||
plane_id=100000104,
|
||||
)
|
||||
Simulated_Universe_The_Swarm_Disaster = DungeonList(
|
||||
@ -631,6 +693,7 @@ Simulated_Universe_The_Swarm_Disaster = DungeonList(
|
||||
en='The Swarm Disaster',
|
||||
jp='宇宙の蝗害',
|
||||
es='La Plaga',
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
Simulated_Universe_Gold_and_Gears = DungeonList(
|
||||
@ -641,6 +704,7 @@ Simulated_Universe_Gold_and_Gears = DungeonList(
|
||||
en='Gold and Gears',
|
||||
jp='黄金と機械',
|
||||
es='Oro y maquinaria',
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
Memory_of_Chaos = DungeonList(
|
||||
@ -651,6 +715,7 @@ Memory_of_Chaos = DungeonList(
|
||||
en='Memory of Chaos',
|
||||
jp='混沌の記憶',
|
||||
es='Evocación caótica',
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
The_Voyage_of_Navis_Astriger = DungeonList(
|
||||
@ -661,6 +726,7 @@ The_Voyage_of_Navis_Astriger = DungeonList(
|
||||
en='The Voyage of Navis Astriger',
|
||||
jp='天艟求仙放浪記',
|
||||
es='El viaje de las naves astriger',
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
The_Last_Vestiges_of_Towering_Citadel = DungeonList(
|
||||
@ -671,5 +737,6 @@ The_Last_Vestiges_of_Towering_Citadel = DungeonList(
|
||||
en='The Last Vestiges of Towering Citadel',
|
||||
jp='永屹の城の秘密',
|
||||
es='Herencia de la Ciudadela Imponente',
|
||||
dungeon_id=-1,
|
||||
plane_id=-1,
|
||||
)
|
||||
|
@ -51,6 +51,10 @@ class WeeklyDungeon(Dungeon):
|
||||
self.weekly_quests = self.config.stored.BattlePassWeeklyQuest.load_quests()
|
||||
|
||||
dungeon = DungeonList.find(self.config.Weekly_Name)
|
||||
planner = self.planner.get_weekly()
|
||||
if planner is not None:
|
||||
dungeon = planner
|
||||
logger.attr('DungeonWeekly', dungeon)
|
||||
|
||||
# UI switches
|
||||
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
|
||||
|
75
tasks/item/assets/assets_item_synthesize.py
Normal file
@ -0,0 +1,75 @@
|
||||
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 ```
|
||||
|
||||
ENTRY_ITEM_FROM = ButtonWrapper(
|
||||
name='ENTRY_ITEM_FROM',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/ENTRY_ITEM_FROM.png',
|
||||
area=(825, 408, 905, 488),
|
||||
search=(805, 388, 925, 508),
|
||||
color=(70, 105, 114),
|
||||
button=(825, 408, 905, 488),
|
||||
),
|
||||
)
|
||||
ENTRY_ITEM_TO = ButtonWrapper(
|
||||
name='ENTRY_ITEM_TO',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/ENTRY_ITEM_TO.png',
|
||||
area=(815, 193, 915, 293),
|
||||
search=(795, 173, 935, 313),
|
||||
color=(157, 143, 120),
|
||||
button=(815, 193, 915, 293),
|
||||
),
|
||||
)
|
||||
ITEM_NAME = ButtonWrapper(
|
||||
name='ITEM_NAME',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/ITEM_NAME.png',
|
||||
area=(657, 95, 1057, 118),
|
||||
search=(637, 75, 1077, 138),
|
||||
color=(92, 100, 111),
|
||||
button=(657, 95, 1057, 118),
|
||||
),
|
||||
)
|
||||
SWITCH_RARITY = ButtonWrapper(
|
||||
name='SWITCH_RARITY',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/SWITCH_RARITY.png',
|
||||
area=(1180, 262, 1216, 298),
|
||||
search=(1160, 242, 1236, 318),
|
||||
color=(89, 96, 124),
|
||||
button=(1180, 262, 1216, 298),
|
||||
),
|
||||
)
|
||||
SYNTHESIZE_AMOUNT = ButtonWrapper(
|
||||
name='SYNTHESIZE_AMOUNT',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/SYNTHESIZE_AMOUNT.png',
|
||||
area=(683, 548, 1034, 568),
|
||||
search=(663, 528, 1054, 588),
|
||||
color=(122, 132, 147),
|
||||
button=(683, 548, 1034, 568),
|
||||
),
|
||||
)
|
||||
SYNTHESIZE_MINUS = ButtonWrapper(
|
||||
name='SYNTHESIZE_MINUS',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/SYNTHESIZE_MINUS.png',
|
||||
area=(575, 569, 605, 589),
|
||||
search=(555, 549, 625, 609),
|
||||
color=(235, 235, 235),
|
||||
button=(575, 569, 605, 589),
|
||||
),
|
||||
)
|
||||
SYNTHESIZE_PLUS = ButtonWrapper(
|
||||
name='SYNTHESIZE_PLUS',
|
||||
share=Button(
|
||||
file='./assets/share/item/synthesize/SYNTHESIZE_PLUS.png',
|
||||
area=(1125, 567, 1155, 589),
|
||||
search=(1105, 547, 1175, 609),
|
||||
color=(228, 228, 228),
|
||||
button=(1125, 567, 1155, 589),
|
||||
),
|
||||
)
|
211
tasks/item/synthesize.py
Normal file
@ -0,0 +1,211 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import color_similarity_2d, crop, image_size
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Ocr
|
||||
from tasks.base.page import page_synthesize
|
||||
from tasks.combat.obtain import CombatObtain
|
||||
from tasks.item.assets.assets_item_synthesize import *
|
||||
from tasks.planner.keywords import ITEM_CLASSES
|
||||
from tasks.planner.model import ObtainedAmmount
|
||||
from tasks.planner.scan import OcrItemName
|
||||
|
||||
RARITY_COLOR = {
|
||||
'green': (68, 127, 124),
|
||||
'blue': (76, 124, 191),
|
||||
'purple': (141, 97, 203),
|
||||
}
|
||||
|
||||
|
||||
def image_color_count(image, color, threshold=221):
|
||||
mask = color_similarity_2d(image, color=color)
|
||||
cv2.inRange(mask, threshold, 255, dst=mask)
|
||||
sum_ = cv2.countNonZero(mask)
|
||||
return sum_
|
||||
|
||||
|
||||
class WhiteStrip(Ocr):
|
||||
def pre_process(self, image):
|
||||
mask = color_similarity_2d(image, color=(255, 255, 255))
|
||||
mask = cv2.inRange(mask, 180, 255, dst=mask)
|
||||
|
||||
mask = np.mean(mask, axis=0)
|
||||
point = np.array(cv2.findNonZero(mask))[:, 0, 1]
|
||||
x1, x2 = point.min(), point.max()
|
||||
|
||||
_, y = image_size(image)
|
||||
image = crop(image, (x1 - 5, 0, x2 + 5, y), copy=False)
|
||||
return image
|
||||
|
||||
|
||||
class SynthesizeItemName(OcrItemName, WhiteStrip):
|
||||
pass
|
||||
|
||||
|
||||
class Synthesize(CombatObtain):
|
||||
def item_get_rarity(self, button) -> str | None:
|
||||
"""
|
||||
Args:
|
||||
button:
|
||||
|
||||
Returns:
|
||||
str: Rarity color or None if no match
|
||||
|
||||
Pages:
|
||||
in: page_synthesize
|
||||
"""
|
||||
image = self.image_crop(button)
|
||||
image = cv2.GaussianBlur(image, (3, 3), 0)
|
||||
x2, y2 = image_size(image)
|
||||
y1 = y2 - int(y2 // 4)
|
||||
image = crop(image, (0, y1, x2, y2))
|
||||
# self.device.image_show(image)
|
||||
# print(image.shape)
|
||||
|
||||
# Must contain 30% target color at icon bottom
|
||||
minimum = x2 * (y2 - y1) * 0.3
|
||||
for rarity, color in RARITY_COLOR.items():
|
||||
count = image_color_count(image, color=color, threshold=221)
|
||||
# print(rarity, count, minimum)
|
||||
if count > minimum:
|
||||
return rarity
|
||||
|
||||
return None
|
||||
|
||||
def item_get_rarity_retry(self, button, skip_first_screenshot=True) -> str | None:
|
||||
timeout = Timer(1, count=3).start()
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# End
|
||||
current = self.item_get_rarity(button)
|
||||
logger.attr('SynthesizeRarity', current)
|
||||
if current is not None:
|
||||
return current
|
||||
if timeout.reached():
|
||||
logger.warning(f'item_get_rarity_retry timeout')
|
||||
return None
|
||||
|
||||
def synthesize_rarity_set(self, rarity: str, skip_first_screenshot=True) -> bool:
|
||||
"""
|
||||
Args:
|
||||
rarity: "green" or "blue"
|
||||
note that rarity is the one you consume to synthesize
|
||||
skip_first_screenshot:
|
||||
|
||||
Returns:
|
||||
bool: If switched
|
||||
|
||||
Pages:
|
||||
in: page_synthesize
|
||||
"""
|
||||
logger.info(f'item_synthesize_rarity_set: {rarity}')
|
||||
|
||||
switched = False
|
||||
self.interval_clear(page_synthesize.check_button)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# End
|
||||
current = self.item_get_rarity(ENTRY_ITEM_FROM)
|
||||
logger.attr('SynthesizeRarity', current)
|
||||
if current is not None and current == rarity:
|
||||
break
|
||||
|
||||
# Click
|
||||
if self.ui_page_appear(page_synthesize, interval=2):
|
||||
self.device.click(SWITCH_RARITY)
|
||||
switched = True
|
||||
continue
|
||||
|
||||
return switched
|
||||
|
||||
def synthesize_rarity_reset(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Reset rarity switch, so current item will pin on the first row
|
||||
|
||||
Returns:
|
||||
bool: If success
|
||||
"""
|
||||
|
||||
current = self.item_get_rarity_retry(ENTRY_ITEM_FROM)
|
||||
if current == 'blue':
|
||||
r1, r2 = 'green', 'blue'
|
||||
elif current == 'green':
|
||||
r1, r2 = 'blue', 'green'
|
||||
else:
|
||||
logger.error(f'item_synthesize_rarity_reset: Unknown current rarity {current}')
|
||||
return False
|
||||
|
||||
self.synthesize_rarity_set(r1, skip_first_screenshot=skip_first_screenshot)
|
||||
self.synthesize_rarity_set(r2, skip_first_screenshot=True)
|
||||
return True
|
||||
|
||||
def synthesize_obtain_get(self) -> list[ObtainedAmmount]:
|
||||
"""
|
||||
Update item amount from synthesize page
|
||||
"""
|
||||
logger.hr('Synthesize obtain get', level=2)
|
||||
items = []
|
||||
|
||||
def obtain_end():
|
||||
return self.item_get_rarity(ENTRY_ITEM_FROM) is not None
|
||||
|
||||
# Purple
|
||||
self.synthesize_rarity_set('blue')
|
||||
self._obtain_enter(ENTRY_ITEM_TO, appear_button=page_synthesize.check_button)
|
||||
item = self._obtain_parse()
|
||||
if item is not None:
|
||||
items.append(item)
|
||||
self._obtain_close(check_button=obtain_end)
|
||||
# Blue
|
||||
self._obtain_enter(ENTRY_ITEM_FROM, appear_button=page_synthesize.check_button)
|
||||
item = self._obtain_parse()
|
||||
if item is not None:
|
||||
items.append(item)
|
||||
self._obtain_close(check_button=obtain_end)
|
||||
# Green
|
||||
self.synthesize_rarity_set('green')
|
||||
self._obtain_enter(ENTRY_ITEM_FROM, appear_button=page_synthesize.check_button)
|
||||
item = self._obtain_parse()
|
||||
if item is not None:
|
||||
items.append(item)
|
||||
self._obtain_close(check_button=obtain_end)
|
||||
|
||||
logger.hr('Obtained Result')
|
||||
for item in items:
|
||||
# Pretend everything is full
|
||||
# item.value += 1000
|
||||
logger.info(f'Obtained item: {item.item.name}, {item.value}')
|
||||
"""
|
||||
<<< OBTAIN GET RESULT >>>
|
||||
ItemAmount: Arrow_of_the_Starchaser, 15
|
||||
ItemAmount: Arrow_of_the_Demon_Slayer, 68
|
||||
ItemAmount: Arrow_of_the_Beast_Hunter, 85
|
||||
"""
|
||||
self.planner.load_obtained_amount(items)
|
||||
self.planner_write()
|
||||
return items
|
||||
|
||||
def synthesize_get_item(self):
|
||||
ocr = SynthesizeItemName(ITEM_NAME)
|
||||
item = ocr.matched_single_line(self.device.image, keyword_classes=ITEM_CLASSES)
|
||||
if item is None:
|
||||
logger.warning('synthesize_get_item: Unknown item name')
|
||||
return None
|
||||
|
||||
return item
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
self = Synthesize('src')
|
||||
self.device.screenshot()
|
||||
self.synthesize_obtain_get()
|
65
tasks/planner/assets/assets_planner_result.py
Normal file
@ -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 ```
|
||||
|
||||
CALCULATE_TITLE = ButtonWrapper(
|
||||
name='CALCULATE_TITLE',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/CALCULATE_TITLE.png',
|
||||
area=(264, 187, 346, 207),
|
||||
search=(244, 167, 366, 227),
|
||||
color=(141, 143, 161),
|
||||
button=(264, 187, 346, 207),
|
||||
),
|
||||
)
|
||||
DETAIL_TITLE = ButtonWrapper(
|
||||
name='DETAIL_TITLE',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/DETAIL_TITLE.png',
|
||||
area=(263, 402, 346, 422),
|
||||
search=(243, 382, 366, 442),
|
||||
color=(144, 146, 164),
|
||||
button=(263, 402, 346, 422),
|
||||
),
|
||||
)
|
||||
MATERIAL_TITLE = ButtonWrapper(
|
||||
name='MATERIAL_TITLE',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/MATERIAL_TITLE.png',
|
||||
area=(263, 194, 346, 214),
|
||||
search=(243, 174, 366, 234),
|
||||
color=(135, 136, 156),
|
||||
button=(263, 194, 346, 214),
|
||||
),
|
||||
)
|
||||
OCR_RESULT = ButtonWrapper(
|
||||
name='OCR_RESULT',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/OCR_RESULT.png',
|
||||
area=(331, 104, 1201, 592),
|
||||
search=(311, 84, 1221, 612),
|
||||
color=(254, 254, 254),
|
||||
button=(331, 104, 1201, 592),
|
||||
),
|
||||
)
|
||||
RESULT_CHECK = ButtonWrapper(
|
||||
name='RESULT_CHECK',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/RESULT_CHECK.png',
|
||||
area=(263, 128, 324, 148),
|
||||
search=(255, 103, 355, 593),
|
||||
color=(132, 119, 92),
|
||||
button=(263, 128, 324, 148),
|
||||
),
|
||||
)
|
||||
RESULT_SCROLL = ButtonWrapper(
|
||||
name='RESULT_SCROLL',
|
||||
share=Button(
|
||||
file='./assets/share/planner/result/RESULT_SCROLL.png',
|
||||
area=(1238, 104, 1245, 592),
|
||||
search=(1218, 84, 1265, 612),
|
||||
color=(33, 44, 62),
|
||||
button=(1238, 104, 1245, 592),
|
||||
),
|
||||
)
|
20
tasks/planner/keywords/__init__.py
Normal file
@ -0,0 +1,20 @@
|
||||
from typing import Union
|
||||
|
||||
# Import order matters, DO NOT optimize imports
|
||||
# 1
|
||||
import tasks.planner.keywords.item_currency as KEYWORDS_ITEM_CURRENCY
|
||||
# 2
|
||||
import tasks.planner.keywords.item_exp as KEYWORDS_ITEM_EXP
|
||||
# 3
|
||||
import tasks.planner.keywords.item_ascension as KEYWORDS_ITEM_ASCENSION
|
||||
# 4
|
||||
import tasks.planner.keywords.item_trace as KEYWORDS_ITEM_TRACE
|
||||
# 5
|
||||
import tasks.planner.keywords.item_weekly as KEYWORDS_ITEM_WEEKLY
|
||||
# 6
|
||||
import tasks.planner.keywords.item_calyx as KEYWORDS_ITEM_CALYX
|
||||
|
||||
from tasks.planner.keywords.classes import ItemAscension, ItemCalyx, ItemCurrency, ItemExp, ItemTrace, ItemWeekly
|
||||
|
||||
ITEM_CLASSES = [ItemAscension, ItemCalyx, ItemCurrency, ItemExp, ItemTrace, ItemWeekly]
|
||||
ITEM_TYPES = Union[ItemAscension, ItemCalyx, ItemCurrency, ItemExp, ItemTrace, ItemWeekly]
|
152
tasks/planner/keywords/classes.py
Normal file
@ -0,0 +1,152 @@
|
||||
from dataclasses import dataclass
|
||||
from functools import cached_property
|
||||
from typing import ClassVar
|
||||
|
||||
from module.exception import ScriptError
|
||||
from module.ocr.keyword import Keyword
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemBase(Keyword):
|
||||
instances: ClassVar = {}
|
||||
|
||||
rarity: str
|
||||
item_id: int
|
||||
item_group: int
|
||||
dungeon_id: int
|
||||
|
||||
def __post_init__(self):
|
||||
self.__class__.instances[self.name] = self
|
||||
|
||||
@classmethod
|
||||
def find_name(cls, name):
|
||||
"""
|
||||
Args:
|
||||
name: Attribute name of keyword.
|
||||
|
||||
Returns:
|
||||
Keyword instance.
|
||||
|
||||
Raises:
|
||||
ScriptError: If nothing found.
|
||||
"""
|
||||
if isinstance(name, Keyword):
|
||||
return name
|
||||
try:
|
||||
return cls.instances[name]
|
||||
except KeyError:
|
||||
# Not found
|
||||
raise ScriptError(f'Cannot find a {cls.__name__} instance that matches "{name}"')
|
||||
|
||||
@cached_property
|
||||
def dungeon(self):
|
||||
"""
|
||||
Dungeon that drops this item
|
||||
|
||||
Returns:
|
||||
DungeonList: DungeonList object or None
|
||||
"""
|
||||
if self.dungeon_id > 0:
|
||||
from tasks.dungeon.keywords.classes import DungeonList
|
||||
return DungeonList.find_dungeon_id(self.dungeon_id)
|
||||
else:
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def is_rarity_gold(self):
|
||||
return self.rarity == 'SuperRare'
|
||||
|
||||
@cached_property
|
||||
def is_rarity_purple(self):
|
||||
return self.rarity == 'VeryRare'
|
||||
|
||||
@cached_property
|
||||
def is_rarity_blue(self):
|
||||
return self.rarity == 'Rare'
|
||||
|
||||
@cached_property
|
||||
def is_rarity_green(self):
|
||||
return self.rarity == 'NotNormal'
|
||||
|
||||
@cached_property
|
||||
def is_ItemAscension(self):
|
||||
return self.__class__.__name__ == 'ItemAscension'
|
||||
|
||||
@cached_property
|
||||
def is_ItemCalyx(self):
|
||||
return self.__class__.__name__ == 'ItemCalyx'
|
||||
|
||||
@cached_property
|
||||
def is_ItemCurrency(self):
|
||||
return self.__class__.__name__ == 'ItemCurrency'
|
||||
|
||||
@cached_property
|
||||
def is_ItemExp(self):
|
||||
return self.__class__.__name__ == 'ItemExp'
|
||||
|
||||
@cached_property
|
||||
def is_ItemTrace(self):
|
||||
return self.__class__.__name__ == 'ItemTrace'
|
||||
|
||||
@cached_property
|
||||
def is_ItemWeekly(self):
|
||||
return self.__class__.__name__ == 'ItemWeekly'
|
||||
|
||||
@cached_property
|
||||
def group_base(self):
|
||||
if not self.has_group_base:
|
||||
return self
|
||||
if self.item_group <= 0:
|
||||
raise ScriptError(f'Item {self} has no item_group defined, cannot find group_base')
|
||||
|
||||
for instance in self.__class__.instances.values():
|
||||
if instance.item_group == self.item_group and instance.is_rarity_purple:
|
||||
return instance
|
||||
|
||||
raise ScriptError(f'Item {self} has no group_base')
|
||||
|
||||
@cached_property
|
||||
def has_group_base(self):
|
||||
return self.is_ItemCalyx or self.is_ItemExp or self.is_ItemTrace
|
||||
|
||||
@cached_property
|
||||
def is_group_base(self):
|
||||
if self.has_group_base:
|
||||
return self.is_rarity_purple
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
"""
|
||||
Sub item genres don't have `instances` defined, so all objects are in ItemBase.instances
|
||||
"""
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemAscension(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemCalyx(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemCurrency(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemExp(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemTrace(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ItemWeekly(ItemBase):
|
||||
pass
|
239
tasks/planner/keywords/item_ascension.py
Normal file
@ -0,0 +1,239 @@
|
||||
from .classes import ItemAscension
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Broken_Teeth_of_Iron_Wolf = ItemAscension(
|
||||
id=1,
|
||||
name='Broken_Teeth_of_Iron_Wolf',
|
||||
cn='铁狼碎齿',
|
||||
cht='鐵狼碎齒',
|
||||
en='Broken Teeth of Iron Wolf',
|
||||
jp='鉄狼の砕けた刃',
|
||||
es='Dientes rotos del huargo férreo',
|
||||
rarity='VeryRare',
|
||||
item_id=110401,
|
||||
item_group=1100,
|
||||
dungeon_id=1105,
|
||||
)
|
||||
Endotherm_Chitin = ItemAscension(
|
||||
id=2,
|
||||
name='Endotherm_Chitin',
|
||||
cn='恒温晶壳',
|
||||
cht='恆溫晶殼',
|
||||
en='Endotherm Chitin',
|
||||
jp='恒温晶殻',
|
||||
es='Quitina endoterma',
|
||||
rarity='VeryRare',
|
||||
item_id=110402,
|
||||
item_group=1100,
|
||||
dungeon_id=1104,
|
||||
)
|
||||
Horn_of_Snow = ItemAscension(
|
||||
id=3,
|
||||
name='Horn_of_Snow',
|
||||
cn='风雪之角',
|
||||
cht='風雪之角',
|
||||
en='Horn of Snow',
|
||||
jp='吹雪の角',
|
||||
es='Cuerno de nieve',
|
||||
rarity='VeryRare',
|
||||
item_id=110403,
|
||||
item_group=1100,
|
||||
dungeon_id=1106,
|
||||
)
|
||||
Lightning_Crown_of_the_Past_Shadow = ItemAscension(
|
||||
id=4,
|
||||
name='Lightning_Crown_of_the_Past_Shadow',
|
||||
cn='往日之影的雷冠',
|
||||
cht='往日之影的雷冠',
|
||||
en='Lightning Crown of the Past Shadow',
|
||||
jp='過去の影の雷冠',
|
||||
es='Corona de rayos de la sombra del pasado',
|
||||
rarity='VeryRare',
|
||||
item_id=110404,
|
||||
item_group=1100,
|
||||
dungeon_id=1103,
|
||||
)
|
||||
Storm_Eye = ItemAscension(
|
||||
id=5,
|
||||
name='Storm_Eye',
|
||||
cn='暴风之眼',
|
||||
cht='暴風之眼',
|
||||
en='Storm Eye',
|
||||
jp='暴風の眼',
|
||||
es='Ojo del vendaval',
|
||||
rarity='VeryRare',
|
||||
item_id=110405,
|
||||
item_group=1100,
|
||||
dungeon_id=1102,
|
||||
)
|
||||
Void_Cast_Iron = ItemAscension(
|
||||
id=6,
|
||||
name='Void_Cast_Iron',
|
||||
cn='虚幻铸铁',
|
||||
cht='虛幻鑄鐵',
|
||||
en='Void Cast Iron',
|
||||
jp='虚幻鋳鉄',
|
||||
es='Hierro forjado del Vacío',
|
||||
rarity='VeryRare',
|
||||
item_id=110406,
|
||||
item_group=1100,
|
||||
dungeon_id=1101,
|
||||
)
|
||||
Golden_Crown_of_the_Past_Shadow = ItemAscension(
|
||||
id=7,
|
||||
name='Golden_Crown_of_the_Past_Shadow',
|
||||
cn='往日之影的金饰',
|
||||
cht='往日之影的金飾',
|
||||
en='Golden Crown of the Past Shadow',
|
||||
jp='過去の影の金装飾',
|
||||
es='Corona dorada de la sombra del pasado',
|
||||
rarity='VeryRare',
|
||||
item_id=110407,
|
||||
item_group=1100,
|
||||
dungeon_id=1107,
|
||||
)
|
||||
Netherworld_Token = ItemAscension(
|
||||
id=8,
|
||||
name='Netherworld_Token',
|
||||
cn='幽府通令',
|
||||
cht='幽府通令',
|
||||
en='Netherworld Token',
|
||||
jp='幽府通令',
|
||||
es='Pase del inframundo',
|
||||
rarity='VeryRare',
|
||||
item_id=110411,
|
||||
item_group=1100,
|
||||
dungeon_id=1114,
|
||||
)
|
||||
Searing_Steel_Blade = ItemAscension(
|
||||
id=9,
|
||||
name='Searing_Steel_Blade',
|
||||
cn='过热钢刃',
|
||||
cht='過熱鋼刃',
|
||||
en='Searing Steel Blade',
|
||||
jp='灼熱の鋼刃',
|
||||
es='Hoja de acero sobrecalentado',
|
||||
rarity='VeryRare',
|
||||
item_id=110412,
|
||||
item_group=1100,
|
||||
dungeon_id=1112,
|
||||
)
|
||||
Gelid_Chitin = ItemAscension(
|
||||
id=10,
|
||||
name='Gelid_Chitin',
|
||||
cn='苦寒晶壳',
|
||||
cht='苦寒晶殼',
|
||||
en='Gelid Chitin',
|
||||
jp='苦寒晶殻',
|
||||
es='Quitina gélida',
|
||||
rarity='VeryRare',
|
||||
item_id=110413,
|
||||
item_group=1100,
|
||||
dungeon_id=1108,
|
||||
)
|
||||
Shape_Shifter_Lightning_Staff = ItemAscension(
|
||||
id=11,
|
||||
name='Shape_Shifter_Lightning_Staff',
|
||||
cn='炼形者雷枝',
|
||||
cht='煉形者雷枝',
|
||||
en="Shape Shifter's Lightning Staff",
|
||||
jp='鍛錬者の雷枝',
|
||||
es='Báculo del Cambiaformas',
|
||||
rarity='VeryRare',
|
||||
item_id=110414,
|
||||
item_group=1100,
|
||||
dungeon_id=1109,
|
||||
)
|
||||
Ascendant_Debris = ItemAscension(
|
||||
id=12,
|
||||
name='Ascendant_Debris',
|
||||
cn='天人遗垢',
|
||||
cht='天人遺垢',
|
||||
en='Ascendant Debris',
|
||||
jp='天人の残穢',
|
||||
es='Vestigios elevados',
|
||||
rarity='VeryRare',
|
||||
item_id=110415,
|
||||
item_group=1100,
|
||||
dungeon_id=1113,
|
||||
)
|
||||
Nail_of_the_Ape = ItemAscension(
|
||||
id=13,
|
||||
name='Nail_of_the_Ape',
|
||||
cn='苍猿之钉',
|
||||
cht='蒼猿之釘',
|
||||
en='Nail of the Ape',
|
||||
jp='蒼猿の釘',
|
||||
es='Clavo del simio',
|
||||
rarity='VeryRare',
|
||||
item_id=110416,
|
||||
item_group=1100,
|
||||
dungeon_id=1111,
|
||||
)
|
||||
Suppressing_Edict = ItemAscension(
|
||||
id=14,
|
||||
name='Suppressing_Edict',
|
||||
cn='镇灵敕符',
|
||||
cht='鎮靈敕符',
|
||||
en='Suppressing Edict',
|
||||
jp='霊鎮めの勅符',
|
||||
es='Edicto de la contención',
|
||||
rarity='VeryRare',
|
||||
item_id=110417,
|
||||
item_group=1100,
|
||||
dungeon_id=1110,
|
||||
)
|
||||
IPC_Work_Permit = ItemAscension(
|
||||
id=15,
|
||||
name='IPC_Work_Permit',
|
||||
cn='星际和平工作证',
|
||||
cht='星際和平工作證',
|
||||
en='IPC Work Permit',
|
||||
jp='スターピース社員証',
|
||||
es='Permiso de trabajo de la Corporación',
|
||||
rarity='VeryRare',
|
||||
item_id=110421,
|
||||
item_group=1100,
|
||||
dungeon_id=1118,
|
||||
)
|
||||
Raging_Heart = ItemAscension(
|
||||
id=16,
|
||||
name='Raging_Heart',
|
||||
cn='忿火之心',
|
||||
cht='忿火之心',
|
||||
en='Raging Heart',
|
||||
jp='憤怒の心',
|
||||
es='Corazón ardiente',
|
||||
rarity='VeryRare',
|
||||
item_id=110422,
|
||||
item_group=1100,
|
||||
dungeon_id=1117,
|
||||
)
|
||||
Dream_Fridge = ItemAscension(
|
||||
id=17,
|
||||
name='Dream_Fridge',
|
||||
cn='冷藏梦箱',
|
||||
cht='冷藏夢箱',
|
||||
en='Dream Fridge',
|
||||
jp='夢の冷蔵庫',
|
||||
es='Nevera de sueños',
|
||||
rarity='VeryRare',
|
||||
item_id=110423,
|
||||
item_group=1100,
|
||||
dungeon_id=1115,
|
||||
)
|
||||
Dream_Flamer = ItemAscension(
|
||||
id=18,
|
||||
name='Dream_Flamer',
|
||||
cn='炙梦喷枪',
|
||||
cht='炙夢噴槍',
|
||||
en='Dream Flamer',
|
||||
jp='夢を炙るトーチバーナー',
|
||||
es='Soplete de ensueño',
|
||||
rarity='VeryRare',
|
||||
item_id=110426,
|
||||
item_group=1100,
|
||||
dungeon_id=1116,
|
||||
)
|
317
tasks/planner/keywords/item_calyx.py
Normal file
@ -0,0 +1,317 @@
|
||||
from .classes import ItemCalyx
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Extinguished_Core = ItemCalyx(
|
||||
id=1,
|
||||
name='Extinguished_Core',
|
||||
cn='熄灭原核',
|
||||
cht='熄滅原核',
|
||||
en='Extinguished Core',
|
||||
jp='消滅した原核',
|
||||
es='Núcleo apagado',
|
||||
rarity='NotNormal',
|
||||
item_id=111001,
|
||||
item_group=1401,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Glimmering_Core = ItemCalyx(
|
||||
id=2,
|
||||
name='Glimmering_Core',
|
||||
cn='微光原核',
|
||||
cht='微光原核',
|
||||
en='Glimmering Core',
|
||||
jp='微かに光る原核',
|
||||
es='Núcleo reluciente',
|
||||
rarity='Rare',
|
||||
item_id=111002,
|
||||
item_group=1401,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Squirming_Core = ItemCalyx(
|
||||
id=3,
|
||||
name='Squirming_Core',
|
||||
cn='蠢动原核',
|
||||
cht='蠢動原核',
|
||||
en='Squirming Core',
|
||||
jp='脈動する原核',
|
||||
es='Núcleo serpenteante',
|
||||
rarity='VeryRare',
|
||||
item_id=111003,
|
||||
item_group=1401,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Thief_Instinct = ItemCalyx(
|
||||
id=4,
|
||||
name='Thief_Instinct',
|
||||
cn='掠夺的本能',
|
||||
cht='掠奪的本能',
|
||||
en="Thief's Instinct",
|
||||
jp='略奪の本能',
|
||||
es='Instinto del ladrón',
|
||||
rarity='NotNormal',
|
||||
item_id=111011,
|
||||
item_group=1402,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Usurper_Scheme = ItemCalyx(
|
||||
id=5,
|
||||
name='Usurper_Scheme',
|
||||
cn='篡改的野心',
|
||||
cht='篡改的野心',
|
||||
en="Usurper's Scheme",
|
||||
jp='改ざんの野心',
|
||||
es='Ambición distorsionada',
|
||||
rarity='Rare',
|
||||
item_id=111012,
|
||||
item_group=1402,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Conqueror_Will = ItemCalyx(
|
||||
id=6,
|
||||
name='Conqueror_Will',
|
||||
cn='践踏的意志',
|
||||
cht='踐踏的意志',
|
||||
en="Conqueror's Will",
|
||||
jp='踏みにじる意志',
|
||||
es='Voluntad de conquista',
|
||||
rarity='VeryRare',
|
||||
item_id=111013,
|
||||
item_group=1402,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Silvermane_Badge = ItemCalyx(
|
||||
id=7,
|
||||
name='Silvermane_Badge',
|
||||
cn='铁卫扣饰',
|
||||
cht='鐵衛扣飾',
|
||||
en='Silvermane Badge',
|
||||
jp='シルバーメインの釦',
|
||||
es='Pin del guardia',
|
||||
rarity='NotNormal',
|
||||
item_id=112001,
|
||||
item_group=1403,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Silvermane_Insignia = ItemCalyx(
|
||||
id=8,
|
||||
name='Silvermane_Insignia',
|
||||
cn='铁卫军徽',
|
||||
cht='鐵衛軍徽',
|
||||
en='Silvermane Insignia',
|
||||
jp='シルバーメインの記章',
|
||||
es='Insignia del guardia',
|
||||
rarity='Rare',
|
||||
item_id=112002,
|
||||
item_group=1403,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Silvermane_Medal = ItemCalyx(
|
||||
id=9,
|
||||
name='Silvermane_Medal',
|
||||
cn='铁卫勋章',
|
||||
cht='鐵衛勳章',
|
||||
en='Silvermane Medal',
|
||||
jp='シルバーメインの勲章',
|
||||
es='Medalla del guardia',
|
||||
rarity='VeryRare',
|
||||
item_id=112003,
|
||||
item_group=1403,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Ancient_Part = ItemCalyx(
|
||||
id=10,
|
||||
name='Ancient_Part',
|
||||
cn='古代零件',
|
||||
cht='古代零件',
|
||||
en='Ancient Part',
|
||||
jp='古代パーツ',
|
||||
es='Componente antiguo',
|
||||
rarity='NotNormal',
|
||||
item_id=112011,
|
||||
item_group=1404,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Ancient_Spindle = ItemCalyx(
|
||||
id=11,
|
||||
name='Ancient_Spindle',
|
||||
cn='古代转轴',
|
||||
cht='古代轉軸',
|
||||
en='Ancient Spindle',
|
||||
jp='古代シャフト',
|
||||
es='Eje antiguo',
|
||||
rarity='Rare',
|
||||
item_id=112012,
|
||||
item_group=1404,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Ancient_Engine = ItemCalyx(
|
||||
id=12,
|
||||
name='Ancient_Engine',
|
||||
cn='古代引擎',
|
||||
cht='古代引擎',
|
||||
en='Ancient Engine',
|
||||
jp='古代エンジン',
|
||||
es='Motor antiguo',
|
||||
rarity='VeryRare',
|
||||
item_id=112013,
|
||||
item_group=1404,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Immortal_Scionette = ItemCalyx(
|
||||
id=13,
|
||||
name='Immortal_Scionette',
|
||||
cn='永寿幼芽',
|
||||
cht='永壽幼芽',
|
||||
en='Immortal Scionette',
|
||||
jp='永寿の萌芽',
|
||||
es='Brote verde inmortal',
|
||||
rarity='NotNormal',
|
||||
item_id=113001,
|
||||
item_group=1405,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Immortal_Aeroblossom = ItemCalyx(
|
||||
id=14,
|
||||
name='Immortal_Aeroblossom',
|
||||
cn='永寿天华',
|
||||
cht='永壽天華',
|
||||
en='Immortal Aeroblossom',
|
||||
jp='永寿の天華',
|
||||
es='Flor etérea inmortal',
|
||||
rarity='Rare',
|
||||
item_id=113002,
|
||||
item_group=1405,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Immortal_Lumintwig = ItemCalyx(
|
||||
id=15,
|
||||
name='Immortal_Lumintwig',
|
||||
cn='永寿荣枝',
|
||||
cht='永壽榮枝',
|
||||
en='Immortal Lumintwig',
|
||||
jp='永寿の栄枝',
|
||||
es='Rama gloriosa inmortal',
|
||||
rarity='VeryRare',
|
||||
item_id=113003,
|
||||
item_group=1405,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Artifex_Module = ItemCalyx(
|
||||
id=16,
|
||||
name='Artifex_Module',
|
||||
cn='工造机杼',
|
||||
cht='工造機杼',
|
||||
en="Artifex's Module",
|
||||
jp='工造機関',
|
||||
es='Componente artificial mecánico',
|
||||
rarity='NotNormal',
|
||||
item_id=113011,
|
||||
item_group=1406,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Artifex_Cogwheel = ItemCalyx(
|
||||
id=17,
|
||||
name='Artifex_Cogwheel',
|
||||
cn='工造迴轮',
|
||||
cht='工造迴輪',
|
||||
en="Artifex's Cogwheel",
|
||||
jp='工造迴輪',
|
||||
es='Engranaje cilíndrico mecánico',
|
||||
rarity='Rare',
|
||||
item_id=113012,
|
||||
item_group=1406,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Artifex_Gyreheart = ItemCalyx(
|
||||
id=18,
|
||||
name='Artifex_Gyreheart',
|
||||
cn='工造浑心',
|
||||
cht='工造渾心',
|
||||
en="Artifex's Gyreheart",
|
||||
jp='工造渾心',
|
||||
es='Corazón armonioso mecánico',
|
||||
rarity='VeryRare',
|
||||
item_id=113013,
|
||||
item_group=1406,
|
||||
dungeon_id=1011,
|
||||
)
|
||||
Dream_Collection_Component = ItemCalyx(
|
||||
id=19,
|
||||
name='Dream_Collection_Component',
|
||||
cn='蓄梦元件',
|
||||
cht='蓄夢元件',
|
||||
en='Dream Collection Component',
|
||||
jp='ドリームコレクションパーツ',
|
||||
es='Componente del acumulador de sueños',
|
||||
rarity='NotNormal',
|
||||
item_id=114001,
|
||||
item_group=1407,
|
||||
dungeon_id=1014,
|
||||
)
|
||||
Dream_Flow_Valve = ItemCalyx(
|
||||
id=20,
|
||||
name='Dream_Flow_Valve',
|
||||
cn='流梦阀门',
|
||||
cht='流夢閥門',
|
||||
en='Dream Flow Valve',
|
||||
jp='ドリームフローバルブ',
|
||||
es='Válvula del flujo de sueños',
|
||||
rarity='Rare',
|
||||
item_id=114002,
|
||||
item_group=1407,
|
||||
dungeon_id=1014,
|
||||
)
|
||||
Dream_Making_Engine = ItemCalyx(
|
||||
id=21,
|
||||
name='Dream_Making_Engine',
|
||||
cn='造梦马达',
|
||||
cht='造夢馬達',
|
||||
en='Dream Making Engine',
|
||||
jp='ドリームメイキングモーター',
|
||||
es='Motor creasueños',
|
||||
rarity='VeryRare',
|
||||
item_id=114003,
|
||||
item_group=1407,
|
||||
dungeon_id=1014,
|
||||
)
|
||||
Tatters_of_Thought = ItemCalyx(
|
||||
id=22,
|
||||
name='Tatters_of_Thought',
|
||||
cn='思绪末屑',
|
||||
cht='思緒末屑',
|
||||
en='Tatters of Thought',
|
||||
jp='思考の粉末',
|
||||
es='Jirones de pensamientos',
|
||||
rarity='NotNormal',
|
||||
item_id=114011,
|
||||
item_group=1408,
|
||||
dungeon_id=1014,
|
||||
)
|
||||
Fragments_of_Impression = ItemCalyx(
|
||||
id=23,
|
||||
name='Fragments_of_Impression',
|
||||
cn='印象残晶',
|
||||
cht='印象殘晶',
|
||||
en='Fragments of Impression',
|
||||
jp='印象の残晶',
|
||||
es='Fragmento de impresiones',
|
||||
rarity='Rare',
|
||||
item_id=114012,
|
||||
item_group=1408,
|
||||
dungeon_id=1014,
|
||||
)
|
||||
Shards_of_Desires = ItemCalyx(
|
||||
id=24,
|
||||
name='Shards_of_Desires',
|
||||
cn='欲念碎镜',
|
||||
cht='欲念碎鏡',
|
||||
en='Shards of Desires',
|
||||
jp='砕けた欲望の鏡',
|
||||
es='Fragmento de deseos',
|
||||
rarity='VeryRare',
|
||||
item_id=114013,
|
||||
item_group=1408,
|
||||
dungeon_id=1014,
|
||||
)
|
31
tasks/planner/keywords/item_currency.py
Normal file
@ -0,0 +1,31 @@
|
||||
from .classes import ItemCurrency
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Credit = ItemCurrency(
|
||||
id=1,
|
||||
name='Credit',
|
||||
cn='信用点',
|
||||
cht='信用點',
|
||||
en='Credit',
|
||||
jp='信用ポイント',
|
||||
es='Crédito',
|
||||
rarity='Rare',
|
||||
item_id=2,
|
||||
item_group=0,
|
||||
dungeon_id=-1,
|
||||
)
|
||||
Trailblaze_EXP = ItemCurrency(
|
||||
id=2,
|
||||
name='Trailblaze_EXP',
|
||||
cn='里程',
|
||||
cht='里程',
|
||||
en='Trailblaze EXP',
|
||||
jp='マイレージ',
|
||||
es='EXP trazacaminos',
|
||||
rarity='Rare',
|
||||
item_id=22,
|
||||
item_group=0,
|
||||
dungeon_id=-1,
|
||||
)
|
122
tasks/planner/keywords/item_exp.py
Normal file
@ -0,0 +1,122 @@
|
||||
from .classes import ItemExp
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Travel_Encounters = ItemExp(
|
||||
id=1,
|
||||
name='Travel_Encounters',
|
||||
cn='旅情见闻',
|
||||
cht='旅情見聞',
|
||||
en='Travel Encounters',
|
||||
jp='旅の見聞',
|
||||
es='Noticias del viaje',
|
||||
rarity='NotNormal',
|
||||
item_id=211,
|
||||
item_group=1010,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Adventure_Log = ItemExp(
|
||||
id=2,
|
||||
name='Adventure_Log',
|
||||
cn='冒险记录',
|
||||
cht='冒險紀錄',
|
||||
en='Adventure Log',
|
||||
jp='冒険記録',
|
||||
es='Registro de aventuras',
|
||||
rarity='Rare',
|
||||
item_id=212,
|
||||
item_group=1010,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Traveler_Guide = ItemExp(
|
||||
id=3,
|
||||
name='Traveler_Guide',
|
||||
cn='漫游指南',
|
||||
cht='漫遊指南',
|
||||
en="Traveler's Guide",
|
||||
jp='漫遊指南',
|
||||
es='Guía del espíritu viajero',
|
||||
rarity='VeryRare',
|
||||
item_id=213,
|
||||
item_group=1010,
|
||||
dungeon_id=1001,
|
||||
)
|
||||
Sparse_Aether = ItemExp(
|
||||
id=4,
|
||||
name='Sparse_Aether',
|
||||
cn='稀薄以太',
|
||||
cht='稀薄乙太',
|
||||
en='Sparse Aether',
|
||||
jp='希薄なエーテル',
|
||||
es='Éter disperso',
|
||||
rarity='NotNormal',
|
||||
item_id=221,
|
||||
item_group=1020,
|
||||
dungeon_id=1002,
|
||||
)
|
||||
Condensed_Aether = ItemExp(
|
||||
id=5,
|
||||
name='Condensed_Aether',
|
||||
cn='凝缩以太',
|
||||
cht='凝縮乙太',
|
||||
en='Condensed Aether',
|
||||
jp='濃縮エーテル',
|
||||
es='Éter condensado',
|
||||
rarity='Rare',
|
||||
item_id=222,
|
||||
item_group=1020,
|
||||
dungeon_id=1002,
|
||||
)
|
||||
Refined_Aether = ItemExp(
|
||||
id=6,
|
||||
name='Refined_Aether',
|
||||
cn='提纯以太',
|
||||
cht='精煉乙太',
|
||||
en='Refined Aether',
|
||||
jp='精製エーテル',
|
||||
es='Éter refinado',
|
||||
rarity='VeryRare',
|
||||
item_id=223,
|
||||
item_group=1020,
|
||||
dungeon_id=1002,
|
||||
)
|
||||
Lost_Lightdust = ItemExp(
|
||||
id=7,
|
||||
name='Lost_Lightdust',
|
||||
cn='遗失光尘',
|
||||
cht='遺失光塵',
|
||||
en='Lost Lightdust',
|
||||
jp='遺失光塵',
|
||||
es='Polvo luminoso perdido',
|
||||
rarity='NotNormal',
|
||||
item_id=231,
|
||||
item_group=1030,
|
||||
dungeon_id=-1,
|
||||
)
|
||||
Lost_Gold_Fragment = ItemExp(
|
||||
id=8,
|
||||
name='Lost_Gold_Fragment',
|
||||
cn='遗失碎金',
|
||||
cht='遺失碎金',
|
||||
en='Lost Gold Fragment',
|
||||
jp='遺失砕金',
|
||||
es='Fragmento dorado perdido',
|
||||
rarity='Rare',
|
||||
item_id=232,
|
||||
item_group=1030,
|
||||
dungeon_id=-1,
|
||||
)
|
||||
Lost_Crystal = ItemExp(
|
||||
id=9,
|
||||
name='Lost_Crystal',
|
||||
cn='遗失晶块',
|
||||
cht='遺失晶塊',
|
||||
en='Lost Crystal',
|
||||
jp='遺失晶塊',
|
||||
es='Cristal perdido',
|
||||
rarity='VeryRare',
|
||||
item_id=233,
|
||||
item_group=1030,
|
||||
dungeon_id=-1,
|
||||
)
|
512
tasks/planner/keywords/item_trace.py
Normal file
@ -0,0 +1,512 @@
|
||||
from .classes import ItemTrace
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Shattered_Blade = ItemTrace(
|
||||
id=1,
|
||||
name='Shattered_Blade',
|
||||
cn='破碎残刃',
|
||||
cht='破碎殘刃',
|
||||
en='Shattered Blade',
|
||||
jp='破砕の刃切',
|
||||
es='Espada rota',
|
||||
rarity='NotNormal',
|
||||
item_id=110111,
|
||||
item_group=1201,
|
||||
dungeon_id=1004,
|
||||
)
|
||||
Lifeless_Blade = ItemTrace(
|
||||
id=2,
|
||||
name='Lifeless_Blade',
|
||||
cn='无生残刃',
|
||||
cht='無生殘刃',
|
||||
en='Lifeless Blade',
|
||||
jp='無生の刃切',
|
||||
es='Espada inerte',
|
||||
rarity='Rare',
|
||||
item_id=110112,
|
||||
item_group=1201,
|
||||
dungeon_id=1004,
|
||||
)
|
||||
Worldbreaker_Blade = ItemTrace(
|
||||
id=3,
|
||||
name='Worldbreaker_Blade',
|
||||
cn='净世残刃',
|
||||
cht='淨世殘刃',
|
||||
en='Worldbreaker Blade',
|
||||
jp='浄世の刃切',
|
||||
es='Espada rompemundos',
|
||||
rarity='VeryRare',
|
||||
item_id=110113,
|
||||
item_group=1201,
|
||||
dungeon_id=1004,
|
||||
)
|
||||
Arrow_of_the_Beast_Hunter = ItemTrace(
|
||||
id=4,
|
||||
name='Arrow_of_the_Beast_Hunter',
|
||||
cn='猎兽之矢',
|
||||
cht='獵獸之矢',
|
||||
en='Arrow of the Beast Hunter',
|
||||
jp='狩獣の矢',
|
||||
es='Flecha del cazabestias',
|
||||
rarity='NotNormal',
|
||||
item_id=110121,
|
||||
item_group=1202,
|
||||
dungeon_id=1006,
|
||||
)
|
||||
Arrow_of_the_Demon_Slayer = ItemTrace(
|
||||
id=5,
|
||||
name='Arrow_of_the_Demon_Slayer',
|
||||
cn='屠魔之矢',
|
||||
cht='屠魔之矢',
|
||||
en='Arrow of the Demon Slayer',
|
||||
jp='屠魔の矢',
|
||||
es='Flecha del matademonios',
|
||||
rarity='Rare',
|
||||
item_id=110122,
|
||||
item_group=1202,
|
||||
dungeon_id=1006,
|
||||
)
|
||||
Arrow_of_the_Starchaser = ItemTrace(
|
||||
id=6,
|
||||
name='Arrow_of_the_Starchaser',
|
||||
cn='逐星之矢',
|
||||
cht='逐星之矢',
|
||||
en='Arrow of the Starchaser',
|
||||
jp='逐星の矢',
|
||||
es='Flecha del persigueestrellas',
|
||||
rarity='VeryRare',
|
||||
item_id=110123,
|
||||
item_group=1202,
|
||||
dungeon_id=1006,
|
||||
)
|
||||
Key_of_Inspiration = ItemTrace(
|
||||
id=7,
|
||||
name='Key_of_Inspiration',
|
||||
cn='灵感之钥',
|
||||
cht='靈感之鑰',
|
||||
en='Key of Inspiration',
|
||||
jp='着想のカギ',
|
||||
es='Llave de la inspiración',
|
||||
rarity='NotNormal',
|
||||
item_id=110131,
|
||||
item_group=1203,
|
||||
dungeon_id=1008,
|
||||
)
|
||||
Key_of_Knowledge = ItemTrace(
|
||||
id=8,
|
||||
name='Key_of_Knowledge',
|
||||
cn='启迪之钥',
|
||||
cht='啟迪之鑰',
|
||||
en='Key of Knowledge',
|
||||
jp='啓発のカギ',
|
||||
es='Llave del conocimiento',
|
||||
rarity='Rare',
|
||||
item_id=110132,
|
||||
item_group=1203,
|
||||
dungeon_id=1008,
|
||||
)
|
||||
Key_of_Wisdom = ItemTrace(
|
||||
id=9,
|
||||
name='Key_of_Wisdom',
|
||||
cn='智识之钥',
|
||||
cht='智識之鑰',
|
||||
en='Key of Wisdom',
|
||||
jp='叡智のカギ',
|
||||
es='Llave de la sabiduría',
|
||||
rarity='VeryRare',
|
||||
item_id=110133,
|
||||
item_group=1203,
|
||||
dungeon_id=1008,
|
||||
)
|
||||
Endurance_of_Bronze = ItemTrace(
|
||||
id=10,
|
||||
name='Endurance_of_Bronze',
|
||||
cn='青铜的执着',
|
||||
cht='青銅的執著',
|
||||
en='Endurance of Bronze',
|
||||
jp='青銅の執着',
|
||||
es='Persistencia del bronce',
|
||||
rarity='NotNormal',
|
||||
item_id=110141,
|
||||
item_group=1204,
|
||||
dungeon_id=1005,
|
||||
)
|
||||
Oath_of_Steel = ItemTrace(
|
||||
id=11,
|
||||
name='Oath_of_Steel',
|
||||
cn='寒铁的誓言',
|
||||
cht='寒鐵的誓言',
|
||||
en='Oath of Steel',
|
||||
jp='寒鉄の誓い',
|
||||
es='Juramento de acero',
|
||||
rarity='Rare',
|
||||
item_id=110142,
|
||||
item_group=1204,
|
||||
dungeon_id=1005,
|
||||
)
|
||||
Safeguard_of_Amber = ItemTrace(
|
||||
id=12,
|
||||
name='Safeguard_of_Amber',
|
||||
cn='琥珀的坚守',
|
||||
cht='琥珀的堅守',
|
||||
en='Safeguard of Amber',
|
||||
jp='琥珀の堅守',
|
||||
es='Custodia de ámbar',
|
||||
rarity='VeryRare',
|
||||
item_id=110143,
|
||||
item_group=1204,
|
||||
dungeon_id=1005,
|
||||
)
|
||||
Obsidian_of_Dread = ItemTrace(
|
||||
id=13,
|
||||
name='Obsidian_of_Dread',
|
||||
cn='黯淡黑曜',
|
||||
cht='黯淡黑曜',
|
||||
en='Obsidian of Dread',
|
||||
jp='黯淡な黒曜',
|
||||
es='Obsidiana lúgubre',
|
||||
rarity='NotNormal',
|
||||
item_id=110151,
|
||||
item_group=1205,
|
||||
dungeon_id=1010,
|
||||
)
|
||||
Obsidian_of_Desolation = ItemTrace(
|
||||
id=14,
|
||||
name='Obsidian_of_Desolation',
|
||||
cn='虚空黑曜',
|
||||
cht='虛空黑曜',
|
||||
en='Obsidian of Desolation',
|
||||
jp='虚空の黒曜',
|
||||
es='Obsidiana del vacío',
|
||||
rarity='Rare',
|
||||
item_id=110152,
|
||||
item_group=1205,
|
||||
dungeon_id=1010,
|
||||
)
|
||||
Obsidian_of_Obsession = ItemTrace(
|
||||
id=15,
|
||||
name='Obsidian_of_Obsession',
|
||||
cn='沉沦黑曜',
|
||||
cht='沉淪黑曜',
|
||||
en='Obsidian of Obsession',
|
||||
jp='沈淪せし黒曜',
|
||||
es='Obsidiana de la obsesión',
|
||||
rarity='VeryRare',
|
||||
item_id=110153,
|
||||
item_group=1205,
|
||||
dungeon_id=1010,
|
||||
)
|
||||
Harmonic_Tune = ItemTrace(
|
||||
id=16,
|
||||
name='Harmonic_Tune',
|
||||
cn='谐乐小调',
|
||||
cht='諧樂小調',
|
||||
en='Harmonic Tune',
|
||||
jp='調和のハーモニー',
|
||||
es='Melodía armónica',
|
||||
rarity='NotNormal',
|
||||
item_id=110161,
|
||||
item_group=1206,
|
||||
dungeon_id=1009,
|
||||
)
|
||||
Ancestral_Hymn = ItemTrace(
|
||||
id=17,
|
||||
name='Ancestral_Hymn',
|
||||
cn='家族颂歌',
|
||||
cht='家族頌歌',
|
||||
en='Ancestral Hymn',
|
||||
jp='ファミリー賛歌',
|
||||
es='Himno del acervo',
|
||||
rarity='Rare',
|
||||
item_id=110162,
|
||||
item_group=1206,
|
||||
dungeon_id=1009,
|
||||
)
|
||||
Stellaris_Symphony = ItemTrace(
|
||||
id=18,
|
||||
name='Stellaris_Symphony',
|
||||
cn='群星乐章',
|
||||
cht='群星樂章',
|
||||
en='Stellaris Symphony',
|
||||
jp='群星の楽章',
|
||||
es='Opus Stellaris',
|
||||
rarity='VeryRare',
|
||||
item_id=110163,
|
||||
item_group=1206,
|
||||
dungeon_id=1009,
|
||||
)
|
||||
Seed_of_Abundance = ItemTrace(
|
||||
id=19,
|
||||
name='Seed_of_Abundance',
|
||||
cn='丰饶之种',
|
||||
cht='豐饒之種',
|
||||
en='Seed of Abundance',
|
||||
jp='豊穣の種',
|
||||
es='Semilla de la abundancia',
|
||||
rarity='NotNormal',
|
||||
item_id=110171,
|
||||
item_group=1207,
|
||||
dungeon_id=1007,
|
||||
)
|
||||
Sprout_of_Life = ItemTrace(
|
||||
id=20,
|
||||
name='Sprout_of_Life',
|
||||
cn='生命之芽',
|
||||
cht='生命之芽',
|
||||
en='Sprout of Life',
|
||||
jp='生命の芽',
|
||||
es='Brote de la vida',
|
||||
rarity='Rare',
|
||||
item_id=110172,
|
||||
item_group=1207,
|
||||
dungeon_id=1007,
|
||||
)
|
||||
Flower_of_Eternity = ItemTrace(
|
||||
id=21,
|
||||
name='Flower_of_Eternity',
|
||||
cn='永恒之花',
|
||||
cht='永恆之花',
|
||||
en='Flower of Eternity',
|
||||
jp='永久の花',
|
||||
es='Flor de la eternidad',
|
||||
rarity='VeryRare',
|
||||
item_id=110173,
|
||||
item_group=1207,
|
||||
dungeon_id=1007,
|
||||
)
|
||||
Borisin_Teeth = ItemTrace(
|
||||
id=22,
|
||||
name='Borisin_Teeth',
|
||||
cn='步离犬牙',
|
||||
cht='步離犬牙',
|
||||
en='Borisin Teeth',
|
||||
jp='歩離の犬牙',
|
||||
es='Canino de borisin',
|
||||
rarity='NotNormal',
|
||||
item_id=110181,
|
||||
item_group=1211,
|
||||
dungeon_id=1018,
|
||||
)
|
||||
Lupitoxin_Sawteeth = ItemTrace(
|
||||
id=23,
|
||||
name='Lupitoxin_Sawteeth',
|
||||
cn='狼毒锯牙',
|
||||
cht='狼毒鋸牙',
|
||||
en='Lupitoxin Sawteeth',
|
||||
jp='狼毒の牙',
|
||||
es='Diente serrado con lupitoxina',
|
||||
rarity='Rare',
|
||||
item_id=110182,
|
||||
item_group=1211,
|
||||
dungeon_id=1018,
|
||||
)
|
||||
Moon_Madness_Fang = ItemTrace(
|
||||
id=24,
|
||||
name='Moon_Madness_Fang',
|
||||
cn='月狂獠牙',
|
||||
cht='月狂獠牙',
|
||||
en='Moon Madness Fang',
|
||||
jp='月狂いの凶牙',
|
||||
es='Colmillo de la locura lunar',
|
||||
rarity='VeryRare',
|
||||
item_id=110183,
|
||||
item_group=1211,
|
||||
dungeon_id=1018,
|
||||
)
|
||||
Meteoric_Bullet = ItemTrace(
|
||||
id=25,
|
||||
name='Meteoric_Bullet',
|
||||
cn='陨铁弹丸',
|
||||
cht='隕鐵彈丸',
|
||||
en='Meteoric Bullet',
|
||||
jp='隕鉄の弾丸',
|
||||
es='Perdigón meteórico',
|
||||
rarity='NotNormal',
|
||||
item_id=110191,
|
||||
item_group=1212,
|
||||
dungeon_id=1022,
|
||||
)
|
||||
Destined_Expiration = ItemTrace(
|
||||
id=26,
|
||||
name='Destined_Expiration',
|
||||
cn='命定死因',
|
||||
cht='命定死因',
|
||||
en='Destined Expiration',
|
||||
jp='定められた死因',
|
||||
es='Deceso predestinado',
|
||||
rarity='Rare',
|
||||
item_id=110192,
|
||||
item_group=1212,
|
||||
dungeon_id=1022,
|
||||
)
|
||||
Countertemporal_Shot = ItemTrace(
|
||||
id=27,
|
||||
name='Countertemporal_Shot',
|
||||
cn='逆时一击',
|
||||
cht='逆時一擊',
|
||||
en='Countertemporal Shot',
|
||||
jp='時に抗う一撃',
|
||||
es='Disparo antitemporal',
|
||||
rarity='VeryRare',
|
||||
item_id=110193,
|
||||
item_group=1212,
|
||||
dungeon_id=1022,
|
||||
)
|
||||
Scattered_Stardust = ItemTrace(
|
||||
id=28,
|
||||
name='Scattered_Stardust',
|
||||
cn='散逸星砂',
|
||||
cht='散逸星砂',
|
||||
en='Scattered Stardust',
|
||||
jp='散らばった星の砂',
|
||||
es='Polvo estelar disperso',
|
||||
rarity='NotNormal',
|
||||
item_id=110211,
|
||||
item_group=1214,
|
||||
dungeon_id=1020,
|
||||
)
|
||||
Crystal_Meteorites = ItemTrace(
|
||||
id=29,
|
||||
name='Crystal_Meteorites',
|
||||
cn='流星棱晶',
|
||||
cht='流星稜晶',
|
||||
en='Crystal Meteorites',
|
||||
jp='流星プリズム',
|
||||
es='Meteoritos de cristal',
|
||||
rarity='Rare',
|
||||
item_id=110212,
|
||||
item_group=1214,
|
||||
dungeon_id=1020,
|
||||
)
|
||||
Divine_Amber = ItemTrace(
|
||||
id=30,
|
||||
name='Divine_Amber',
|
||||
cn='神体琥珀',
|
||||
cht='神體琥珀',
|
||||
en='Divine Amber',
|
||||
jp='聖なる琥珀',
|
||||
es='Ámbar divino',
|
||||
rarity='VeryRare',
|
||||
item_id=110213,
|
||||
item_group=1214,
|
||||
dungeon_id=1020,
|
||||
)
|
||||
Fiery_Spirit = ItemTrace(
|
||||
id=31,
|
||||
name='Fiery_Spirit',
|
||||
cn='炽情之灵',
|
||||
cht='熾情之靈',
|
||||
en='Fiery Spirit',
|
||||
jp='熾烈の霊',
|
||||
es='Espíritu ardiente',
|
||||
rarity='NotNormal',
|
||||
item_id=110221,
|
||||
item_group=1215,
|
||||
dungeon_id=1017,
|
||||
)
|
||||
Starfire_Essence = ItemTrace(
|
||||
id=32,
|
||||
name='Starfire_Essence',
|
||||
cn='星火之精',
|
||||
cht='星火之精',
|
||||
en='Starfire Essence',
|
||||
jp='星火の精',
|
||||
es='Esencia de fuego estelar',
|
||||
rarity='Rare',
|
||||
item_id=110222,
|
||||
item_group=1215,
|
||||
dungeon_id=1017,
|
||||
)
|
||||
Heaven_Incinerator = ItemTrace(
|
||||
id=33,
|
||||
name='Heaven_Incinerator',
|
||||
cn='焚天之魔',
|
||||
cht='焚天之魔',
|
||||
en='Heaven Incinerator',
|
||||
jp='焼天の魔',
|
||||
es='Incinerador divino',
|
||||
rarity='VeryRare',
|
||||
item_id=110223,
|
||||
item_group=1215,
|
||||
dungeon_id=1017,
|
||||
)
|
||||
Firmament_Note = ItemTrace(
|
||||
id=34,
|
||||
name='Firmament_Note',
|
||||
cn='云际音符',
|
||||
cht='雲際音符',
|
||||
en='Firmament Note',
|
||||
jp='雲端の音符',
|
||||
es='Nota del firmamento',
|
||||
rarity='NotNormal',
|
||||
item_id=110231,
|
||||
item_group=1216,
|
||||
dungeon_id=1019,
|
||||
)
|
||||
Celestial_Section = ItemTrace(
|
||||
id=35,
|
||||
name='Celestial_Section',
|
||||
cn='空际小节',
|
||||
cht='空際小節',
|
||||
en='Celestial Section',
|
||||
jp='空際の小節',
|
||||
es='Compás celestial',
|
||||
rarity='Rare',
|
||||
item_id=110232,
|
||||
item_group=1216,
|
||||
dungeon_id=1019,
|
||||
)
|
||||
Heavenly_Melody = ItemTrace(
|
||||
id=36,
|
||||
name='Heavenly_Melody',
|
||||
cn='天外乐章',
|
||||
cht='天外樂章',
|
||||
en='Heavenly Melody',
|
||||
jp='天外の楽章',
|
||||
es='Movimiento celestial',
|
||||
rarity='VeryRare',
|
||||
item_id=110233,
|
||||
item_group=1216,
|
||||
dungeon_id=1019,
|
||||
)
|
||||
Alien_Tree_Seed = ItemTrace(
|
||||
id=37,
|
||||
name='Alien_Tree_Seed',
|
||||
cn='异木种籽',
|
||||
cht='異木種籽',
|
||||
en='Alien Tree Seed',
|
||||
jp='珍木の種',
|
||||
es='Semilla del árbol extraño',
|
||||
rarity='NotNormal',
|
||||
item_id=110241,
|
||||
item_group=1217,
|
||||
dungeon_id=1021,
|
||||
)
|
||||
Nourishing_Honey = ItemTrace(
|
||||
id=38,
|
||||
name='Nourishing_Honey',
|
||||
cn='滋长花蜜',
|
||||
cht='滋長花蜜',
|
||||
en='Nourishing Honey',
|
||||
jp='育みの蜜',
|
||||
es='Miel nutricia',
|
||||
rarity='Rare',
|
||||
item_id=110242,
|
||||
item_group=1217,
|
||||
dungeon_id=1021,
|
||||
)
|
||||
Myriad_Fruit = ItemTrace(
|
||||
id=39,
|
||||
name='Myriad_Fruit',
|
||||
cn='万相果实',
|
||||
cht='萬相果實',
|
||||
en='Myriad Fruit',
|
||||
jp='森羅の果実',
|
||||
es='Fruta del sinfín',
|
||||
rarity='VeryRare',
|
||||
item_id=110243,
|
||||
item_group=1217,
|
||||
dungeon_id=1021,
|
||||
)
|
83
tasks/planner/keywords/item_weekly.py
Normal file
@ -0,0 +1,83 @@
|
||||
from .classes import ItemWeekly
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.keyword_extract ```
|
||||
|
||||
Tracks_of_Destiny = ItemWeekly(
|
||||
id=1,
|
||||
name='Tracks_of_Destiny',
|
||||
cn='命运的足迹',
|
||||
cht='命運的足跡',
|
||||
en='Tracks of Destiny',
|
||||
jp='運命の足跡',
|
||||
es='Huellas del destino',
|
||||
rarity='SuperRare',
|
||||
item_id=241,
|
||||
item_group=1300,
|
||||
dungeon_id=-1,
|
||||
)
|
||||
Destroyer_Final_Road = ItemWeekly(
|
||||
id=2,
|
||||
name='Destroyer_Final_Road',
|
||||
cn='毁灭者的末路',
|
||||
cht='毀滅者的末路',
|
||||
en="Destroyer's Final Road",
|
||||
jp='壊滅者の末路',
|
||||
es='Senda final del destructor',
|
||||
rarity='VeryRare',
|
||||
item_id=110501,
|
||||
item_group=1310,
|
||||
dungeon_id=1301,
|
||||
)
|
||||
Guardian_Lament = ItemWeekly(
|
||||
id=3,
|
||||
name='Guardian_Lament',
|
||||
cn='守护者的悲愿',
|
||||
cht='守護者的悲願',
|
||||
en="Guardian's Lament",
|
||||
jp='守護者の悲願',
|
||||
es='Lamento de la Guardiana',
|
||||
rarity='VeryRare',
|
||||
item_id=110502,
|
||||
item_group=1310,
|
||||
dungeon_id=1302,
|
||||
)
|
||||
Regret_of_Infinite_Ochema = ItemWeekly(
|
||||
id=4,
|
||||
name='Regret_of_Infinite_Ochema',
|
||||
cn='无穷假身的遗恨',
|
||||
cht='無窮假身的遺恨',
|
||||
en='Regret of Infinite Ochema',
|
||||
jp='無窮なる仮身の遺恨',
|
||||
es='Arrepentimiento del eterno vehículo del alma',
|
||||
rarity='VeryRare',
|
||||
item_id=110503,
|
||||
item_group=1310,
|
||||
dungeon_id=1303,
|
||||
)
|
||||
Past_Evils_of_the_Borehole_Planet_Disaster = ItemWeekly(
|
||||
id=5,
|
||||
name='Past_Evils_of_the_Borehole_Planet_Disaster',
|
||||
cn='蛀星孕灾的旧恶',
|
||||
cht='蛀星孕災的舊惡',
|
||||
en='Past Evils of the Borehole Planet Disaster',
|
||||
jp='星を蝕む古の悪',
|
||||
es='Agravios pasados de la catástrofe devoraplanetas',
|
||||
rarity='VeryRare',
|
||||
item_id=110504,
|
||||
item_group=1310,
|
||||
dungeon_id=1304,
|
||||
)
|
||||
Lost_Echo_of_the_Shared_Wish = ItemWeekly(
|
||||
id=6,
|
||||
name='Lost_Echo_of_the_Shared_Wish',
|
||||
cn='同愿的遗音',
|
||||
cht='同願的遺音',
|
||||
en='Lost Echo of the Shared Wish',
|
||||
jp='同願の遺音',
|
||||
es='Eco perdido del deseo compartido',
|
||||
rarity='VeryRare',
|
||||
item_id=110505,
|
||||
item_group=1310,
|
||||
dungeon_id=1305,
|
||||
)
|
510
tasks/planner/model.py
Normal file
@ -0,0 +1,510 @@
|
||||
import typing as t
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
|
||||
from pydantic import BaseModel, ValidationError, WrapValidator, field_validator, model_validator
|
||||
|
||||
from module.base.decorator import cached_property, del_cached_property
|
||||
from module.config.stored.classes import now
|
||||
from module.config.utils import DEFAULT_TIME
|
||||
from module.exception import ScriptError
|
||||
from module.logger import logger
|
||||
from tasks.base.ui import UI
|
||||
from tasks.dungeon.keywords import DungeonList
|
||||
from tasks.planner.keywords import ITEM_TYPES
|
||||
from tasks.planner.keywords.classes import ItemBase
|
||||
|
||||
|
||||
class PlannerResultRow(BaseModel):
|
||||
"""
|
||||
A row of data from planner result page
|
||||
"""
|
||||
item: ITEM_TYPES
|
||||
total: int
|
||||
synthesize: int
|
||||
demand: int
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.item == other.item
|
||||
|
||||
|
||||
class ObtainedAmmount(BaseModel):
|
||||
"""
|
||||
A row of data from DungeonObtain detection
|
||||
"""
|
||||
item: ITEM_TYPES
|
||||
value: int
|
||||
|
||||
|
||||
def _fallback_to_default_validator(
|
||||
get_default: t.Callable[[], t.Any],
|
||||
v: t.Any,
|
||||
next_: t.Callable[[t.Any], t.Any],
|
||||
) -> t.Any:
|
||||
try:
|
||||
return next_(v)
|
||||
except ValueError as e:
|
||||
logger.error(e)
|
||||
return get_default()
|
||||
|
||||
|
||||
class BaseModelWithFallback(BaseModel):
|
||||
"""
|
||||
Pydantic model that fallbacks to default on error
|
||||
https://github.com/pydantic/pydantic/discussions/8579
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def __pydantic_init_subclass__(cls, **kwargs: t.Any) -> None:
|
||||
for field in cls.model_fields.values():
|
||||
if not field.is_required():
|
||||
validator = WrapValidator(partial(_fallback_to_default_validator, field.get_default))
|
||||
field.metadata.append(validator)
|
||||
|
||||
cls.model_rebuild(force=True)
|
||||
|
||||
|
||||
class MultiValue(BaseModelWithFallback):
|
||||
green: int = 0
|
||||
blue: int = 0
|
||||
purple: int = 0
|
||||
|
||||
def add(self, other: "MultiValue"):
|
||||
self.green += other.green
|
||||
self.blue += other.blue
|
||||
self.purple += other.purple
|
||||
|
||||
def equivalent_green(self):
|
||||
return self.green + self.blue * 3 + self.purple * 9
|
||||
|
||||
|
||||
class StoredPlannerProxy(BaseModelWithFallback):
|
||||
item: ITEM_TYPES
|
||||
value: int | MultiValue = 0
|
||||
total: int | MultiValue = 0
|
||||
synthesize: int | MultiValue = 0
|
||||
progress: float = 0.
|
||||
time: datetime = DEFAULT_TIME
|
||||
|
||||
@field_validator('item', mode='before')
|
||||
def val_item(cls, v, info):
|
||||
if isinstance(v, str):
|
||||
v = ItemBase.find_name(v)
|
||||
return v
|
||||
|
||||
@model_validator(mode='after')
|
||||
def val_value(self):
|
||||
if self.item.has_group_base:
|
||||
if not isinstance(self.value, MultiValue):
|
||||
self.value = MultiValue()
|
||||
if not isinstance(self.total, MultiValue):
|
||||
self.total = MultiValue()
|
||||
if not isinstance(self.synthesize, MultiValue):
|
||||
self.synthesize = MultiValue()
|
||||
else:
|
||||
if not isinstance(self.value, int):
|
||||
self.value = 0
|
||||
if not isinstance(self.total, int):
|
||||
self.total = 0
|
||||
if not isinstance(self.synthesize, int):
|
||||
self.synthesize = 0
|
||||
return self
|
||||
|
||||
def update_synthesize(self):
|
||||
if self.item.has_group_base:
|
||||
green = self.value.green - self.total.green
|
||||
blue = self.value.blue - self.total.blue
|
||||
purple = self.value.purple - self.total.purple
|
||||
syn_blue = 0
|
||||
syn_purple = 0
|
||||
if green >= 3 and blue < 0:
|
||||
syn = min(green // 3, -blue)
|
||||
syn_blue += syn
|
||||
green -= syn * 3
|
||||
# blue += syn
|
||||
if blue >= 3 and purple < 0:
|
||||
syn = min(blue // 3, -purple)
|
||||
syn_purple += syn
|
||||
blue -= syn * 3
|
||||
purple += syn
|
||||
if green >= 9 and purple < 0:
|
||||
syn = min(green // 9, -purple)
|
||||
syn_purple += syn
|
||||
syn_blue += syn * 3
|
||||
green -= syn * 9
|
||||
# purple += syn
|
||||
self.synthesize.green = 0
|
||||
self.synthesize.blue = syn_blue
|
||||
self.synthesize.purple = syn_purple
|
||||
else:
|
||||
self.synthesize = 0
|
||||
|
||||
def revert_synthesize(self):
|
||||
if self.item.has_group_base:
|
||||
self.value.green += self.synthesize.blue * 3
|
||||
if self.synthesize.blue > 0:
|
||||
self.value.green += self.synthesize.purple * 9
|
||||
else:
|
||||
self.value.blue += self.synthesize.purple * 3
|
||||
|
||||
def is_approaching_total(self, wave_done: int = 0):
|
||||
"""
|
||||
Args:
|
||||
wave_done:
|
||||
|
||||
Returns:
|
||||
bool: True if the future value may >= total after next combat
|
||||
"""
|
||||
wave_done = max(wave_done, 0)
|
||||
# Items with a static drop rate will have `AVG * (wave_done + 1)
|
||||
if self.item.dungeon.is_Calyx_Golden_Treasures:
|
||||
return self.value + 24000 * (wave_done + 12) >= self.total
|
||||
if self.item.dungeon.is_Calyx_Golden_Memories:
|
||||
# purple, blue, green = 5, 1, 0
|
||||
value = self.value.equivalent_green()
|
||||
total = self.total.equivalent_green()
|
||||
return value + 48 * (wave_done + 12) >= total
|
||||
if self.item.dungeon.is_Calyx_Golden_Aether:
|
||||
# purple, blue, green = 1, 2, 2.5
|
||||
value = self.value.equivalent_green()
|
||||
total = self.total.equivalent_green()
|
||||
return value + 17.5 * (wave_done + 12) >= total
|
||||
if self.item.is_ItemAscension:
|
||||
return self.value + 3 * (wave_done + 1) >= self.total
|
||||
if self.item.is_ItemTrace:
|
||||
# purple, blue, green = 0.155, 1, 1.25
|
||||
value = self.value.equivalent_green()
|
||||
total = self.total.equivalent_green()
|
||||
return value + 5.645 * (wave_done + 12) >= total
|
||||
if self.item.is_ItemWeekly:
|
||||
return self.value + 3 * (wave_done + 1) >= self.total
|
||||
return False
|
||||
|
||||
def update_progress(self):
|
||||
if self.item.has_group_base:
|
||||
total = self.total.equivalent_green()
|
||||
green = min(self.value.green, self.total.green)
|
||||
blue = min(self.value.blue + self.synthesize.blue, self.total.blue)
|
||||
purple = min(self.value.purple + self.synthesize.purple, self.total.purple)
|
||||
value = green + blue * 3 + purple * 9
|
||||
progress = value / total * 100
|
||||
self.progress = round(min(max(progress, 0), 100), 2)
|
||||
else:
|
||||
progress = self.value / self.total * 100
|
||||
self.progress = round(min(max(progress, 0), 100), 2)
|
||||
|
||||
def update(self):
|
||||
self.update_synthesize()
|
||||
self.update_progress()
|
||||
self.time = now()
|
||||
|
||||
def load_value_total(self, item: ItemBase, value=None, total=None, synthesize=None):
|
||||
"""
|
||||
Update data from PlannerResultRow to self
|
||||
"""
|
||||
if self.item.has_group_base:
|
||||
if item.group_base != self.item:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but they are different items')
|
||||
else:
|
||||
if item != self.item:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but they are different items')
|
||||
if self.item.has_group_base:
|
||||
if not self.item.is_rarity_purple:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but self is not in rarity purple')
|
||||
if item.is_rarity_green:
|
||||
if value is not None:
|
||||
self.value.green = value
|
||||
if total is not None:
|
||||
self.total.green = total
|
||||
# Cannot synthesize green
|
||||
# if synthesize is not None:
|
||||
# self.synthesize.green = synthesize
|
||||
self.synthesize.green = 0
|
||||
elif item.is_rarity_blue:
|
||||
if value is not None:
|
||||
self.value.blue = value
|
||||
if total is not None:
|
||||
self.total.blue = total
|
||||
if synthesize is not None:
|
||||
self.synthesize.blue = synthesize
|
||||
elif item.is_rarity_purple:
|
||||
if value is not None:
|
||||
self.value.purple = value
|
||||
if total is not None:
|
||||
self.total.purple = total
|
||||
if synthesize is not None:
|
||||
self.synthesize.purple = synthesize
|
||||
else:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} in to {self} but item is in invalid rarity')
|
||||
else:
|
||||
# Cannot synthesize if item doesn't have multiple rarity
|
||||
self.synthesize = 0
|
||||
if value is not None:
|
||||
self.value = value
|
||||
if total is not None:
|
||||
self.total = total
|
||||
|
||||
def add_planner_result(self, row: "StoredPlannerProxy"):
|
||||
"""
|
||||
Add data from another StoredPlannerProxy to self
|
||||
"""
|
||||
item = row.item
|
||||
if self.item.has_group_base:
|
||||
if item.group_base != self.item:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but they are different items')
|
||||
else:
|
||||
if item != self.item:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but they are different items')
|
||||
if self.item.has_group_base:
|
||||
if not self.item.is_rarity_purple:
|
||||
raise ScriptError(
|
||||
f'load_value_total: Trying to load {item} into {self} but self is not in rarity purple')
|
||||
# Add `total` only
|
||||
# `synthesize` will be updated later
|
||||
# `value` remains unchanged since you still having that many items
|
||||
self.total.add(row.total)
|
||||
else:
|
||||
self.value += row.value
|
||||
self.total += row.total
|
||||
self.synthesize += row.synthesize
|
||||
|
||||
def need_farm(self):
|
||||
return self.progress < 100
|
||||
|
||||
def need_synthesize(self):
|
||||
if self.item.has_group_base:
|
||||
return self.synthesize.green > 0 or self.synthesize.blue > 0 or self.synthesize.purple > 0
|
||||
else:
|
||||
return self.synthesize > 0
|
||||
|
||||
def load_planner_result(self, row: PlannerResultRow):
|
||||
"""
|
||||
Update data from PlannerResultRow to self
|
||||
"""
|
||||
# Approximate value, accurate value can be update in DungeonObtain
|
||||
value = row.total - row.synthesize - row.demand
|
||||
self.load_value_total(item=row.item, value=value, total=row.total, synthesize=row.synthesize)
|
||||
|
||||
def load_item_amount(self, row: ObtainedAmmount):
|
||||
"""
|
||||
Update data from ObtainedAmmount to self
|
||||
"""
|
||||
value = row.value
|
||||
self.load_value_total(item=row.item, value=value)
|
||||
|
||||
|
||||
class PlannerProgressParser:
|
||||
def __init__(self):
|
||||
self.rows: dict[str, StoredPlannerProxy] = {}
|
||||
|
||||
def from_planner_results(self, results: list[PlannerResultRow]):
|
||||
self.rows = {}
|
||||
# Create objects of base items first
|
||||
# them load value and total
|
||||
for row in results:
|
||||
base = row.item.group_base
|
||||
if base.name not in self.rows:
|
||||
try:
|
||||
obj = StoredPlannerProxy(item=base)
|
||||
except ScriptError as e:
|
||||
logger.error(e)
|
||||
continue
|
||||
self.rows[base.name] = obj
|
||||
else:
|
||||
obj = self.rows[base.name]
|
||||
obj.load_planner_result(row)
|
||||
|
||||
rows = {}
|
||||
for name, row in self.rows.items():
|
||||
row.revert_synthesize()
|
||||
row.update()
|
||||
if row.need_farm() or row.need_synthesize():
|
||||
rows[name] = row
|
||||
self.rows = rows
|
||||
return self
|
||||
|
||||
def load_obtained_amount(self, results: list[ObtainedAmmount]):
|
||||
for row in results:
|
||||
base = row.item.group_base
|
||||
try:
|
||||
obj = self.rows[base.name]
|
||||
except KeyError:
|
||||
logger.warning(
|
||||
f'load_obtained_amount() drops {row} because no need to farm')
|
||||
continue
|
||||
obj.load_item_amount(row)
|
||||
obj.update()
|
||||
return self
|
||||
|
||||
def from_config(self, data):
|
||||
self.rows = {}
|
||||
for row in data.values():
|
||||
if not row:
|
||||
continue
|
||||
try:
|
||||
row = StoredPlannerProxy(**row)
|
||||
except (ScriptError, ValidationError) as e:
|
||||
logger.error(e)
|
||||
continue
|
||||
if not row.item.is_group_base:
|
||||
logger.error(f'from_config: item is not group base {row}')
|
||||
continue
|
||||
row.update_synthesize()
|
||||
row.update_progress()
|
||||
self.rows[row.item.name] = row
|
||||
return self
|
||||
|
||||
def add_planner_result(self, planner: "PlannerProgressParser"):
|
||||
"""
|
||||
Add another planner result to self
|
||||
"""
|
||||
for name, row in planner.rows.items():
|
||||
if name in self.rows:
|
||||
self_row = self.rows[name]
|
||||
self_row.add_planner_result(row)
|
||||
else:
|
||||
self.rows[name] = row
|
||||
|
||||
for row in self.rows.values():
|
||||
row.update()
|
||||
|
||||
def to_config(self) -> dict:
|
||||
data = {}
|
||||
for row in self.rows.values():
|
||||
name = f'Item_{row.item.name}'
|
||||
dic = row.model_dump()
|
||||
dic['item'] = row.item.name
|
||||
data[name] = dic
|
||||
return data
|
||||
|
||||
def iter_row_to_farm(self, need_farm=True) -> t.Iterable[StoredPlannerProxy]:
|
||||
"""
|
||||
Args:
|
||||
need_farm: True if filter rows that need farm
|
||||
|
||||
Yields:
|
||||
|
||||
"""
|
||||
if need_farm:
|
||||
rows = [row for row in self.rows.values() if row.need_farm()]
|
||||
else:
|
||||
rows = self.rows.values()
|
||||
|
||||
for row in rows:
|
||||
if row.item.is_ItemWeekly:
|
||||
yield row
|
||||
for row in rows:
|
||||
if row.item.is_ItemAscension:
|
||||
yield row
|
||||
for row in rows:
|
||||
if row.item.is_ItemTrace:
|
||||
yield row
|
||||
for row in rows:
|
||||
if row.item.is_ItemExp:
|
||||
yield row
|
||||
for row in rows:
|
||||
if row.item.is_ItemCurrency:
|
||||
yield row
|
||||
|
||||
def get_dungeon(self, double_calyx=False) -> DungeonList | None:
|
||||
"""
|
||||
Get dungeon to farm, or None if planner finished or the remaining items cannot be farmed
|
||||
"""
|
||||
for row in self.iter_row_to_farm():
|
||||
item = row.item
|
||||
if item.is_ItemWeekly:
|
||||
continue
|
||||
dungeon = item.dungeon
|
||||
if dungeon is None:
|
||||
logger.error(f'Item {item} has nowhere to be farmed')
|
||||
continue
|
||||
if double_calyx:
|
||||
if dungeon.is_Calyx:
|
||||
logger.info(f'Planner farm (double_calyx): {dungeon}')
|
||||
return dungeon
|
||||
else:
|
||||
logger.info(f'Planner farm: {dungeon}')
|
||||
return dungeon
|
||||
|
||||
logger.info('Planner farm empty')
|
||||
return None
|
||||
|
||||
def get_weekly(self) -> DungeonList | None:
|
||||
for row in self.iter_row_to_farm():
|
||||
item = row.item
|
||||
if not item.is_ItemWeekly:
|
||||
continue
|
||||
dungeon = item.dungeon
|
||||
if dungeon is None:
|
||||
logger.error(f'Item {item} has nowhere to be farmed')
|
||||
continue
|
||||
logger.info(f'Planner weekly farm: {dungeon}')
|
||||
return dungeon
|
||||
|
||||
logger.info('Planner weekly farm empty')
|
||||
return None
|
||||
|
||||
def row_come_from_dungeon(self, dungeon: DungeonList | None) -> StoredPlannerProxy | None:
|
||||
"""
|
||||
If any items in planner is able to be farmed from given dungeon
|
||||
"""
|
||||
if dungeon is None:
|
||||
return None
|
||||
for row in self.iter_row_to_farm(need_farm=False):
|
||||
if row.item.dungeon == dungeon:
|
||||
logger.info(f'Planner {row} come from {dungeon}')
|
||||
return row
|
||||
return None
|
||||
|
||||
|
||||
class PlannerMixin(UI):
|
||||
def planner_write_results(self, results: list[PlannerResultRow]):
|
||||
"""
|
||||
Write planner detection results info user config
|
||||
"""
|
||||
add = self.config.PlannerScan_ResultAdd
|
||||
logger.attr('ResultAdd', add)
|
||||
|
||||
planner = PlannerProgressParser().from_planner_results(results)
|
||||
if add:
|
||||
planner.add_planner_result(self.planner)
|
||||
|
||||
self.planner_write(planner)
|
||||
|
||||
@cached_property
|
||||
def planner(self) -> PlannerProgressParser:
|
||||
data = self.config.cross_get('Dungeon.Planner', default={})
|
||||
model = PlannerProgressParser().from_config(data)
|
||||
logger.hr('Planner')
|
||||
for row in model.rows.values():
|
||||
logger.info(row)
|
||||
return model
|
||||
|
||||
def planner_write(self, planner=None):
|
||||
"""
|
||||
Write planner into user config, delete planner object
|
||||
"""
|
||||
if planner is None:
|
||||
planner = self.planner
|
||||
|
||||
data = planner.to_config()
|
||||
|
||||
with self.config.multi_set():
|
||||
# Set value
|
||||
for key, value in data.items():
|
||||
self.config.cross_set(f'Dungeon.Planner.{key}', value)
|
||||
# Remove other value
|
||||
remove = []
|
||||
for key, value in self.config.cross_get('Dungeon.Planner', default={}).items():
|
||||
if value != {} and key not in data:
|
||||
remove.append(key)
|
||||
for key in remove:
|
||||
self.config.cross_set(f'Dungeon.Planner.{key}', {})
|
||||
|
||||
del_cached_property(self, 'planner')
|
228
tasks/planner/scan.py
Normal file
@ -0,0 +1,228 @@
|
||||
import re
|
||||
|
||||
from pponnxcr.predict_system import BoxedResult
|
||||
|
||||
from module.base.utils import area_center, area_in_area
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Ocr, OcrWhiteLetterOnComplexBackground
|
||||
from module.ui.scroll import AdaptiveScroll
|
||||
from tasks.daily.synthesize import SynthesizeUI
|
||||
from tasks.planner.assets.assets_planner_result import *
|
||||
from tasks.planner.keywords import ITEM_CLASSES
|
||||
from tasks.planner.keywords.classes import ItemCurrency
|
||||
from tasks.planner.model import PlannerMixin, PlannerResultRow
|
||||
|
||||
CALCULATE_TITLE.load_search(RESULT_CHECK.search)
|
||||
MATERIAL_TITLE.load_search(RESULT_CHECK.search)
|
||||
DETAIL_TITLE.load_search(RESULT_CHECK.search)
|
||||
|
||||
|
||||
class OcrItemName(Ocr):
|
||||
def after_process(self, result):
|
||||
result = result.replace('念火之心', '忿火之心')
|
||||
result = re.sub('工造机$', '工造机杼', result)
|
||||
result = re.sub('工造迥?轮', '工造迴轮', result)
|
||||
result = re.sub('月狂[療撩]?牙', '月狂獠牙', result)
|
||||
# Error words on blank background
|
||||
result = re.sub('^[國東]', '', result)
|
||||
result = re.sub('時$', '', result)
|
||||
return result
|
||||
|
||||
|
||||
class OcrPlannerResult(OcrWhiteLetterOnComplexBackground, OcrItemName):
|
||||
min_box = (16, 20)
|
||||
|
||||
def __init__(self):
|
||||
# Planner currently CN only
|
||||
super().__init__(OCR_RESULT, lang='cn')
|
||||
self.limited_area = OCR_RESULT.area
|
||||
self.limit_y = 720
|
||||
|
||||
def _match_result(
|
||||
self,
|
||||
result: str,
|
||||
keyword_classes,
|
||||
lang: str = 'cn',
|
||||
ignore_punctuation=True,
|
||||
ignore_digit=True):
|
||||
return super()._match_result(
|
||||
result,
|
||||
keyword_classes,
|
||||
lang,
|
||||
ignore_punctuation,
|
||||
ignore_digit,
|
||||
)
|
||||
|
||||
def filter_detected(self, result: BoxedResult) -> bool:
|
||||
if not area_in_area(result.box, self.limited_area, threshold=0):
|
||||
return False
|
||||
if area_center(result.box)[1] > self.limit_y:
|
||||
return False
|
||||
return True
|
||||
|
||||
def detect_and_ocr(self, image, *args, **kwargs):
|
||||
# Remove rows below DETAIL_TITLE
|
||||
if DETAIL_TITLE.match_template(image):
|
||||
self.limit_y = DETAIL_TITLE.button[3]
|
||||
else:
|
||||
self.limit_y = 720
|
||||
return super().detect_and_ocr(image, *args, **kwargs)
|
||||
|
||||
def pre_process(self, image):
|
||||
# gray = rgb2gray(image)
|
||||
# from PIL import Image
|
||||
# Image.fromarray(gray).show()
|
||||
# image = cv2.merge([gray, gray, gray])
|
||||
return image
|
||||
|
||||
|
||||
class PlannerScan(SynthesizeUI, PlannerMixin):
|
||||
def is_in_planner_result(self):
|
||||
if self.appear(RESULT_CHECK):
|
||||
return True
|
||||
if self.appear(CALCULATE_TITLE):
|
||||
return True
|
||||
if self.appear(MATERIAL_TITLE):
|
||||
return True
|
||||
if self.appear(DETAIL_TITLE):
|
||||
return True
|
||||
return False
|
||||
|
||||
def parse_planner_result_page(self) -> list[PlannerResultRow]:
|
||||
"""
|
||||
Pages:
|
||||
in: planner result
|
||||
"""
|
||||
ocr = OcrPlannerResult()
|
||||
results = ocr.detect_and_ocr(self.device.image)
|
||||
|
||||
x_total = 842
|
||||
x_synthesize = 965
|
||||
x_demand = 1129
|
||||
|
||||
def x_match(result: BoxedResult, x):
|
||||
rx = area_center(result.box)[0]
|
||||
return x - 50 <= rx <= x + 50
|
||||
|
||||
def y_match(result: BoxedResult, y):
|
||||
rx = area_center(result.box)[1]
|
||||
return y - 15 <= rx <= y + 15
|
||||
|
||||
# Split columns
|
||||
list_item = [r for r in results
|
||||
if not r.ocr_text.isdigit() and ocr._match_result(r.ocr_text, keyword_classes=ITEM_CLASSES)]
|
||||
list_number = [r for r in results if r.ocr_text.isdigit()]
|
||||
list_total = [r for r in list_number if x_match(r, x_total)]
|
||||
list_synthesize = [r for r in list_number if x_match(r, x_synthesize)]
|
||||
list_demand = [r for r in list_number if x_match(r, x_demand)]
|
||||
|
||||
# Structure
|
||||
out: list[PlannerResultRow] = []
|
||||
for item in list_item:
|
||||
y_item = area_center(item.box)[1]
|
||||
total = -1
|
||||
for number in list_total:
|
||||
if y_match(number, y_item):
|
||||
total = int(number.ocr_text)
|
||||
break
|
||||
synthesize = 0
|
||||
for number in list_synthesize:
|
||||
if y_match(number, y_item):
|
||||
synthesize = int(number.ocr_text)
|
||||
break
|
||||
demand = 0
|
||||
for number in list_demand:
|
||||
if y_match(number, y_item):
|
||||
demand = int(number.ocr_text)
|
||||
break
|
||||
item = ocr._match_result(item.ocr_text, keyword_classes=ITEM_CLASSES)
|
||||
row = PlannerResultRow(
|
||||
item=item,
|
||||
total=total,
|
||||
synthesize=synthesize,
|
||||
demand=demand
|
||||
)
|
||||
# Validate item
|
||||
# print(row)
|
||||
if row.total <= 0:
|
||||
logger.warning(f'Planner row with total <= 0, {row}')
|
||||
continue
|
||||
if row.synthesize < 0:
|
||||
# Credits always have `synthesize`=="-"
|
||||
if row.item.__class__ != ItemCurrency:
|
||||
logger.warning(f'Planner row with synthesize < 0, {row}')
|
||||
continue
|
||||
if row.demand < 0:
|
||||
logger.warning(f'Planner row with demand < 0, {row}')
|
||||
continue
|
||||
# Add
|
||||
out.append(row)
|
||||
|
||||
logger.info(f'parse_planner_result_page: {out}')
|
||||
return out
|
||||
|
||||
def parse_planner_result(self, skip_first_screenshot=True) -> list[PlannerResultRow]:
|
||||
"""
|
||||
Pages:
|
||||
in: planner result
|
||||
"""
|
||||
logger.hr('Parse planner result', level=2)
|
||||
scroll = AdaptiveScroll(RESULT_SCROLL.button, name=RESULT_SCROLL.name)
|
||||
scroll.drag_threshold = 0.1
|
||||
scroll.edge_threshold = 0.1
|
||||
scroll.parameters = {
|
||||
'height': 50,
|
||||
'prominence': 15,
|
||||
'width': 5,
|
||||
}
|
||||
if not skip_first_screenshot:
|
||||
self.device.screenshot()
|
||||
skip_first_screenshot = False
|
||||
if not scroll.at_top(main=self):
|
||||
scroll.set_top(main=self)
|
||||
|
||||
out = []
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# Skip first page
|
||||
if self.appear(CALCULATE_TITLE):
|
||||
scroll.next_page(main=self, page=0.75)
|
||||
continue
|
||||
|
||||
# Parse
|
||||
rows = self.parse_planner_result_page()
|
||||
for row in rows:
|
||||
if row not in out:
|
||||
out.append(row)
|
||||
logger.attr('PlannerResult', len(rows))
|
||||
|
||||
# Scroll
|
||||
if scroll.at_bottom(main=self):
|
||||
logger.info('Reached scroll end, stop')
|
||||
break
|
||||
elif self.appear(DETAIL_TITLE):
|
||||
logger.info('Reached DETAIL_TITLE, stop')
|
||||
break
|
||||
else:
|
||||
scroll.next_page(main=self, page=0.8)
|
||||
|
||||
logger.hr('Planner Result')
|
||||
for row in out:
|
||||
logger.info(f'Planner item: {row.item.name}, {row.total}, {row.synthesize}, {row.demand}')
|
||||
|
||||
self.planner_write_results(out)
|
||||
return out
|
||||
|
||||
def run(self):
|
||||
self.device.screenshot()
|
||||
self.parse_planner_result()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
self = PlannerScan('src', task='PlannerScan')
|
||||
self.device.screenshot()
|
||||
self.parse_planner_result()
|