StarRailCopilot/dev_tools/keywords/dungeon_list.py

153 lines
5.5 KiB
Python
Raw Permalink Normal View History

2024-02-06 19:05:46 +00:00
import re
import typing as t
2024-05-11 10:21:28 +00:00
from dev_tools.keywords.base import GenerateKeyword, SHARE_DATA, text_to_variable
2024-02-06 19:05:46 +00:00
from module.base.decorator import cached_property
from module.config.utils import deep_get
def dungeon_name(name: str) -> str:
name = text_to_variable(name)
name = re.sub('Bud_of_(Memories|Aether|Treasures)', r'Calyx_Golden_\1', name)
name = re.sub('Bud_of_(.*)', r'Calyx_Crimson_\1', name).replace('Calyx_Crimson_Calyx_Crimson_', 'Calyx_Crimson_')
name = re.sub('Shape_of_(.*)', r'Stagnant_Shadow_\1', name)
name = re.sub('Path_of_(.*)', r'Cavern_of_Corrosion_Path_of_\1', name)
if name in ['Destruction_Beginning', 'End_of_the_Eternal_Freeze', 'Divine_Seed', 'Borehole_Planet_Old_Crater']:
name = f'Echo_of_War_{name}'
if name in ['The_Swarm_Disaster', 'Gold_and_Gears']:
name = f'Simulated_Universe_{name}'
2024-05-08 08:22:47 +00:00
name = name.replace('Stagnant_Shadow_Stagnant_Shadow', 'Stagnant_Shadow')
name = name.replace('Cavern_of_Corrosion_Cavern_of_Corrosion', 'Cavern_of_Corrosion')
2024-02-06 19:05:46 +00:00
return name
class GenerateDungeonList(GenerateKeyword):
output_file = './tasks/dungeon/keywords/dungeon.py'
@cached_property
def data(self):
2024-05-11 10:21:28 +00:00
return SHARE_DATA.GameplayGuideData
2024-02-06 19:05:46 +00:00
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],
2024-05-11 10:21:28 +00:00
dungeon_id=-1,
2024-02-06 19:05:46 +00:00
plane_id=-1,
)
else:
yield keyword
def iter_dungeon(self):
temp_save = ""
2024-07-31 06:28:28 +00:00
for data in self.data:
2024-05-11 10:21:28 +00:00
dungeon_id = data.get('ID', 0)
2024-02-06 19:05:46 +00:00
text_id = deep_get(data, keys='Name.Hash')
plane_id = deep_get(data, 'MapEntranceID', 0)
_, name = self.find_keyword(text_id, lang='cn')
if '永屹之城遗秘' in name: # load after all forgotten hall to make sure the same order in Game UI
temp_save = text_id
continue
if '忘却之庭' in name:
continue
yield dict(
text_id=text_id,
2024-05-11 10:21:28 +00:00
dungeon_id=dungeon_id,
2024-02-06 19:05:46 +00:00
plane_id=plane_id,
)
if temp_save:
yield temp_save
# Consider rogue DLC as a dungeon
yield '寰宇蝗灾'
yield '黄金与机械'
# 'Memory of Chaos' is not a real dungeon, but represents a group
yield '混沌回忆'
yield '天艟求仙迷航录'
yield '永屹之城遗秘'
def convert_name(self, text: str, keyword: dict) -> str:
text = super().convert_name(text, keyword=keyword)
text = dungeon_name(text)
# Add plane suffix
from tasks.map.keywords import MapPlane
2024-09-10 08:08:07 +00:00
if text.startswith('Calyx_Golden'):
plane = MapPlane.find_plane_id(keyword['plane_id'])
if plane is not None:
text = f'{text}_{plane.world.name}'
else:
text = f'{text}_unknown_world'
2024-02-06 19:05:46 +00:00
if text.startswith('Calyx_Crimson'):
plane = MapPlane.find_plane_id(keyword['plane_id'])
2024-05-08 08:22:47 +00:00
if plane is not None:
text = f'{text}_{plane.name}'
else:
text = f'{text}_unknown_plane'
2024-02-06 19:05:46 +00:00
return text
2024-02-06 22:57:52 +00:00
def convert_keyword(self, text: str, lang: str) -> str:
text = super().convert_keyword(text, lang=lang)
# Bud of Memories (Jarilo-Ⅵ)
# Use roman numbers instead
text = re.sub(r'-[V][I]', '-Ⅵ', text)
return text
2024-02-06 22:57:52 +00:00
def iter_rows(self) -> t.Iterable[dict]:
dungeons = list(super().iter_rows())
2024-06-30 16:38:37 +00:00
# Sort by path
2024-02-06 22:57:52 +00:00
calyx = []
order = [
'Calyx_Golden',
'Calyx_Crimson_Destruction',
'Calyx_Crimson_Preservation',
'Calyx_Crimson_The_Hunt',
'Calyx_Crimson_Abundance',
'Calyx_Crimson_Erudition',
'Calyx_Crimson_Harmony',
'Calyx_Crimson_Nihility',
]
for keyword in order:
condition = lambda x: x['name'].startswith(keyword)
calyx += [d for d in dungeons if condition(d)]
dungeons = [d for d in dungeons if not condition(d)]
dungeons = calyx + dungeons
2024-09-10 08:08:07 +00:00
# 2024.09.10, v2.5, add genre prefix
for dungeon in dungeons:
if 230 <= dungeon['dungeon_id'] < 1000:
dungeon['name'] = 'Divergent_Universe_' + dungeon['name']
if 100 < dungeon['dungeon_id'] < 200:
dungeon['name'] = 'Simulated_Universe_' + dungeon['name']
2024-09-10 14:41:00 +00:00
# Reverse dungeon list, latest at top
def reverse_on_name(d, prefix):
start = 0
end = 0
for index, dungeon in enumerate(d):
if dungeon['name'].startswith(prefix):
if start == 0:
start = index
end = index + 1
if start > 0 and end > 0:
d = d[:start] + d[start:end][::-1] + d[end:]
return d
dungeons = reverse_on_name(dungeons, 'Divergent_Universe')
dungeons = reverse_on_name(dungeons, 'Cavern_of_Corrosion')
dungeons = reverse_on_name(dungeons, 'Echo_of_War')
# Reverse Calyx_Golden, sort by world
# Poor sort
dungeons[0:3], dungeons[6:9] = dungeons[6:9], dungeons[0:3]
2024-06-30 16:38:37 +00:00
# Re-sort ID
self.keyword_index = 0
2024-02-06 22:57:52 +00:00
for row in dungeons:
self.keyword_index += 1
row['id'] = self.keyword_index
2024-02-06 22:57:52 +00:00
yield row